Skip to content

Commit

Permalink
Address reviewer comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jmannanc committed Sep 5, 2019
1 parent 637d24c commit 94b8192
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 124 deletions.
2 changes: 1 addition & 1 deletion src/fp/set/index.js
Expand Up @@ -3,6 +3,6 @@
import fn from '../../set/index.js'
import convertToFP from '../_lib/convertToFP/index.js'

var set = convertToFP(fn, 1)
var set = convertToFP(fn, 2)

export default set
6 changes: 5 additions & 1 deletion src/fp/set/index.js.flow
Expand Up @@ -37,4 +37,8 @@ type Locale = {

type CurriedFn1<A, R> = <A>(a: A) => R

declare module.exports: CurriedFn1<Date | number, Date>
type CurriedFn2<A, B, R> = <A>(
a: A
) => CurriedFn1<B, R> | (<A, B>(a: A, b: B) => R)

declare module.exports: CurriedFn2<Object, Date | number, Date>
4 changes: 0 additions & 4 deletions src/fp/setWithOptions/index.d.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/fp/setWithOptions/index.js

This file was deleted.

44 changes: 0 additions & 44 deletions src/fp/setWithOptions/index.js.flow

This file was deleted.

2 changes: 1 addition & 1 deletion src/set/benchmark.js
Expand Up @@ -9,7 +9,7 @@ suite(
'set',
function() {
benchmark('date-fns', function() {
return set(this.date, { years: 2014, months: 8 })
return set(this.date, { year: 2014, month: 8 })
})

benchmark('Moment.js', function() {
Expand Down
104 changes: 66 additions & 38 deletions src/set/index.js
@@ -1,28 +1,48 @@
import toDate from '../toDate/index.js'
import toInteger from '../_lib/toInteger/index.js'
import setMonth from '../setMonth/index.js'

/**
* @name set
* @category Common Helpers
* @summary Set the object to a given date
* @summary Set date values to a given date
*
* @description
* Set the object 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.
*
* 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.
*
* @param {Date|Number} date - the date to be changed
* @param {Object} [options] - an object with options
* @param {Number} [options.years=0] - the number of years to be set
* @param {Number} [options.months=0] - the number of months to be set
* @param {Number} [options.days=0] - the number of days to be set
* @param {Number} [options.hours=0] - the number of hours to be set
* @param {Number} [options.minutes=0] - the number of minutes to be set
* @param {Number} [options.seconds=0] - the number of seconds to be set
* @param {Number} [options.milliseconds=0] - the number of milliseconds to be set
* @param {Object} values - an object with options
* @param {Number} values.year - the number of years to be set
* @param {Number} values.month - the number of months to be set
* @param {Number} values.date - the number of days to be set
* @param {Number} values.hours - the number of hours to be set
* @param {Number} values.minutes - the number of minutes to be set
* @param {Number} values.seconds - the number of seconds to be set
* @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 options object must only contain number properties
* @throws {RangeError} The options object must not contain a NaN
* @throws {RangeError} the value parameter must be an object
*
* @example
* // Set 1 September 2014 to 20 October 2015 in one function
* var result = set(new Date(2014, 8, 20), { year: 2015, month: 9, date: 20 })
* // => 20 October 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
*/

export default function set(dirtyDate, dirtyOptions) {
Expand All @@ -32,41 +52,49 @@ export default function set(dirtyDate, dirtyOptions) {
)
}

var options = dirtyOptions || {}

// check if properties of object are numbers and not NaN
var isNumbers = Object.values(options).every(x => typeof x === 'number')
var hasNaN = Object.values(options).every(x => isNaN(x))
var values = dirtyOptions

if (!isNumbers) {
throw new RangeError('The options object must only contain numbers')
} else if (hasNaN) {
throw new RangeError('The options object must not contain a NaN')
if (typeof values !== 'object' || values === null) {
throw new RangeError('The value parameter must be an object')
}

var years = options.years == null ? 0 : toInteger(options.years)
var months = options.months == null ? 0 : toInteger(options.months)
var days = options.days == null ? 0 : toInteger(options.days)
var hours = options.hours == null ? 0 : toInteger(options.hours)
var minutes = options.minutes == null ? 0 : toInteger(options.minutes)
var seconds = options.seconds == null ? 0 : toInteger(options.seconds)
var milliseconds =
options.milliseconds == null ? 0 : toInteger(options.milliseconds)

var date = toDate(dirtyDate)

var daysForMonth =
values.date == null ? date.getDate() : toInteger(values.date)

// Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date
if (isNaN(date)) {
return new Date(NaN)
}

if (years > 0) date.setFullYear(years)
if (months > 0) date = setMonth(date, months)
if (days > 0) date.setDate(days)
if (hours > 0) date.setHours(hours)
if (minutes > 0) date.setMinutes(minutes)
if (seconds > 0) date.setSeconds(seconds)
if (milliseconds > 0) date.setMilliseconds(milliseconds)
if (values.year != null) {
date.setFullYear(values.year)
}

if (values.month != null) {
date.setMonth(toInteger(values.month), daysForMonth)
}

if (values.date != null) {
date.setDate(toInteger(values.date))
}

if (values.hours != null) {
date.setHours(toInteger(values.hours))
}

if (values.minutes != null) {
date.setMinutes(toInteger(values.minutes))
}

if (values.seconds != null) {
date.setSeconds(toInteger(values.seconds))
}

if (values.milliseconds != null) {
date.setMilliseconds(toInteger(values.milliseconds))
}

return date
}
8 changes: 4 additions & 4 deletions src/set/index.js.flow
Expand Up @@ -37,10 +37,10 @@ type Locale = {

declare module.exports: (
date: Date | number,
options?: {
years?: number,
months?: number,
days?: number,
values: {
year?: number,
month?: number,
date?: number,
hours?: number,
minutes?: number,
seconds?: number,
Expand Down
78 changes: 55 additions & 23 deletions src/set/test.js
Expand Up @@ -7,28 +7,32 @@ import set from '.'
describe('set', function() {
it('set the date with every option', function() {
var result = set(new Date(2013), {
years: 2014,
months: 8,
days: 20,
year: 2014,
month: 8,
date: 20,
hours: 12,
minutes: 12,
seconds: 12,
milliseconds: 12
})
assert.deepEqual(result, new Date(2014, 8, 20, 12, 12, 12, 12))
})
it('test only years', function() {
var result = set(new Date(2013, 8), { years: 2014 })
it('test only year', function() {
var result = set(new Date(2013, 8), { year: 2014 })
assert.deepEqual(result, new Date(2014, 8))
})
it('test only months', function() {
var result = set(new Date(2014, 8 /* Sep */), { months: 9 })
it('test only month', function() {
var result = set(new Date(2014, 8 /* Sep */), { month: 9 })
assert.deepEqual(result, new Date(2014, 9 /* Oct */))
})
it('test only days', function() {
var result = set(new Date(2014, 8), { days: 20 })
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))
Expand All @@ -45,42 +49,70 @@ describe('set', 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('months turns into years', function() {
var result = set(new Date(2014, 8), { months: 13 })
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('days turns into months', function() {
var result = set(new Date(2014, 8), { days: 31 })
it('date turns into month', function() {
var result = set(new Date(2014, 8), { date: 31 })
assert.deepEqual(result, new Date(2014, 9))
})
it('hours turns into days', function() {
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('throws RangeError if NaN is in options object', function() {
var result = set.bind(null, new Date(2014, 8), { years: NaN, months: NaN })
assert.throws(result, RangeError)
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('throws TypeError exception if passed less than 2 arguments', function() {
assert.throws(set.bind(null), TypeError)
})
it('throws RangeError if object has non-number properties', function() {
var result = set.bind(null, new Date(2014, 8), {
years: false,
months: false
})
assert.throws(result, RangeError)
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('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))
})
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)
})
})

0 comments on commit 94b8192

Please sign in to comment.