diff --git a/packages/zone.js/lib/jasmine/jasmine.ts b/packages/zone.js/lib/jasmine/jasmine.ts index 2ad1e3596e..ff76d4a975 100644 --- a/packages/zone.js/lib/jasmine/jasmine.ts +++ b/packages/zone.js/lib/jasmine/jasmine.ts @@ -127,7 +127,7 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) => const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); if (fakeAsyncZoneSpec) { const dateTime = arguments.length > 0 ? arguments[0] : new Date(); - return fakeAsyncZoneSpec.setCurrentRealTime.apply( + return fakeAsyncZoneSpec.setFakeBaseSystemTime.apply( fakeAsyncZoneSpec, dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] : arguments); diff --git a/packages/zone.js/lib/jest/jest.ts b/packages/zone.js/lib/jest/jest.ts index 651fe0ac96..38fe1129d3 100644 --- a/packages/zone.js/lib/jest/jest.ts +++ b/packages/zone.js/lib/jest/jest.ts @@ -188,7 +188,7 @@ Zone.__load_patch('jest', (context: any, Zone: ZoneType, api: _ZonePrivate) => { return function(self: any, args: any[]) { const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); if (fakeAsyncZoneSpec && isPatchingFakeTimer()) { - fakeAsyncZoneSpec.setCurrentRealTime(args[0]); + fakeAsyncZoneSpec.setFakeBaseSystemTime(args[0]); } else { return delegate.apply(self, args); } diff --git a/packages/zone.js/lib/zone-spec/fake-async-test.ts b/packages/zone.js/lib/zone-spec/fake-async-test.ts index 76f6de53c0..b7ef385c30 100644 --- a/packages/zone.js/lib/zone-spec/fake-async-test.ts +++ b/packages/zone.js/lib/zone-spec/fake-async-test.ts @@ -45,16 +45,15 @@ function FakeDate() { } } -FakeDate.now = - function(this: unknown) { +FakeDate.now = function(this: unknown) { const fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); if (fakeAsyncTestZoneSpec) { - return fakeAsyncTestZoneSpec.getCurrentRealTime() + fakeAsyncTestZoneSpec.getCurrentTime(); + return fakeAsyncTestZoneSpec.getFakeSystemTime(); } return OriginalDate.now.apply(this, arguments); -} +}; - FakeDate.UTC = OriginalDate.UTC; +FakeDate.UTC = OriginalDate.UTC; FakeDate.parse = OriginalDate.parse; // keep a reference for zone patched timer function @@ -72,24 +71,24 @@ class Scheduler { // Scheduler queue with the tuple of end time and callback function - sorted by end time. private _schedulerQueue: ScheduledFunction[] = []; // Current simulated time in millis. - private _currentTime: number = 0; - // Current real time in millis. - private _currentRealTime: number = OriginalDate.now(); + private _currentTickTime: number = 0; + // Current fake system base time in millis. + private _currentFakeBaseSystemTime: number = OriginalDate.now(); // track requeuePeriodicTimer private _currentTickRequeuePeriodicEntries: any[] = []; constructor() {} - getCurrentTime() { - return this._currentTime; + getCurrentTickTime() { + return this._currentTickTime; } - getCurrentRealTime() { - return this._currentRealTime; + getFakeSystemTime() { + return this._currentFakeBaseSystemTime + this._currentTickTime; } - setCurrentRealTime(realTime: number) { - this._currentRealTime = realTime; + setFakeBaseSystemTime(fakeBaseSystemTime: number) { + this._currentFakeBaseSystemTime = fakeBaseSystemTime; } getRealSystemTime() { @@ -114,7 +113,7 @@ class Scheduler { ...options }; let currentId = options.id! < 0 ? Scheduler.nextId++ : options.id!; - let endTime = this._currentTime + delay; + let endTime = this._currentTickTime + delay; // Insert so that scheduler queue remains sorted by end time. let newEntry: ScheduledFunction = { @@ -165,7 +164,7 @@ class Scheduler { } // Find the last task currently queued in the scheduler queue and tick // till that time. - const startTime = this._currentTime; + const startTime = this._currentTickTime; const targetTask = this._schedulerQueue[step - 1]; this.tick(targetTask.endTime - startTime, doTick, tickOptions); } @@ -173,7 +172,7 @@ class Scheduler { tick(millis: number = 0, doTick?: (elapsed: number) => void, tickOptions?: { processNewMacroTasksSynchronously: boolean }): void { - let finalTime = this._currentTime + millis; + let finalTime = this._currentTickTime + millis; let lastCurrentTime = 0; tickOptions = Object.assign({processNewMacroTasksSynchronously: true}, tickOptions); // we need to copy the schedulerQueue so nested timeout @@ -202,13 +201,13 @@ class Scheduler { this._schedulerQueue.splice(idx, 1); } } - lastCurrentTime = this._currentTime; - this._currentTime = current.endTime; + lastCurrentTime = this._currentTickTime; + this._currentTickTime = current.endTime; if (doTick) { - doTick(this._currentTime - lastCurrentTime); + doTick(this._currentTickTime - lastCurrentTime); } let retval = current.func.apply( - global, current.isRequestAnimationFrame ? [this._currentTime] : current.args); + global, current.isRequestAnimationFrame ? [this._currentTickTime] : current.args); if (!retval) { // Uncaught exception in the current scheduled function. Stop processing the queue. break; @@ -230,10 +229,10 @@ class Scheduler { } } } - lastCurrentTime = this._currentTime; - this._currentTime = finalTime; + lastCurrentTime = this._currentTickTime; + this._currentTickTime = finalTime; if (doTick) { - doTick(this._currentTime - lastCurrentTime); + doTick(this._currentTickTime - lastCurrentTime); } } @@ -243,10 +242,10 @@ class Scheduler { } // Find the last task currently queued in the scheduler queue and tick // till that time. - const startTime = this._currentTime; + const startTime = this._currentTickTime; const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1]; this.tick(lastTask.endTime - startTime, doTick, {processNewMacroTasksSynchronously: false}); - return this._currentTime - startTime; + return this._currentTickTime - startTime; } flush(limit = 20, flushPeriodic = false, doTick?: (elapsed: number) => void): number { @@ -263,14 +262,14 @@ class Scheduler { } // Find the last task currently queued in the scheduler queue and tick // till that time. - const startTime = this._currentTime; + const startTime = this._currentTickTime; const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1]; this.tick(lastTask.endTime - startTime, doTick); - return this._currentTime - startTime; + return this._currentTickTime - startTime; } private flushNonPeriodic(limit: number, doTick?: (elapsed: number) => void): number { - const startTime = this._currentTime; + const startTime = this._currentTickTime; let lastCurrentTime = 0; let count = 0; while (this._schedulerQueue.length > 0) { @@ -289,11 +288,11 @@ class Scheduler { } const current = this._schedulerQueue.shift()!; - lastCurrentTime = this._currentTime; - this._currentTime = current.endTime; + lastCurrentTime = this._currentTickTime; + this._currentTickTime = current.endTime; if (doTick) { // Update any secondary schedulers like Jasmine mock Date. - doTick(this._currentTime - lastCurrentTime); + doTick(this._currentTickTime - lastCurrentTime); } const retval = current.func.apply(global, current.args); if (!retval) { @@ -301,7 +300,7 @@ class Scheduler { break; } } - return this._currentTime - startTime; + return this._currentTickTime - startTime; } } @@ -426,16 +425,16 @@ class FakeAsyncTestZoneSpec implements ZoneSpec { throw error; } - getCurrentTime() { - return this._scheduler.getCurrentTime(); + getCurrentTickTime() { + return this._scheduler.getCurrentTickTime(); } - getCurrentRealTime() { - return this._scheduler.getCurrentRealTime(); + getFakeSystemTime() { + return this._scheduler.getFakeSystemTime(); } - setCurrentRealTime(realTime: number) { - this._scheduler.setCurrentRealTime(realTime); + setFakeBaseSystemTime(realTime: number) { + this._scheduler.setFakeBaseSystemTime(realTime); } getRealSystemTime() { diff --git a/packages/zone.js/test/jest/jest.spec.js b/packages/zone.js/test/jest/jest.spec.js index f4a5f0bbf2..77ebc6dbee 100644 --- a/packages/zone.js/test/jest/jest.spec.js +++ b/packages/zone.js/test/jest/jest.spec.js @@ -125,14 +125,23 @@ describe('jest modern fakeTimers with zone.js fakeAsync', () => { expect(typeof fakeAsyncZoneSpec.tick).toEqual('function'); }); - test('setSystemTime should set FakeDate.currentRealTime', () => { + test('setSystemTime should set FakeDate.currentFakeTime', () => { const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); - const d = Date.now(); + let d = fakeAsyncZoneSpec.getRealSystemTime(); jest.setSystemTime(d); expect(Date.now()).toEqual(d); for (let i = 0; i < 100000; i++) { } expect(fakeAsyncZoneSpec.getRealSystemTime()).not.toEqual(d); + d = fakeAsyncZoneSpec.getRealSystemTime(); + let timeoutTriggered = false; + setTimeout(() => { + timeoutTriggered = true; + }, 100); + jest.setSystemTime(d); + tick(100); + expect(timeoutTriggered).toBe(true); + expect(Date.now()).toEqual(d + 100); }); test('runAllTicks should run all microTasks', () => {