Skip to content

Commit

Permalink
Implement isDate (closes #541, closes #752) (#754)
Browse files Browse the repository at this point in the history
* Implement isDate that works properly with dates passed across iframes
* Upgrade Flow
* Fix pending Flow issues
  • Loading branch information
kossnocorp committed May 21, 2018
1 parent e0cbdfa commit 7a79037
Show file tree
Hide file tree
Showing 28 changed files with 431 additions and 27 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -565,8 +565,6 @@ for the list of changes made since `v2.0.0-alpha.1`.
- **BREAKING**: all functions now check if the passed number of arguments is less
than the number of required arguments and throw `TypeError` exception if so.

- **BREAKING**: removed `isDate`. Instead, you can use `x instanceof Date`.

- Every function now has `options` as the last argument which is passed to all its dependencies
for consistency and future features.
See [docs/Options.js](https://github.com/date-fns/date-fns/blob/master/docs/Options.js)
Expand All @@ -589,6 +587,8 @@ for the list of changes made since `v2.0.0-alpha.1`.
- Fix `differenceIn...` functions returning negative zero in some cases:
[#692](https://github.com/date-fns/date-fns/issues/692)

- `isDate` now works properly with dates passed across iframes [#754](https://github.com/date-fns/date-fns/pull/754).

## [1.28.5] - 2017-05-19

### Fixed
Expand Down
3 changes: 1 addition & 2 deletions config/karma.js
Expand Up @@ -128,7 +128,6 @@ function config (config) {
},

plugins: [
'karma-es5-shim',
'karma-mocha',
'karma-mocha-reporter',
'karma-phantomjs-launcher',
Expand All @@ -153,7 +152,7 @@ function getFrameworksConfig () {
if (process.env.TEST_BENCHMARK) {
return ['benchmark']
} else {
return ['mocha', 'sinon', 'es5-shim']
return ['mocha', 'sinon']
}
}

Expand Down
3 changes: 1 addition & 2 deletions package.json
Expand Up @@ -36,7 +36,7 @@
"babel-preset-power-assert": "^1.0.0",
"cloc": "^2.2.0",
"firebase": "^3.7.1",
"flow-bin": "^0.36.0",
"flow-bin": "0.72",
"fs-promise": "^1.0.0",
"glob-promise": "^2.0.0",
"gzip-size-cli": "^1.0.0",
Expand All @@ -48,7 +48,6 @@
"karma-benchmark-reporter": "^0.1.1",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-es5-shim": "0.0.4",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.1",
"karma-phantomjs-launcher": "^1.0.4",
Expand Down
2 changes: 1 addition & 1 deletion src/_lib/startOfUTCISOWeekYear/test.js
Expand Up @@ -28,7 +28,7 @@ describe('startOfUTCISOWeekYear', function () {

it('handles dates before 100 AD', function () {
var initialDate = new Date(0)
initialDate.setUTCFullYear(9, 0 /* Jan */, 1, 16, 0)
initialDate.setUTCFullYear(9, 0 /* Jan */, 1)
initialDate.setUTCHours(0, 0, 0, 0)
var expectedResult = new Date(0)
expectedResult.setUTCFullYear(8, 11 /* Dec */, 29)
Expand Down
2 changes: 1 addition & 1 deletion src/_lib/startOfUTCWeekYear/test.js
Expand Up @@ -28,7 +28,7 @@ describe('startOfUTCWeekYear', function () {

it('handles dates before 100 AD', function () {
var initialDate = new Date(0)
initialDate.setUTCFullYear(9, 0 /* Jan */, 1, 16, 0)
initialDate.setUTCFullYear(9, 0 /* Jan */, 1)
initialDate.setUTCHours(0, 0, 0, 0)
var expectedResult = new Date(0)
expectedResult.setUTCFullYear(8, 11 /* Dec */, 28)
Expand Down
2 changes: 2 additions & 0 deletions src/esm/fp/index.js
Expand Up @@ -142,6 +142,8 @@ export {default as isAfter} from './isAfter/index.js'
export {default as isAfterWithOptions} from './isAfterWithOptions/index.js'
export {default as isBefore} from './isBefore/index.js'
export {default as isBeforeWithOptions} from './isBeforeWithOptions/index.js'
export {default as isDate} from './isDate/index.js'
export {default as isDateWithOptions} from './isDateWithOptions/index.js'
export {default as isEqual} from './isEqual/index.js'
export {default as isEqualWithOptions} from './isEqualWithOptions/index.js'
export {default as isFirstDayOfMonth} from './isFirstDayOfMonth/index.js'
Expand Down
1 change: 1 addition & 0 deletions src/esm/index.js
Expand Up @@ -71,6 +71,7 @@ export {default as getWeeksInMonth} from './getWeeksInMonth/index.js'
export {default as getYear} from './getYear/index.js'
export {default as isAfter} from './isAfter/index.js'
export {default as isBefore} from './isBefore/index.js'
export {default as isDate} from './isDate/index.js'
export {default as isEqual} from './isEqual/index.js'
export {default as isFirstDayOfMonth} from './isFirstDayOfMonth/index.js'
export {default as isFriday} from './isFriday/index.js'
Expand Down
2 changes: 1 addition & 1 deletion src/formatDistance/test.js
Expand Up @@ -273,8 +273,8 @@ describe('formatDistance', function () {
var block = formatDistance.bind(
null,
new Date(1986, 3, 4, 10, 32, 0),
new Date(1986, 3, 4, 10, 32, 3),
// $ExpectedMistake
new Date(1986, 3, 4, 10, 32, 3),
{includeSeconds: true, locale: customLocale}
)
assert.throws(block, RangeError)
Expand Down
2 changes: 1 addition & 1 deletion src/formatDistanceStrict/test.js
Expand Up @@ -431,8 +431,8 @@ describe('formatDistanceStrict', function () {
var block = formatDistanceStrict.bind(
null,
new Date(1986, 3, 4, 10, 32, 0),
new Date(1986, 3, 4, 10, 37, 0),
// $ExpectedMistake
new Date(1986, 3, 4, 10, 37, 0),
{unit: 'minute', locale: customLocale}
)
assert.throws(block, RangeError)
Expand Down
2 changes: 2 additions & 0 deletions src/fp/index.js
Expand Up @@ -143,6 +143,8 @@ module.exports = {
isAfterWithOptions: require('./isAfterWithOptions/index.js'),
isBefore: require('./isBefore/index.js'),
isBeforeWithOptions: require('./isBeforeWithOptions/index.js'),
isDate: require('./isDate/index.js'),
isDateWithOptions: require('./isDateWithOptions/index.js'),
isEqual: require('./isEqual/index.js'),
isEqualWithOptions: require('./isEqualWithOptions/index.js'),
isFirstDayOfMonth: require('./isFirstDayOfMonth/index.js'),
Expand Down
2 changes: 2 additions & 0 deletions src/fp/index.js.flow
Expand Up @@ -203,6 +203,8 @@ declare module.exports: {
isAfterWithOptions: CurriedFn3<Options, Date | string | number, Date | string | number, boolean>,
isBefore: CurriedFn2<Date | string | number, Date | string | number, boolean>,
isBeforeWithOptions: CurriedFn3<Options, Date | string | number, Date | string | number, boolean>,
isDate: CurriedFn1<any, boolean>,
isDateWithOptions: CurriedFn2<Options, any, boolean>,
isEqual: CurriedFn2<Date | string | number, Date | string | number, boolean>,
isEqualWithOptions: CurriedFn3<Options, Date | string | number, Date | string | number, boolean>,
isFirstDayOfMonth: CurriedFn1<Date | string | number, boolean>,
Expand Down
4 changes: 4 additions & 0 deletions src/fp/isDate/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {isDate} from 'date-fns/fp'
export = isDate
8 changes: 8 additions & 0 deletions src/fp/isDate/index.js
@@ -0,0 +1,8 @@
// This file is generated automatically by `scripts/build/fp.js`. Please, don't change it.

import fn from '../../isDate/index.js'
import convertToFP from '../_lib/convertToFP/index.js'

var isDate = convertToFP(fn, 1)

export default isDate
51 changes: 51 additions & 0 deletions src/fp/isDate/index.js.flow
@@ -0,0 +1,51 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round'
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

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

declare module.exports: CurriedFn1<any, boolean>
4 changes: 4 additions & 0 deletions src/fp/isDateWithOptions/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {isDateWithOptions} from 'date-fns/fp'
export = isDateWithOptions
8 changes: 8 additions & 0 deletions src/fp/isDateWithOptions/index.js
@@ -0,0 +1,8 @@
// This file is generated automatically by `scripts/build/fp.js`. Please, don't change it.

import fn from '../../isDate/index.js'
import convertToFP from '../_lib/convertToFP/index.js'

var isDateWithOptions = convertToFP(fn, 2)

export default isDateWithOptions
54 changes: 54 additions & 0 deletions src/fp/isDateWithOptions/index.js.flow
@@ -0,0 +1,54 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round'
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

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

type CurriedFn2<A, B, R> = <A>(a: A) => CurriedFn1<B, R>
| <A, B>(a: A, b: B) => R

declare module.exports: CurriedFn2<Options, any, boolean>
4 changes: 2 additions & 2 deletions src/fp/test.js
Expand Up @@ -46,12 +46,12 @@ describe('FP functions', function () {
})

it('addMinutes', function () {
var result = fp.addMinutes(30)(new Date(2014, 6 /* Jul */, 10, 12, 0), 30)
var result = fp.addMinutes(30)(new Date(2014, 6 /* Jul */, 10, 12, 0))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 30))
})

it('addMinutesWithOptions', function () {
var result = fp.addMinutesWithOptions({})(30)(new Date(2014, 6 /* Jul */, 10, 12, 0), 30)
var result = fp.addMinutesWithOptions({})(30)(new Date(2014, 6 /* Jul */, 10, 12, 0))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 30))
})

Expand Down
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -72,6 +72,7 @@ module.exports = {
getYear: require('./getYear/index.js'),
isAfter: require('./isAfter/index.js'),
isBefore: require('./isBefore/index.js'),
isDate: require('./isDate/index.js'),
isEqual: require('./isEqual/index.js'),
isFirstDayOfMonth: require('./isFirstDayOfMonth/index.js'),
isFriday: require('./isFriday/index.js'),
Expand Down
5 changes: 5 additions & 0 deletions src/index.js.flow
Expand Up @@ -441,6 +441,11 @@ declare module.exports: {
options?: Options
) => boolean,

isDate: (
value: any,
options?: Options
) => boolean,

isEqual: (
dateLeft: Date | string | number,
dateRight: Date | string | number,
Expand Down
4 changes: 4 additions & 0 deletions src/isDate/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {isDate} from 'date-fns'
export = isDate
41 changes: 41 additions & 0 deletions src/isDate/index.js
@@ -0,0 +1,41 @@
/**
* @name isDate
* @category Common Helpers
* @summary Is the given value a date?
*
* @description
* Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
*
* @param {*} value - the value to check
* @param {Options} [options] - the object with options. Unused; present for FP submodule compatibility sake. See [Options]{@link https://date-fns.org/docs/Options}
* @returns {boolean} true if the given value is a date
* @throws {TypeError} 1 arguments required
*
* @example
* // For a valid date:
* var result = isDate(new Date())
* //=> true
*
* @example
* // For a value
* var result = isDate('2014-02-31')
* //=> false
*
* @example
* // For a object
* var result = isDate({})
* //=> false
*/
export default function isDate (value) {
if (arguments.length < 1) {
throw new TypeError(
'1 argument required, but only ' + arguments.length + ' present'
)
}

return (
value instanceof Date ||
(typeof value === 'object' &&
Object.prototype.toString.call(value) === '[object Date]')
)
}
52 changes: 52 additions & 0 deletions src/isDate/index.js.flow
@@ -0,0 +1,52 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round'
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

declare module.exports: (
value: any,
options?: Options
) => boolean

0 comments on commit 7a79037

Please sign in to comment.