diff --git a/src/set/index.js b/src/set/index.js index 96591c6e7e..c4c777e4a5 100644 --- a/src/set/index.js +++ b/src/set/index.js @@ -1,25 +1,21 @@ import toDate from '../toDate/index.js' +import setMonth from '../setMonth/index.js' import toInteger from '../_lib/toInteger/index.js' /** * @name set * @category Common Helpers - * @summary Set date values to a given date + * @summary Set date values to a given date. * * @description - * Set date values to a given date + * Set date values to a given date. * - * The set function takes in an inital Date() paramater, and allows you to set any type of date - * method such as years or months in one object. This way you only need to import one function - * and allows for greater readability. + * Sets time values to date from object `values`. + * A value is not set if it is undefined or null or doesn't exist in `values`. * - * It is not required to include all values. For example, if you only wanted to set the hours, you - * would not also need to include year, month, etc. All that is required is at least one date method - * you wish to set. - * - * Note about bundle size: set does not internally use setX functions from date-fns but instead opts - * to use native set functions. If you use this function, you may not want to include the - * other setX functions that date-fns provides if you are concerned about the bundle size. + * Note about bundle size: `set` does not internally use `setX` functions from date-fns but instead opts + * to use native `Date#setX` methods. If you use this function, you may not want to include the + * other `setX` functions that date-fns provides if you are concerned about the bundle size. * * @param {Date|Number} date - the date to be changed * @param {Object} values - an object with options @@ -32,30 +28,28 @@ import toInteger from '../_lib/toInteger/index.js' * @param {Number} values.milliseconds - the number of milliseconds to be set * @returns {Date} the new date with options set * @throws {TypeError} 2 arguments required - * @throws {RangeError} the value parameter must be an object + * @throws {RangeError} `values` must be an object * * @example - * // Set 1 September 2014 to 20 October 2015 in one function + * // Transform 1 September 2014 into 20 October 2015 in a single line: * var result = set(new Date(2014, 8, 20), { year: 2015, month: 9, date: 20 }) - * // => 20 October 2015 00:00:00 + * //=> Tue Oct 20 2015 00:00:00 * * @example - * // Set 1 September 2014 00:00:00 to 1 September 2014 12:00:00 - * var result = set(new Date(2014, 8, 1), { hours: 12 }) - * // => 1 September 2014 12:00:00 + * // Set 12 PM to 1 September 2014 01:23:45 to 1 September 2014 12:00:00: + * var result = set(new Date(2014, 8, 1, 1, 23, 45), { hours: 12 }) + * //=> Mon Sep 01 2014 12:23:45 */ -export default function set(dirtyDate, dirtyOptions) { +export default function set(dirtyDate, values) { if (arguments.length < 2) { throw new TypeError( '2 arguments required, but only ' + arguments.length + ' present' ) } - var values = dirtyOptions - if (typeof values !== 'object' || values === null) { - throw new RangeError('The value parameter must be an object') + throw new RangeError('values parameter must be an object') } var date = toDate(dirtyDate) @@ -70,7 +64,7 @@ export default function set(dirtyDate, dirtyOptions) { } if (values.month != null) { - date.setMonth(toInteger(values.month)) + date = setMonth(date, values.month) } if (values.date != null) { diff --git a/src/set/test.js b/src/set/test.js index bef15789b3..5028fddd5e 100644 --- a/src/set/test.js +++ b/src/set/test.js @@ -5,118 +5,139 @@ import assert from 'power-assert' import set from '.' describe('set', function() { - it('set the date with every option', function() { + it('sets all values', function() { var result = set(new Date(2013), { year: 2014, - month: 8, + month: 8, // Sep date: 20, hours: 12, minutes: 12, seconds: 12, milliseconds: 12 }) - assert.deepEqual(result, new Date(2014, 8, 20, 12, 12, 12, 12)) + assert.deepEqual( + result.toString(), + new Date(2014, 8 /* Sep */, 20, 12, 12, 12, 12).toString() + ) }) - it('test only year', function() { - var result = set(new Date(2013, 8), { year: 2014 }) - assert.deepEqual(result, new Date(2014, 8)) + + it('sets year', function() { + var result = set(new Date(2013, 8 /* Sep */), { year: 2014 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */)) }) - it('test only month', function() { - var result = set(new Date(2014, 8 /* Sep */), { month: 9 }) + + it('sets month', function() { + var result = set(new Date(2014, 8 /* Sep */), { month: 9 /* Oct */ }) assert.deepEqual(result, new Date(2014, 9 /* Oct */)) }) - it('test only date', function() { - var result = set(new Date(2014, 8), { date: 20 }) - assert.deepEqual(result, new Date(2014, 8, 20)) - }) - it('test month in January', function() { - var result = set(new Date(2014, 8 /* Sep */), { month: 0 }) - assert.deepEqual(result, new Date(2014, 0 /* Jan */)) - }) - it('test only hours', function() { - var result = set(new Date(2014, 8, 1), { hours: 12 }) - assert.deepEqual(result, new Date(2014, 8, 1, 12)) - }) - it('test only minutes', function() { - var result = set(new Date(2014, 8, 1, 1), { minutes: 12 }) - assert.deepEqual(result, new Date(2014, 8, 1, 1, 12)) - }) - it('test only seconds', function() { - var result = set(new Date(2014, 8, 1, 1, 1), { seconds: 12 }) - assert.deepEqual(result, new Date(2014, 8, 1, 1, 1, 12)) - }) - it('test only milliseconds', function() { - var result = set(new Date(2014, 8, 1, 1, 1, 1), { milliseconds: 500 }) - assert.deepEqual(result, new Date(2014, 8, 1, 1, 1, 1, 500)) - }) - it('month turns into year', function() { - var result = set(new Date(2014, 8), { month: 12 }) - assert.deepEqual(result, new Date(2015, 0)) - }) - it('out of bounds month turns into year and month', function() { - var result = set(new Date(2014, 8), { month: 13 }) - assert.deepEqual(result, new Date(2015, 1)) - }) - it('date turns into month', function() { - var result = set(new Date(2014, 8), { date: 31 }) - assert.deepEqual(result, new Date(2014, 9)) - }) - it('out of bounds date turns into month and date', function() { - var result = set(new Date(2014, 8), { date: 32 }) - assert.deepEqual(result, new Date(2014, 9, 2)) - }) - it('hours turns into date', function() { - var result = set(new Date(2014, 8, 19), { hours: 24 }) - assert.deepEqual(result, new Date(2014, 8, 20)) - }) - it('out of bounds hours turns into date and hours', function() { - var result = set(new Date(2014, 8, 1), { hours: 25 }) - assert.deepEqual(result, new Date(2014, 8, 2, 1)) - }) - it('minutes turns into hours', function() { - var result = set(new Date(2014, 8, 20, 11), { minutes: 60 }) - assert.deepEqual(result, new Date(2014, 8, 20, 12)) - }) - it('out of bounds minutes turns into hours and minutes', function() { - var result = set(new Date(2014, 8, 1, 1), { minutes: 61 }) - assert.deepEqual(result, new Date(2014, 8, 1, 2, 1)) - }) - it('seconds turns into minutes', function() { - var result = set(new Date(2014, 8, 20, 12, 58), { seconds: 60 }) - assert.deepEqual(result, new Date(2014, 8, 20, 12, 59)) - }) - it('out of bounds seconds turns into minutes and seconds', function() { - var result = set(new Date(2014, 8, 1, 1, 1), { seconds: 61 }) - assert.deepEqual(result, new Date(2014, 8, 1, 1, 2, 1)) - }) - it('milliseconds turns into seconds', function() { - var result = set(new Date(2014, 8, 20, 12, 58, 30), { milliseconds: 1000 }) - assert.deepEqual(result, new Date(2014, 8, 20, 12, 58, 31)) + + it('sets day of month', function() { + var result = set(new Date(2014, 8 /* Sep */), { date: 20 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20)) }) - it('out of bounds seconds turns into minutes and seconds', function() { - var result = set(new Date(2014, 8, 1, 1, 1, 1), { milliseconds: 1001 }) - assert.deepEqual(result, new Date(2014, 8, 1, 1, 1, 2, 1)) + + it('sets hours', function() { + var result = set(new Date(2014, 8 /* Sep */, 1), { hours: 12 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 12)) }) - it('throws TypeError exception if passed less than 2 arguments', function() { - assert.throws(set.bind(null), TypeError) + + it('sets minutes', function() { + var result = set(new Date(2014, 8 /* Sep */, 1, 1), { minutes: 12 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 12)) }) - it('if any value in values is NaN', function() { - var result = set(new Date(2014, 8), { year: NaN }) - assert.deepEqual(isNaN(result), isNaN(new Date(NaN))) + + it('sets seconds', function() { + var result = set(new Date(2014, 8 /* Sep */, 1, 1, 1), { seconds: 12 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 1, 12)) }) - it('if any value in values is undefined should have no effect', function() { - var result = set(new Date(2014, 8), { year: undefined }) - assert.deepEqual(result, new Date(2014, 8)) + + it('sets milliseconds', function() { + var result = set(new Date(2014, 8 /* Sep */, 1, 1, 1, 1), { + milliseconds: 500 + }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 1, 1, 500)) }) - it('if any value in values is null should have no effect', function() { - // $ExpectedMistake - var result = set(new Date(2014, 8), { year: null }) - assert.deepEqual(result, new Date(2014, 8)) + + describe('value overflow', function() { + it('months overflow into years', function() { + var result = set(new Date(2014, 8 /* Sep */, 1), { + month: 12 /* 13th month */ + }) + assert.deepEqual(result, new Date(2015, 0 /* Jan */, 1)) + }) + + it('days of months overflow into months', function() { + var result = set(new Date(2014, 8 /* Sep */, 1), { date: 31 }) + assert.deepEqual(result, new Date(2014, 9 /* Oct */, 1)) + }) + + it('hours overflow into days', function() { + var result = set(new Date(2014, 8 /* Sep */, 19), { hours: 24 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20)) + }) + + it('minutes overflow into hours', function() { + var result = set(new Date(2014, 8 /* Sep */, 20, 11), { minutes: 60 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12)) + }) + + it('seconds overflow into minutes', function() { + var result = set(new Date(2014, 8 /* Sep */, 20, 12, 58), { seconds: 60 }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12, 59)) + }) + + it('milliseconds overflow into seconds', function() { + var result = set(new Date(2014, 8 /* Sep */, 20, 12, 58, 30), { + milliseconds: 1000 + }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12, 58, 31)) + }) }) - it('throws RangeError exception if value is passed a non-object or null', function() { - // $ExpectedMistake - assert.throws(set.bind(null, new Date(), null), RangeError) - // $ExpectedMistake - assert.throws(set.bind(null, new Date(), true), RangeError) + + describe('edge cases', function() { + it('sets January', function() { + var result = set(new Date(2014, 8 /* Sep */), { month: 0 /* Jan */ }) + assert.deepEqual(result, new Date(2014, 0 /* Jan */)) + }) + + it('sets the last day of new month if the initial date was the last day of a longer month', function() { + var result = set(new Date(2014, 7 /* Aug */, 31), { month: 8 /* Sep */ }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */, 30)) + }) + + it('ignores undefined values', function() { + var result = set(new Date(2014, 8 /* Sep */), { year: undefined }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */)) + }) + + it('ignores null values', function() { + // $ExpectedMistake + var result = set(new Date(2014, 8 /* Sep */), { year: null }) + assert.deepEqual(result, new Date(2014, 8 /* Sep */)) + }) + + it('throws TypeError exception if passed less than 2 arguments', function() { + assert.throws(set.bind(null), TypeError) + }) + + it('returns Invalid Date if any value in values is NaN', function() { + var result = set(new Date(2014, 8 /* Sep */), { year: NaN }) + assert.deepEqual(isNaN(result), isNaN(new Date(NaN))) + }) + + it('returns Invalid Date the initial date was Invalid Date as well', function() { + var result = set(new Date(NaN), { year: 2019 }) + assert.deepEqual(isNaN(result), isNaN(new Date(NaN))) + }) + + it('throws RangeError exception if `values` is not an object', function() { + // $ExpectedMistake + assert.throws(set.bind(null, new Date(), null), RangeError) + }) + + it('throws RangeError exception if `values` is null', function() { + // $ExpectedMistake + assert.throws(set.bind(null, new Date(), true), RangeError) + }) }) })