From 3d3c33423ce863760e784b9e74ea3c60bff7aa03 Mon Sep 17 00:00:00 2001 From: Vitaly Budovski Date: Sat, 25 Jun 2022 11:36:03 +1000 Subject: [PATCH] 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. --- src/cache.ts | 10 +++++----- src/dateutil.ts | 2 +- src/rruleset.ts | 4 ++-- test/lib/utils.ts | 7 +++---- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cache.ts b/src/cache.ts index 02ed58e3..62ee1899 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -1,5 +1,5 @@ import IterResult, { IterArgs } from './iterresult' -import { clone, cloneDates } from './dateutil' +import { clone, cloneDates, isDate } from './dateutil' import { isArray } from './helpers' export type CacheKeys = 'before' | 'after' | 'between' @@ -14,8 +14,8 @@ function argsMatch( return left.every((date, i) => date.getTime() === right[i].getTime()) } - if (left instanceof Date) { - return right instanceof Date && left.getTime() === right.getTime() + if (isDate(left)) { + return isDate(right) && left.getTime() === right.getTime() } return left === right @@ -38,7 +38,7 @@ export class Cache { args?: Partial ) { if (value) { - value = value instanceof Date ? clone(value) : cloneDates(value) + value = isDate(value) ? clone(value) : cloneDates(value) } if (what === 'all') { @@ -99,7 +99,7 @@ export class Cache { return isArray(cached) ? cloneDates(cached) - : cached instanceof Date + : isDate(cached) ? clone(cached) : cached } diff --git a/src/dateutil.ts b/src/dateutil.ts index 59cbcc6d..0ddcebad 100644 --- a/src/dateutil.ts +++ b/src/dateutil.ts @@ -66,7 +66,7 @@ export const isLeapYear = function (year: number) { } export const isDate = function (value: unknown): value is Date { - return value instanceof Date + return value instanceof Date || (typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]') } export const isValidDate = function (value: unknown): value is Date { diff --git a/src/rruleset.ts b/src/rruleset.ts index ebf9d01d..d3f838aa 100644 --- a/src/rruleset.ts +++ b/src/rruleset.ts @@ -1,5 +1,5 @@ import { RRule } from './rrule' -import { sort, timeToUntilString } from './dateutil' +import { sort, timeToUntilString, isDate } from './dateutil' import { includes } from './helpers' import IterResult from './iterresult' import { iterSet } from './iterset' @@ -206,7 +206,7 @@ function _addRule(rrule: RRule, collection: RRule[]) { } function _addDate(date: Date, collection: Date[]) { - if (!(date instanceof Date)) { + if (!isDate(date)) { throw new TypeError(String(date) + ' is not Date instance') } if (!includes(collection.map(Number), Number(date))) { diff --git a/test/lib/utils.ts b/test/lib/utils.ts index 5610b384..0d4483f3 100644 --- a/test/lib/utils.ts +++ b/test/lib/utils.ts @@ -1,8 +1,7 @@ import { expect } from 'chai' import { ExclusiveTestFunction, TestFunction } from 'mocha' -export { datetime } from '../../src/dateutil' -import { datetime } from '../../src/dateutil' -import { RRule, RRuleSet } from '../../src' +import { datetime, RRule, RRuleSet } from '../../src' +import { isDate } from '../../src/dateutil' const assertDatesEqual = function ( actual: Date | Date[], @@ -25,7 +24,7 @@ const assertDatesEqual = function ( for (let i = 0; i < expected.length; i++) { const act = actual[i] const exp = expected[i] - expect(exp instanceof Date ? exp.toString() : exp).to.equal( + expect(isDate(exp) ? exp.toString() : exp).to.equal( act.toString(), msg + (i + 1) + '/' + expected.length )