From: Joe Date: Sat, 25 Apr 2020 20:04:33 +0000 (-0400) Subject: [feature] Calendar function handles formats only arg (#3666) X-Git-Tag: 2.25.0~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8eb71ae271c23c36a5223459dfd4e779f4bedfa7;p=thirdparty%2Fmoment.git [feature] Calendar function handles formats only arg (#3666) * Issue no. 3658 adding overload for single parameter to calendar function Corrected the formatting on calendarjs unit test file Corrected autoformatting * Removed trailing space... * fixed comment per request * added helper utils for better type and property checking, updated calendar functionality to properly identify time and formats inputs. added a bunch of unit tests --- diff --git a/src/lib/moment/calendar.js b/src/lib/moment/calendar.js index 4b5725c58..5abb9745b 100644 --- a/src/lib/moment/calendar.js +++ b/src/lib/moment/calendar.js @@ -2,6 +2,8 @@ import { createLocal } from '../create/local'; import { cloneWithOffset } from '../units/offset'; import isFunction from '../utils/is-function'; import { hooks } from '../utils/hooks'; +import { isMomentInput } from '../utils/is-moment-input'; +import isCalendarSpec from '../utils/is-calendar-spec'; export function getCalendarFormat(myMoment, now) { var diff = myMoment.diff(now, 'days', true); @@ -14,6 +16,16 @@ export function getCalendarFormat(myMoment, now) { } export function calendar (time, formats) { + // Support for single parameter, formats only overload to the calendar function + if (arguments.length === 1) { + if (isMomentInput(arguments[0])) { + time = arguments[0]; + formats = undefined; + } else if (isCalendarSpec(arguments[0])) { + formats = arguments[0]; + time = undefined; + } + } // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're local/utc/offset or not. var now = time || createLocal(), diff --git a/src/lib/utils/is-calendar-spec.js b/src/lib/utils/is-calendar-spec.js new file mode 100644 index 000000000..1e0094f8e --- /dev/null +++ b/src/lib/utils/is-calendar-spec.js @@ -0,0 +1,23 @@ +import isObjectEmpty from './is-object-empty'; +import hasOwnProp from './has-own-prop'; +import isObject from './is-object'; + +export default function isCalendarSpec(input) { + var objectTest = isObject(input) && !isObjectEmpty(input); + + var propertyTest = false, + properties = [ + 'sameDay', + 'nextDay', + 'lastDay', + 'nextWeek', + 'lastWeek', + 'sameElse' + ]; + + for (var property of properties) { + propertyTest = propertyTest || hasOwnProp(input, property); + } + + return objectTest && propertyTest; +} diff --git a/src/lib/utils/is-moment-input.js b/src/lib/utils/is-moment-input.js new file mode 100644 index 000000000..ce5e42aa8 --- /dev/null +++ b/src/lib/utils/is-moment-input.js @@ -0,0 +1,69 @@ +import isObjectEmpty from './is-object-empty'; +import hasOwnProp from './has-own-prop'; +import isObject from './is-object'; +import isDate from './is-date'; +import isNumber from './is-number'; +import isString from './is-string'; +import {isMoment} from '../moment/constructor'; +import isArray from './is-array'; + +// type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined +export function isMomentInput(input) { + return isMoment(input) || + isDate(input) || + isString(input) || + isNumber(input) || + isNumberOrStringArray(input) || + isMomentInputObject(input) || + input === null || + input === undefined; +} + +export function isMomentInputObject(input) { + var objectTest = isObject(input) && !isObjectEmpty(input); + + var propertyTest = false, + properties = [ + 'years', + 'year', + 'y', + 'months', + 'month', + 'M', + 'days', + 'day', + 'd', + 'dates', + 'date', + 'D', + 'hours', + 'hour', + 'h', + 'minutes', + 'minute', + 'm', + 'seconds', + 'second', + 's', + 'milliseconds', + 'millisecond', + 'ms' + ]; + + for (var property of properties) { + propertyTest = propertyTest || hasOwnProp(input, property); + } + + return objectTest && propertyTest; +} + +function isNumberOrStringArray (input) { + var arrayTest = isArray(input), + dataTypeTest = false; + if (arrayTest) { + dataTypeTest = input.filter(function (item) { + return !isNumber(item) && isString(input); + }).length === 0; + } + return arrayTest && dataTypeTest; +} diff --git a/src/lib/utils/is-string.js b/src/lib/utils/is-string.js new file mode 100644 index 000000000..1f6753057 --- /dev/null +++ b/src/lib/utils/is-string.js @@ -0,0 +1,3 @@ +export default function isString (input) { + return typeof input === 'string' || input instanceof String; +} diff --git a/src/test/moment/calendar.js b/src/test/moment/calendar.js index 36af6848f..8a64570bf 100644 --- a/src/test/moment/calendar.js +++ b/src/test/moment/calendar.js @@ -55,3 +55,105 @@ test('extending calendar options', function (assert) { moment.updateLocale('en', null); } }); + +test('calendar overload time - passing one parameter - a Moment', function (assert) { + var a = moment().hours(13).minutes(23).seconds(45); + var b = moment().add(1, 'd'); + assert.equal( + a.calendar(b), + 'Yesterday at 1:23 PM', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - a Date', function (assert) { + var a = moment().hours(13).minutes(23).seconds(45).subtract(1, 'd'); + var d = new Date(); + assert.equal( + a.calendar(d), + 'Yesterday at 1:23 PM', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - a string', function (assert) { + var a = moment([2808, 11, 1]); + assert.equal( + a.calendar('1999-12-31'), + '12/01/2808', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - a number', function (assert) { + var a = moment([2808, 11, 1]); + assert.equal( + a.calendar(Date.now()), + '12/01/2808', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - an array of numbers', function (assert) { + var a = moment().year(2808).month(11).date(1).hours(13).minutes(23).seconds(45); + assert.equal( + a.calendar([2808, 11, 1, 13, 23, 45]), + 'Today at 1:23 PM', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - an array of strings', function (assert) { + var a = moment().year(2808).month(11).date(1).hours(13).minutes(23).seconds(45); + assert.equal( + a.calendar(['2808', '11', '1', '13', '23', '45']), + 'Today at 1:23 PM', + 'should equate' + ); +}); + +test('calendar overload time - passing one parameter - a moment input object', function (assert) { + var a = moment(); + + var todayTime = new Date(), + month = todayTime.getMonth() + 1, + day = todayTime.getDate(), + year = todayTime.getFullYear(); + + month = month < 10 ? '0' + month.toString() : month; + day = day < 10 ? '0' + day.toString() : day; + + var expectedString = month + '/' + day + '/' + year; + + assert.equal( + a.calendar({ + month: 12, + day: 1, + year: 2808 + }), + expectedString, + 'should equate' + ); +}); + +test('calendar overload format - passing one parameter - object w/ sameDay as a string', function (assert) { + var a = moment().hours(13).minutes(23).seconds(45); + assert.equal( + a.calendar({'sameDay':'h:mm:ssA'}), + '1:23:45PM', + 'should equate' + ); +}); + +test('calendar overload format - passing one parameter - object w/ sameDay as function returning a string', function (assert) { + var a = moment().hours(13).minutes(23).seconds(45); + assert.equal( + a.calendar({ + 'sameDay': function () { + return 'h:mm:ssA'; + } + }), + '1:23:45PM', + 'should equate' + ); +});