Skip to content

Commit

Permalink
Allow passing undefined in the duration to add and sub (#2515)
Browse files Browse the repository at this point in the history
Added: Allowed passing `undefined` in the duration to add and sub functions.
  • Loading branch information
komyg committed Jul 23, 2021
1 parent 4dec385 commit eff8352
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 32 deletions.
16 changes: 8 additions & 8 deletions src/add/index.ts
Expand Up @@ -20,7 +20,7 @@ import { Duration } from '../types'
* |----------------|------------------------------------|
* | years | Amount of years to be added |
* | months | Amount of months to be added |
* | weeks | Amount of weeks to be added |
* | weeks | Amount of weeks to be added |
* | days | Amount of days to be added |
* | hours | Amount of hours to be added |
* | minutes | Amount of minutes to be added |
Expand Down Expand Up @@ -52,13 +52,13 @@ export default function add(

if (!duration || typeof duration !== 'object') return new Date(NaN)

const years = 'years' in duration ? toInteger(duration.years) : 0
const months = 'months' in duration ? toInteger(duration.months) : 0
const weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0
const days = 'days' in duration ? toInteger(duration.days) : 0
const hours = 'hours' in duration ? toInteger(duration.hours) : 0
const minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0
const seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0
const years = duration.years ? toInteger(duration.years) : 0
const months = duration.months ? toInteger(duration.months) : 0
const weeks = duration.weeks ? toInteger(duration.weeks) : 0
const days = duration.days ? toInteger(duration.days) : 0
const hours = duration.hours ? toInteger(duration.hours) : 0
const minutes = duration.minutes ? toInteger(duration.minutes) : 0
const seconds = duration.seconds ? toInteger(duration.seconds) : 0

// Add years and months
const date = toDate(dirtyDate)
Expand Down
56 changes: 41 additions & 15 deletions src/add/test.ts
Expand Up @@ -5,50 +5,76 @@ import assert from 'assert'
import add from '.'
import { getDstTransitions } from '../../test/dst/tzOffsetTransitions'

describe('add', function() {
it('adds the values from the given object', function() {
describe('add', function () {
it('adds the values from the given object', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10, 19, 50), {
years: 2,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30
seconds: 30,
})
assert.deepStrictEqual(result, new Date(2017, 5 /* June */, 15, 15, 29, 20))
})

it('returns same date object when passed empty duration values', function() {
it('supports an undefined value in the duration object', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10, 19, 50), {
years: undefined,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30,
})
assert.deepStrictEqual(result, new Date(2015, 5 /* June */, 15, 15, 29, 20))
})

it('returns same date object when passed empty duration values', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {
years: undefined,
months: undefined,
weeks: undefined,
days: undefined,
hours: undefined,
minutes: undefined,
seconds: undefined,
})
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})

it('returns same date object when passed undefined duration values', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {})
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})

it('accepts a timestamp', function() {
it('accepts a timestamp', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {
hours: 4
hours: 4,
})
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('converts a fractional number to an integer', function() {
it('converts a fractional number to an integer', function () {
const result = add(new Date(2014, 8 /* Sep */, 1, 10), { hours: 4.2 })
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('implicitly converts number arguments', function() {
it('implicitly converts number arguments', function () {
// @ts-expect-error
const result = add(new Date(2014, 8 /* Sep */, 1, 10), { hours: '4.2' })
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('does not mutate the original date', function() {
it('does not mutate the original date', function () {
const date = new Date(2014, 8 /* Sep */, 1, 10)
add(date, { hours: 4 })
assert.deepStrictEqual(date, new Date(2014, 8 /* Sep */, 1, 10))
})

it('works well if the desired month has fewer days and the provided date is in the last day of a month', function() {
it('works well if the desired month has fewer days and the provided date is in the last day of a month', function () {
const date = new Date(2014, 11 /* Dec */, 31)
const result = add(date, { months: 9 })
assert.deepStrictEqual(result, new Date(2015, 8 /* Sep */, 30))
Expand All @@ -61,14 +87,14 @@ describe('add', function() {

dstOnly(
`works at DST-end boundary in local timezone: ${tz || '(unknown)'}`,
function() {
function () {
const date = dstTransitions.end
const result = add(date!, { hours: 1 })
assert.deepStrictEqual(result, new Date(date!.getTime() + HOUR))
}
)

it('handles dates before 100 AD', function() {
it('handles dates before 100 AD', function () {
const initialDate = new Date(0)
initialDate.setFullYear(-1, 10 /* Nov */, 30)
initialDate.setHours(0, 0, 0, 0)
Expand All @@ -79,18 +105,18 @@ describe('add', function() {
assert.deepStrictEqual(result, expectedResult)
})

it('returns `Invalid Date` if the given date is invalid', function() {
it('returns `Invalid Date` if the given date is invalid', function () {
const result = add(new Date(NaN), { hours: 5 })
assert(result instanceof Date && isNaN(result.getTime()))
})

it('throws RangeError exception if passed Number as duration', function() {
it('throws RangeError exception if passed Number as duration', function () {
// @ts-expect-error
const result = add(new Date(2014, 8, 1), 'wut')
assert(result instanceof Date && isNaN(result.getTime()))
})

it('throws TypeError exception if passed less than 2 arguments', function() {
it('throws TypeError exception if passed less than 2 arguments', function () {
// @ts-expect-error
assert.throws(add.bind(null), TypeError)
// @ts-expect-error
Expand Down
14 changes: 7 additions & 7 deletions src/sub/index.js
Expand Up @@ -48,13 +48,13 @@ export default function sub(dirtyDate, duration) {

if (!duration || typeof duration !== 'object') return new Date(NaN)

const years = 'years' in duration ? toInteger(duration.years) : 0
const months = 'months' in duration ? toInteger(duration.months) : 0
const weeks = 'weeks' in duration ? toInteger(duration.weeks) : 0
const days = 'days' in duration ? toInteger(duration.days) : 0
const hours = 'hours' in duration ? toInteger(duration.hours) : 0
const minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0
const seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0
const years = duration.years ? toInteger(duration.years) : 0
const months = duration.months ? toInteger(duration.months) : 0
const weeks = duration.weeks ? toInteger(duration.weeks) : 0
const days = duration.days ? toInteger(duration.days) : 0
const hours = duration.hours ? toInteger(duration.hours) : 0
const minutes = duration.minutes ? toInteger(duration.minutes) : 0
const seconds = duration.seconds ? toInteger(duration.seconds) : 0

// Subtract years and months
const dateWithoutMonths = subMonths(toDate(dirtyDate), months + years * 12)
Expand Down
30 changes: 28 additions & 2 deletions src/sub/test.js
Expand Up @@ -13,19 +13,45 @@ describe('sub', () => {
days: 7,
hours: 5,
minutes: 9,
seconds: 30
seconds: 30,
})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 10, 19, 50))
})

it('supports an undefined value in the duration object', function () {
const result = sub(new Date(2017, 5 /* June */, 15, 15, 29, 20), {
years: undefined,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30,
})
assert.deepEqual(result, new Date(2016, 8 /* Sep */, 1, 10, 19, 50))
})

it('returns same date object when passed empty duration values', function () {
const result = sub(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {
years: undefined,
months: undefined,
weeks: undefined,
days: undefined,
hours: undefined,
minutes: undefined,
seconds: undefined,
})
assert.deepStrictEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})

it('returns same date object when passed empty duration', () => {
const result = sub(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})

it('accepts a timestamp', () => {
const result = sub(new Date(2014, 8 /* Sep */, 1, 14).getTime(), {
hours: 4
hours: 4,
})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})
Expand Down

0 comments on commit eff8352

Please sign in to comment.