Skip to content

Commit f09a9f3

Browse files
committed
fix: Support Jest mocked dates
Jest provides two different implementations of fake timers - legacy and modern. The legacy implementation works with RRule, while the modern one does not, as it uses a strict instance check. Compare the toString result of the object if the value is not a Date instance.
1 parent 6de8945 commit f09a9f3

File tree

4 files changed

+15
-12
lines changed

4 files changed

+15
-12
lines changed

src/cache.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import IterResult, { IterArgs } from './iterresult'
2-
import { clone, cloneDates } from './dateutil'
2+
import { clone, cloneDates, isDate } from './dateutil'
33
import { isArray } from './helpers'
44

55
export type CacheKeys = 'before' | 'after' | 'between'
@@ -14,8 +14,8 @@ function argsMatch(
1414
return left.every((date, i) => date.getTime() === right[i].getTime())
1515
}
1616

17-
if (left instanceof Date) {
18-
return right instanceof Date && left.getTime() === right.getTime()
17+
if (isDate(left)) {
18+
return isDate(right) && left.getTime() === right.getTime()
1919
}
2020

2121
return left === right
@@ -38,7 +38,7 @@ export class Cache {
3838
args?: Partial<IterArgs>
3939
) {
4040
if (value) {
41-
value = value instanceof Date ? clone(value) : cloneDates(value)
41+
value = isDate(value) ? clone(value) : cloneDates(value)
4242
}
4343

4444
if (what === 'all') {
@@ -99,7 +99,7 @@ export class Cache {
9999

100100
return isArray(cached)
101101
? cloneDates(cached)
102-
: cached instanceof Date
102+
: isDate(cached)
103103
? clone(cached)
104104
: cached
105105
}

src/dateutil.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ export const isLeapYear = function (year: number) {
6666
}
6767

6868
export const isDate = function (value: unknown): value is Date {
69-
return value instanceof Date
69+
return (
70+
value instanceof Date ||
71+
(typeof value === 'object' &&
72+
Object.prototype.toString.call(value) === '[object Date]')
73+
)
7074
}
7175

7276
export const isValidDate = function (value: unknown): value is Date {

src/rruleset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RRule } from './rrule'
2-
import { sort, timeToUntilString } from './dateutil'
2+
import { sort, timeToUntilString, isDate } from './dateutil'
33
import { includes } from './helpers'
44
import IterResult from './iterresult'
55
import { iterSet } from './iterset'
@@ -206,7 +206,7 @@ function _addRule(rrule: RRule, collection: RRule[]) {
206206
}
207207

208208
function _addDate(date: Date, collection: Date[]) {
209-
if (!(date instanceof Date)) {
209+
if (!isDate(date)) {
210210
throw new TypeError(String(date) + ' is not Date instance')
211211
}
212212
if (!includes(collection.map(Number), Number(date))) {

test/lib/utils.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { expect } from 'chai'
22
import { ExclusiveTestFunction, TestFunction } from 'mocha'
3-
export { datetime } from '../../src/dateutil'
4-
import { datetime } from '../../src/dateutil'
5-
import { RRule, RRuleSet } from '../../src'
3+
import { datetime, RRule, RRuleSet } from '../../src'
4+
import { isDate } from '../../src/dateutil'
65

76
const assertDatesEqual = function (
87
actual: Date | Date[],
@@ -25,7 +24,7 @@ const assertDatesEqual = function (
2524
for (let i = 0; i < expected.length; i++) {
2625
const act = actual[i]
2726
const exp = expected[i]
28-
expect(exp instanceof Date ? exp.toString() : exp).to.equal(
27+
expect(isDate(exp) ? exp.toString() : exp).to.equal(
2928
act.toString(),
3029
msg + (i + 1) + '/' + expected.length
3130
)

0 commit comments

Comments
 (0)