From 0f564be6e245b0f3ed6a3c3b215dc7e6e7213ca4 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Sat, 4 Mar 2023 14:59:07 +0100 Subject: [PATCH 01/12] feat(jest-runtime): expose @sinonjs/fake-timers async APIs close #13435 --- docs/JestObjectAPI.md | 48 ++++++++ packages/jest-environment/src/index.ts | 46 ++++++++ .../src/__tests__/modernFakeTimers.test.ts | 107 ++++++++++++++++++ .../jest-fake-timers/src/modernFakeTimers.ts | 28 +++++ packages/jest-runtime/src/index.ts | 44 +++++++ .../jest-types/__typetests__/jest.test.ts | 12 ++ 6 files changed, 285 insertions(+) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index c012e9323d4a..6d56f976522a 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -983,6 +983,54 @@ This function is not available when using legacy fake timers implementation. ::: +### `jest.nextAsync()` + +Advances the clock to the the moment of the first scheduled timer. + +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + +:::info + +This function is not available when using legacy fake timers implementation. + +::: + +### `jest.runAllAsync()` + +Runs all pending timers until there are none remaining. + +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + +:::info + +This function is not available when using legacy fake timers implementation. + +::: + +### `jest.runToLastAsync()` + +Takes note of the last scheduled timer when it is run, and advances the clock to that time firing callbacks as necessary. + +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + +:::info + +This function is not available when using legacy fake timers implementation. + +::: + +### `jest.tickAsync()` + +Advance the clock, firing callbacks if necessary. + +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + +:::info + +This function is not available when using legacy fake timers implementation. + +::: + ## Misc ### `jest.getSeed()` diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index f503703519fe..56fc87f83939 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -186,6 +186,17 @@ export interface Jest { * `isolateModulesAsync`. */ isolateModulesAsync(fn: () => Promise): Promise; + /** + * Advances the clock to the the moment of the first scheduled timer, firing it. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @returns + * Fake milliseconds since the unix epoch. + * @remarks + * Not available when using legacy fake timers implementation. + */ + nextAsync(): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ @@ -281,6 +292,18 @@ export interface Jest { numRetries: number, options?: {logErrorsBeforeRetry?: boolean}, ): Jest; + /** + * Runs all pending timers until there are none remaining. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @returns Fake milliseconds since the unix epoch. + * @remarks + * If new timers are added while it is executing they will be run as well. + * @remarks + * Not available when using legacy fake timers implementation. + */ + runAllAsync: () => Promise; /** * Exhausts tasks queued by `setImmediate()`. * @@ -305,6 +328,17 @@ export interface Jest { * macro-tasks, those new tasks will not be executed by this call. */ runOnlyPendingTimers(): void; + /** + * Takes note of the last scheduled timer when it is run, and advances the clock to + * that time firing callbacks as necessary. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * @returns + * Fake milliseconds since the unix epoch. + * @remarks + * Not available when using legacy fake timers implementation. + */ + runToLastAsync: () => Promise; /** * Explicitly supplies the mock object that the module system should return * for the specified module. @@ -344,6 +378,18 @@ export interface Jest { * behavior from most other test libraries. */ spyOn: ModuleMocker['spyOn']; + /** + * Advance the clock, firing callbacks if necessary. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @param time How many ticks to advance by. + * @returns + * Fake milliseconds since the unix epoch. + * @remarks + * Not available when using legacy fake timers implementation. + */ + tickAsync(time: string | number): Promise; /** * Indicates that the module system should never return a mocked version of * the specified module from `require()` (e.g. that it should always return the diff --git a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts index 72afd53bfdb1..1785207ac2d1 100644 --- a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts +++ b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts @@ -960,6 +960,113 @@ describe('FakeTimers', () => { }); }); + describe('nextAsync', () => { + it('should advance the clock at the moment of the first scheduled timer', async () => { + const global = { + Date, + Promise, + clearTimeout, + process, + setTimeout, + } as unknown as typeof globalThis; + const timers = new FakeTimers({config: makeProjectConfig(), global}); + timers.useFakeTimers(); + timers.setSystemTime(0); + + const spy = jest.fn(); + global.setTimeout(async () => { + await Promise.resolve(); + global.setTimeout(spy, 100); + }, 100); + + await timers.nextAsync(); + expect(timers.now()).toBe(100); + + await timers.nextAsync(); + expect(timers.now()).toBe(200); + expect(spy).toHaveBeenCalled(); + }); + }); + + describe('runAllAsync', () => { + it('should advance the clock to the last scheduled timer', async () => { + const global = { + Date, + Promise, + clearTimeout, + process, + setTimeout, + } as unknown as typeof globalThis; + const timers = new FakeTimers({config: makeProjectConfig(), global}); + timers.useFakeTimers(); + timers.setSystemTime(0); + + const spy = jest.fn(); + const spy2 = jest.fn(); + global.setTimeout(async () => { + await Promise.resolve(); + global.setTimeout(spy, 100); + global.setTimeout(spy2, 200); + }, 100); + + await timers.runAllAsync(); + expect(timers.now()).toBe(300); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + }); + }); + + describe('runToLastAsync', () => { + it('should advance the clock to the last scheduled timer', async () => { + const global = { + Date, + Promise, + clearTimeout, + process, + setTimeout, + } as unknown as typeof globalThis; + const timers = new FakeTimers({config: makeProjectConfig(), global}); + timers.useFakeTimers(); + timers.setSystemTime(0); + + const spy = jest.fn(); + const spy2 = jest.fn(); + global.setTimeout(spy, 50); + global.setTimeout(spy2, 50); + global.setTimeout(async () => { + await Promise.resolve(); + }, 100); + + await timers.runToLastAsync(); + expect(timers.now()).toBe(100); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + }); + }); + + describe('tickAsync', () => { + it('should advance the clock', async () => { + const global = { + Date, + Promise, + clearTimeout, + process, + setTimeout, + } as unknown as typeof globalThis; + const timers = new FakeTimers({config: makeProjectConfig(), global}); + timers.useFakeTimers(); + + const spy = jest.fn(); + global.setTimeout(async () => { + await Promise.resolve(); + global.setTimeout(spy, 100); + }, 100); + + await timers.tickAsync(200); + expect(spy).toHaveBeenCalled(); + }); + }); + describe('now', () => { let timers: FakeTimers; let fakedGlobal: typeof globalThis; diff --git a/packages/jest-fake-timers/src/modernFakeTimers.ts b/packages/jest-fake-timers/src/modernFakeTimers.ts index f1178707ec5b..fc0723cea97d 100644 --- a/packages/jest-fake-timers/src/modernFakeTimers.ts +++ b/packages/jest-fake-timers/src/modernFakeTimers.ts @@ -137,6 +137,34 @@ export default class FakeTimers { return 0; } + nextAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.nextAsync(); + } + return Promise.resolve(0); + } + + runAllAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.runAllAsync(); + } + return Promise.resolve(0); + } + + runToLastAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.runToLastAsync(); + } + return Promise.resolve(0); + } + + tickAsync(time: string | number): Promise { + if (this._checkFakeTimers()) { + return this._clock.tickAsync(time); + } + return Promise.resolve(0); + } + private _checkFakeTimers() { if (!this._fakingTime) { this._global.console.warn( diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index b638e2927577..d849c660b1e7 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2270,6 +2270,17 @@ export default class Runtime { isolateModulesAsync: this.isolateModulesAsync, mock, mocked, + nextAsync: (): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.nextAsync(); + } else { + throw new TypeError( + '`jest.nextAsync()` is not available when using legacy fake timers.', + ); + } + }, now: () => _getFakeTimers().now(), replaceProperty, requireActual: moduleName => this.requireActual(from, moduleName), @@ -2278,6 +2289,17 @@ export default class Runtime { resetModules, restoreAllMocks, retryTimes, + runAllAsync: (): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.runAllAsync(); + } else { + throw new TypeError( + '`jest.runAllAsync()` is not available when using legacy fake timers.', + ); + } + }, runAllImmediates: () => { const fakeTimers = _getFakeTimers(); @@ -2292,6 +2314,17 @@ export default class Runtime { runAllTicks: () => _getFakeTimers().runAllTicks(), runAllTimers: () => _getFakeTimers().runAllTimers(), runOnlyPendingTimers: () => _getFakeTimers().runOnlyPendingTimers(), + runToLastAsync: (): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.runToLastAsync(); + } else { + throw new TypeError( + '`jest.runToLastAsync()` is not available when using legacy fake timers.', + ); + } + }, setMock: (moduleName: string, mock: unknown) => setMockFactory(moduleName, () => mock), setSystemTime: (now?: number | Date) => { @@ -2307,6 +2340,17 @@ export default class Runtime { }, setTimeout, spyOn, + tickAsync: (time: number | string): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.tickAsync(time); + } else { + throw new TypeError( + '`jest.tickAsync()` is not available when using legacy fake timers.', + ); + } + }, unmock, unstable_mockModule: mockModule, useFakeTimers, diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 6a1042a45488..215ad2b909f2 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -574,6 +574,18 @@ expectError(jest.useFakeTimers('modern')); expectType(jest.useRealTimers()); expectError(jest.useRealTimers(true)); +expectType>(jest.tickAsync(250)); +expectError(jest.tickAsync()); + +expectType>(jest.nextAsync()); +expectError(jest.nextAsync('jest')); + +expectType>(jest.runAllAsync()); +expectError(jest.runAllAsync('jest')); + +expectType>(jest.runToLastAsync()); +expectError(jest.runToLastAsync('jest')); + // Misc expectType(jest.retryTimes(3)); From d1f54cea5da8bd4e1b922ce42d91a8efa75f1515 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Sat, 4 Mar 2023 15:10:43 +0100 Subject: [PATCH 02/12] Updated CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f98b97eb773b..28ea0018199e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - `[jest-runtime, @jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#13974](https://github.com/facebook/jest/pull/13974)) - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) +- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `nextAsync`, `runAllAsync`, `runToLastAsync`, and `tickAsync(time)` ([#13981](https://github.com/facebook/jest/pull/13981)) ### Fixes From 860ed38463628ebf34b44ee237023a1ad81a4c89 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Sun, 5 Mar 2023 09:23:21 +0100 Subject: [PATCH 03/12] updated fake-timers async API method names --- CHANGELOG.md | 2 +- docs/JestObjectAPI.md | 8 +-- packages/jest-environment/src/index.ts | 59 ++++++++-------- .../src/__tests__/modernFakeTimers.test.ts | 18 ++--- .../jest-fake-timers/src/modernFakeTimers.ts | 56 +++++++-------- packages/jest-runtime/src/index.ts | 70 +++++++++---------- .../jest-types/__typetests__/jest.test.ts | 16 ++--- 7 files changed, 116 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28ea0018199e..12e2bf260273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - `[jest-runtime, @jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#13974](https://github.com/facebook/jest/pull/13974)) - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) -- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `nextAsync`, `runAllAsync`, `runToLastAsync`, and `tickAsync(time)` ([#13981](https://github.com/facebook/jest/pull/13981)) +- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersToNextTimerAsync` (`nextAsync`), `runOnlyPendingTimersAsync` (`runToLastAsync`), `runAllTimersAsync` (`runAllAsync`), and `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`) ([#13981](https://github.com/facebook/jest/pull/13981)) ### Fixes diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 6d56f976522a..84e7507278a6 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -983,7 +983,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.nextAsync()` +### `jest.advanceTimersToNextTimerAsync()` Advances the clock to the the moment of the first scheduled timer. @@ -995,7 +995,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.runAllAsync()` +### `jest.runAllTimers()` Runs all pending timers until there are none remaining. @@ -1007,7 +1007,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.runToLastAsync()` +### `jest.runOnlyPendingTimersAsync()` Takes note of the last scheduled timer when it is run, and advances the clock to that time firing callbacks as necessary. @@ -1019,7 +1019,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.tickAsync()` +### `jest.advanceTimersByTimeAsync()` Advance the clock, firing callbacks if necessary. diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 56fc87f83939..68fbe019224e 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -60,6 +60,17 @@ export interface Jest { * executed within this time frame will be executed. */ advanceTimersByTime(msToRun: number): void; + /** + * Advances all timers by `msToRun` milliseconds, firing callbacks if necessary. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @returns + * Fake milliseconds since the unix epoch. + * @remarks + * Not available when using legacy fake timers implementation. + */ + advanceTimersByTimeAsync(msToRun: number): Promise; /** * Advances all timers by the needed milliseconds so that only the next * timeouts/intervals will run. Optionally, you can provide steps, so it will @@ -196,7 +207,7 @@ export interface Jest { * @remarks * Not available when using legacy fake timers implementation. */ - nextAsync(): Promise; + advanceTimersToNextTimerAsync(): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ @@ -292,18 +303,6 @@ export interface Jest { numRetries: number, options?: {logErrorsBeforeRetry?: boolean}, ): Jest; - /** - * Runs all pending timers until there are none remaining. - * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. - * - * @returns Fake milliseconds since the unix epoch. - * @remarks - * If new timers are added while it is executing they will be run as well. - * @remarks - * Not available when using legacy fake timers implementation. - */ - runAllAsync: () => Promise; /** * Exhausts tasks queued by `setImmediate()`. * @@ -321,6 +320,19 @@ export interface Jest { * and `setInterval()`). */ runAllTimers(): void; + /** + * Exhausts the macro-task queue (i.e., all tasks queued by `setTimeout()` + * and `setInterval()`). + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @returns Fake milliseconds since the unix epoch. + * @remarks + * If new timers are added while it is executing they will be run as well. + * @remarks + * Not available when using legacy fake timers implementation. + */ + runAllTimersAsync: () => Promise; /** * Executes only the macro-tasks that are currently pending (i.e., only the * tasks that have been queued by `setTimeout()` or `setInterval()` up to this @@ -329,16 +341,19 @@ export interface Jest { */ runOnlyPendingTimers(): void; /** - * Takes note of the last scheduled timer when it is run, and advances the clock to - * that time firing callbacks as necessary. + * Executes only the macro-tasks that are currently pending (i.e., only the + * tasks that have been queued by `setTimeout()` or `setInterval()` up to this + * point). If any of the currently pending macro-tasks schedule new + * macro-tasks, those new tasks will not be executed by this call. * * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * * @returns * Fake milliseconds since the unix epoch. * @remarks * Not available when using legacy fake timers implementation. */ - runToLastAsync: () => Promise; + runOnlyPendingTimersAsync: () => Promise; /** * Explicitly supplies the mock object that the module system should return * for the specified module. @@ -378,18 +393,6 @@ export interface Jest { * behavior from most other test libraries. */ spyOn: ModuleMocker['spyOn']; - /** - * Advance the clock, firing callbacks if necessary. - * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. - * - * @param time How many ticks to advance by. - * @returns - * Fake milliseconds since the unix epoch. - * @remarks - * Not available when using legacy fake timers implementation. - */ - tickAsync(time: string | number): Promise; /** * Indicates that the module system should never return a mocked version of * the specified module from `require()` (e.g. that it should always return the diff --git a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts index 1785207ac2d1..6dfe19001b19 100644 --- a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts +++ b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts @@ -960,7 +960,7 @@ describe('FakeTimers', () => { }); }); - describe('nextAsync', () => { + describe('advanceTimersToNextTimerAsync', () => { it('should advance the clock at the moment of the first scheduled timer', async () => { const global = { Date, @@ -979,16 +979,16 @@ describe('FakeTimers', () => { global.setTimeout(spy, 100); }, 100); - await timers.nextAsync(); + await timers.advanceTimersToNextTimerAsync(); expect(timers.now()).toBe(100); - await timers.nextAsync(); + await timers.advanceTimersToNextTimerAsync(); expect(timers.now()).toBe(200); expect(spy).toHaveBeenCalled(); }); }); - describe('runAllAsync', () => { + describe('runAllTimersAsync', () => { it('should advance the clock to the last scheduled timer', async () => { const global = { Date, @@ -1009,14 +1009,14 @@ describe('FakeTimers', () => { global.setTimeout(spy2, 200); }, 100); - await timers.runAllAsync(); + await timers.runAllTimersAsync(); expect(timers.now()).toBe(300); expect(spy).toHaveBeenCalled(); expect(spy2).toHaveBeenCalled(); }); }); - describe('runToLastAsync', () => { + describe('runOnlyPendingTimersAsync', () => { it('should advance the clock to the last scheduled timer', async () => { const global = { Date, @@ -1037,14 +1037,14 @@ describe('FakeTimers', () => { await Promise.resolve(); }, 100); - await timers.runToLastAsync(); + await timers.runOnlyPendingTimersAsync(); expect(timers.now()).toBe(100); expect(spy).toHaveBeenCalled(); expect(spy2).toHaveBeenCalled(); }); }); - describe('tickAsync', () => { + describe('advanceTimersByTimeAsync', () => { it('should advance the clock', async () => { const global = { Date, @@ -1062,7 +1062,7 @@ describe('FakeTimers', () => { global.setTimeout(spy, 100); }, 100); - await timers.tickAsync(200); + await timers.advanceTimersByTimeAsync(200); expect(spy).toHaveBeenCalled(); }); }); diff --git a/packages/jest-fake-timers/src/modernFakeTimers.ts b/packages/jest-fake-timers/src/modernFakeTimers.ts index fc0723cea97d..cf63ffe11eb3 100644 --- a/packages/jest-fake-timers/src/modernFakeTimers.ts +++ b/packages/jest-fake-timers/src/modernFakeTimers.ts @@ -52,12 +52,26 @@ export default class FakeTimers { } } + runAllTimersAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.runAllAsync(); + } + return Promise.resolve(0); + } + runOnlyPendingTimers(): void { if (this._checkFakeTimers()) { this._clock.runToLast(); } } + runOnlyPendingTimersAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.runToLastAsync(); + } + return Promise.resolve(0); + } + advanceTimersToNextTimer(steps = 1): void { if (this._checkFakeTimers()) { for (let i = steps; i > 0; i--) { @@ -72,12 +86,26 @@ export default class FakeTimers { } } + advanceTimersToNextTimerAsync(): Promise { + if (this._checkFakeTimers()) { + return this._clock.nextAsync(); + } + return Promise.resolve(0); + } + advanceTimersByTime(msToRun: number): void { if (this._checkFakeTimers()) { this._clock.tick(msToRun); } } + advanceTimersByTimeAsync(msToRun: number): Promise { + if (this._checkFakeTimers()) { + return this._clock.tickAsync(msToRun); + } + return Promise.resolve(0); + } + runAllTicks(): void { if (this._checkFakeTimers()) { // @ts-expect-error - doesn't exist? @@ -137,34 +165,6 @@ export default class FakeTimers { return 0; } - nextAsync(): Promise { - if (this._checkFakeTimers()) { - return this._clock.nextAsync(); - } - return Promise.resolve(0); - } - - runAllAsync(): Promise { - if (this._checkFakeTimers()) { - return this._clock.runAllAsync(); - } - return Promise.resolve(0); - } - - runToLastAsync(): Promise { - if (this._checkFakeTimers()) { - return this._clock.runToLastAsync(); - } - return Promise.resolve(0); - } - - tickAsync(time: string | number): Promise { - if (this._checkFakeTimers()) { - return this._clock.tickAsync(time); - } - return Promise.resolve(0); - } - private _checkFakeTimers() { if (!this._fakingTime) { this._global.console.warn( diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 95e1edbd083b..6fd5132dd375 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2231,8 +2231,30 @@ export default class Runtime { const jestObject: Jest = { advanceTimersByTime: (msToRun: number) => _getFakeTimers().advanceTimersByTime(msToRun), + advanceTimersByTimeAsync: (msToRun: number): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.advanceTimersByTimeAsync(msToRun); + } else { + throw new TypeError( + '`jest.advanceTimersByTimeAsync()` is not available when using legacy fake timers.', + ); + } + }, advanceTimersToNextTimer: (steps?: number) => _getFakeTimers().advanceTimersToNextTimer(steps), + advanceTimersToNextTimerAsync: (): Promise => { + const fakeTimers = _getFakeTimers(); + + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.advanceTimersToNextTimerAsync(); + } else { + throw new TypeError( + '`jest.advanceTimersToNextTimerAsync()` is not available when using legacy fake timers.', + ); + } + }, autoMockOff: disableAutomock, autoMockOn: enableAutomock, clearAllMocks, @@ -2274,17 +2296,6 @@ export default class Runtime { isolateModulesAsync: this.isolateModulesAsync, mock, mocked, - nextAsync: (): Promise => { - const fakeTimers = _getFakeTimers(); - - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.nextAsync(); - } else { - throw new TypeError( - '`jest.nextAsync()` is not available when using legacy fake timers.', - ); - } - }, now: () => _getFakeTimers().now(), replaceProperty, requireActual: moduleName => this.requireActual(from, moduleName), @@ -2293,39 +2304,39 @@ export default class Runtime { resetModules, restoreAllMocks, retryTimes, - runAllAsync: (): Promise => { + runAllImmediates: () => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.runAllAsync(); + if (fakeTimers === this._environment.fakeTimers) { + fakeTimers.runAllImmediates(); } else { throw new TypeError( - '`jest.runAllAsync()` is not available when using legacy fake timers.', + '`jest.runAllImmediates()` is only available when using legacy fake timers.', ); } }, - runAllImmediates: () => { + runAllTicks: () => _getFakeTimers().runAllTicks(), + runAllTimers: () => _getFakeTimers().runAllTimers(), + runAllTimersAsync: (): Promise => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimers) { - fakeTimers.runAllImmediates(); + if (fakeTimers === this._environment.fakeTimersModern) { + return fakeTimers.runAllTimersAsync(); } else { throw new TypeError( - '`jest.runAllImmediates()` is only available when using legacy fake timers.', + '`jest.runAllTimersAsync()` is not available when using legacy fake timers.', ); } }, - runAllTicks: () => _getFakeTimers().runAllTicks(), - runAllTimers: () => _getFakeTimers().runAllTimers(), runOnlyPendingTimers: () => _getFakeTimers().runOnlyPendingTimers(), - runToLastAsync: (): Promise => { + runOnlyPendingTimersAsync: (): Promise => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.runToLastAsync(); + return fakeTimers.runOnlyPendingTimersAsync(); } else { throw new TypeError( - '`jest.runToLastAsync()` is not available when using legacy fake timers.', + '`jest.runOnlyPendingTimersAsync()` is not available when using legacy fake timers.', ); } }, @@ -2344,17 +2355,6 @@ export default class Runtime { }, setTimeout, spyOn, - tickAsync: (time: number | string): Promise => { - const fakeTimers = _getFakeTimers(); - - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.tickAsync(time); - } else { - throw new TypeError( - '`jest.tickAsync()` is not available when using legacy fake timers.', - ); - } - }, unmock, unstable_mockModule: mockModule, useFakeTimers, diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 215ad2b909f2..e2c379e7166c 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -574,17 +574,17 @@ expectError(jest.useFakeTimers('modern')); expectType(jest.useRealTimers()); expectError(jest.useRealTimers(true)); -expectType>(jest.tickAsync(250)); -expectError(jest.tickAsync()); +expectType>(jest.advanceTimersByTimeAsync(250)); +expectError(jest.advanceTimersByTimeAsync()); -expectType>(jest.nextAsync()); -expectError(jest.nextAsync('jest')); +expectType>(jest.advanceTimersToNextTimerAsync()); +expectError(jest.advanceTimersToNextTimerAsync('jest')); -expectType>(jest.runAllAsync()); -expectError(jest.runAllAsync('jest')); +expectType>(jest.runAllTimersAsync()); +expectError(jest.runAllTimersAsync('jest')); -expectType>(jest.runToLastAsync()); -expectError(jest.runToLastAsync('jest')); +expectType>(jest.runOnlyPendingTimersAsync()); +expectError(jest.runOnlyPendingTimersAsync('jest')); // Misc From f927e60d843c9c3cfd5db3770db6992c84c3f118 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Sun, 5 Mar 2023 09:25:23 +0100 Subject: [PATCH 04/12] fixed method name and added parameter in documentation --- docs/JestObjectAPI.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 84e7507278a6..97ff75a495d2 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -995,7 +995,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.runAllTimers()` +### `jest.runAllTimersAsync()` Runs all pending timers until there are none remaining. @@ -1019,7 +1019,7 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.advanceTimersByTimeAsync()` +### `jest.advanceTimersByTimeAsync(msToRun)` Advance the clock, firing callbacks if necessary. From 0324d78fbc8426d047af2be70407c250913f308a Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 10:29:34 +0100 Subject: [PATCH 05/12] chenged methods return type, added test environment check, and fixed alphabetical ordering --- CHANGELOG.md | 2 +- docs/JestObjectAPI.md | 76 +++++++++---------- packages/jest-environment/src/index.ts | 30 +++----- .../jest-fake-timers/src/modernFakeTimers.ts | 20 ++--- packages/jest-runtime/src/index.ts | 36 ++++++--- .../jest-types/__typetests__/jest.test.ts | 24 +++--- 6 files changed, 95 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12e2bf260273..8acdec9bcdd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - `[jest-runtime, @jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#13974](https://github.com/facebook/jest/pull/13974)) - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) -- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersToNextTimerAsync` (`nextAsync`), `runOnlyPendingTimersAsync` (`runToLastAsync`), `runAllTimersAsync` (`runAllAsync`), and `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`) ([#13981](https://github.com/facebook/jest/pull/13981)) +- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#13981](https://github.com/facebook/jest/pull/13981)) ### Fixes diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 97ff75a495d2..c45f239ae0ce 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -921,6 +921,18 @@ When this API is called, all pending macro-tasks and micro-tasks will be execute This is often useful for synchronously executing setTimeouts during a test in order to synchronously assert about some behavior that would only happen after the `setTimeout()` or `setInterval()` callbacks executed. See the [Timer mocks](TimerMocks.md) doc for more information. +### `jest.runAllTimersAsync()` + +Runs all pending timers until there are none remaining. + +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + +:::info + +This function is not available when using legacy fake timers implementation. + +::: + ### `jest.runAllImmediates()` Exhausts all tasks queued by `setImmediate()`. @@ -937,35 +949,29 @@ Executes only the macro task queue (i.e. all tasks queued by `setTimeout()` or ` When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via `setTimeout()` or `setInterval()`, and would be executed within this time frame will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within `msToRun` milliseconds. -### `jest.runOnlyPendingTimers()` - -Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by `setTimeout()` or `setInterval()` up to this point). If any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call. - -This is useful for scenarios such as one where the module being tested schedules a `setTimeout()` whose callback schedules another `setTimeout()` recursively (meaning the scheduling never stops). In these scenarios, it's useful to be able to run forward in time by a single step at a time. - -### `jest.advanceTimersToNextTimer(steps)` +### `jest.advanceTimersByTimeAsync(msToRun)` -Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run. +Advance the clock, firing callbacks if necessary. -Optionally, you can provide `steps`, so it will run `steps` amount of next timeouts/intervals. +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. -### `jest.clearAllTimers()` +:::info -Removes any pending timers from the timer system. +This function is not available when using legacy fake timers implementation. -This means, if any timers have been scheduled (but have not yet executed), they will be cleared and will never have the opportunity to execute in the future. +::: -### `jest.getTimerCount()` +### `jest.runOnlyPendingTimers()` -Returns the number of fake timers still left to run. +Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by `setTimeout()` or `setInterval()` up to this point). If any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call. -### `jest.now()` +This is useful for scenarios such as one where the module being tested schedules a `setTimeout()` whose callback schedules another `setTimeout()` recursively (meaning the scheduling never stops). In these scenarios, it's useful to be able to run forward in time by a single step at a time. -Returns the time in ms of the current clock. This is equivalent to `Date.now()` if real timers are in use, or if `Date` is mocked. In other cases (such as legacy timers) it may be useful for implementing custom mocks of `Date.now()`, `performance.now()`, etc. +### `jest.runOnlyPendingTimersAsync()` -### `jest.setSystemTime(now?: number | Date)` +Takes note of the last scheduled timer when it is run, and advances the clock to that time firing callbacks as necessary. -Set the current system time used by fake timers. Simulates a user changing the system clock while your program is running. It affects the current time but it does not in itself cause e.g. timers to fire; they will fire exactly as they would have done without the call to `jest.setSystemTime()`. +Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. :::info @@ -973,15 +979,11 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.getRealSystemTime()` - -When mocking time, `Date.now()` will also be mocked. If you for some reason need access to the real current time, you can invoke this function. - -:::info +### `jest.advanceTimersToNextTimer(steps)` -This function is not available when using legacy fake timers implementation. +Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run. -::: +Optionally, you can provide `steps`, so it will run `steps` amount of next timeouts/intervals. ### `jest.advanceTimersToNextTimerAsync()` @@ -995,23 +997,23 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.runAllTimersAsync()` +### `jest.clearAllTimers()` -Runs all pending timers until there are none remaining. +Removes any pending timers from the timer system. -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +This means, if any timers have been scheduled (but have not yet executed), they will be cleared and will never have the opportunity to execute in the future. -:::info +### `jest.getTimerCount()` -This function is not available when using legacy fake timers implementation. +Returns the number of fake timers still left to run. -::: +### `jest.now()` -### `jest.runOnlyPendingTimersAsync()` +Returns the time in ms of the current clock. This is equivalent to `Date.now()` if real timers are in use, or if `Date` is mocked. In other cases (such as legacy timers) it may be useful for implementing custom mocks of `Date.now()`, `performance.now()`, etc. -Takes note of the last scheduled timer when it is run, and advances the clock to that time firing callbacks as necessary. +### `jest.setSystemTime(now?: number | Date)` -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +Set the current system time used by fake timers. Simulates a user changing the system clock while your program is running. It affects the current time but it does not in itself cause e.g. timers to fire; they will fire exactly as they would have done without the call to `jest.setSystemTime()`. :::info @@ -1019,11 +1021,9 @@ This function is not available when using legacy fake timers implementation. ::: -### `jest.advanceTimersByTimeAsync(msToRun)` - -Advance the clock, firing callbacks if necessary. +### `jest.getRealSystemTime()` -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +When mocking time, `Date.now()` will also be mocked. If you for some reason need access to the real current time, you can invoke this function. :::info diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 68fbe019224e..5680c8707391 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -65,18 +65,25 @@ export interface Jest { * * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. * - * @returns - * Fake milliseconds since the unix epoch. * @remarks * Not available when using legacy fake timers implementation. */ - advanceTimersByTimeAsync(msToRun: number): Promise; + advanceTimersByTimeAsync(msToRun: number): Promise; /** * Advances all timers by the needed milliseconds so that only the next * timeouts/intervals will run. Optionally, you can provide steps, so it will * run steps amount of next timeouts/intervals. */ advanceTimersToNextTimer(steps?: number): void; + /** + * Advances the clock to the the moment of the first scheduled timer, firing it. + * + * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * + * @remarks + * Not available when using legacy fake timers implementation. + */ + advanceTimersToNextTimerAsync(): Promise; /** * Disables automatic mocking in the module loader. */ @@ -197,17 +204,6 @@ export interface Jest { * `isolateModulesAsync`. */ isolateModulesAsync(fn: () => Promise): Promise; - /** - * Advances the clock to the the moment of the first scheduled timer, firing it. - * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. - * - * @returns - * Fake milliseconds since the unix epoch. - * @remarks - * Not available when using legacy fake timers implementation. - */ - advanceTimersToNextTimerAsync(): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ @@ -332,7 +328,7 @@ export interface Jest { * @remarks * Not available when using legacy fake timers implementation. */ - runAllTimersAsync: () => Promise; + runAllTimersAsync: () => Promise; /** * Executes only the macro-tasks that are currently pending (i.e., only the * tasks that have been queued by `setTimeout()` or `setInterval()` up to this @@ -348,12 +344,10 @@ export interface Jest { * * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. * - * @returns - * Fake milliseconds since the unix epoch. * @remarks * Not available when using legacy fake timers implementation. */ - runOnlyPendingTimersAsync: () => Promise; + runOnlyPendingTimersAsync: () => Promise; /** * Explicitly supplies the mock object that the module system should return * for the specified module. diff --git a/packages/jest-fake-timers/src/modernFakeTimers.ts b/packages/jest-fake-timers/src/modernFakeTimers.ts index cf63ffe11eb3..d0ec79016908 100644 --- a/packages/jest-fake-timers/src/modernFakeTimers.ts +++ b/packages/jest-fake-timers/src/modernFakeTimers.ts @@ -52,11 +52,10 @@ export default class FakeTimers { } } - runAllTimersAsync(): Promise { + async runAllTimersAsync(): Promise { if (this._checkFakeTimers()) { - return this._clock.runAllAsync(); + await this._clock.runAllAsync(); } - return Promise.resolve(0); } runOnlyPendingTimers(): void { @@ -65,11 +64,10 @@ export default class FakeTimers { } } - runOnlyPendingTimersAsync(): Promise { + async runOnlyPendingTimersAsync(): Promise { if (this._checkFakeTimers()) { - return this._clock.runToLastAsync(); + await this._clock.runToLastAsync(); } - return Promise.resolve(0); } advanceTimersToNextTimer(steps = 1): void { @@ -86,11 +84,10 @@ export default class FakeTimers { } } - advanceTimersToNextTimerAsync(): Promise { + async advanceTimersToNextTimerAsync(): Promise { if (this._checkFakeTimers()) { - return this._clock.nextAsync(); + await this._clock.nextAsync(); } - return Promise.resolve(0); } advanceTimersByTime(msToRun: number): void { @@ -99,11 +96,10 @@ export default class FakeTimers { } } - advanceTimersByTimeAsync(msToRun: number): Promise { + async advanceTimersByTimeAsync(msToRun: number): Promise { if (this._checkFakeTimers()) { - return this._clock.tickAsync(msToRun); + await this._clock.tickAsync(msToRun); } - return Promise.resolve(0); } runAllTicks(): void { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 6fd5132dd375..fdac8fe2d6af 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2231,11 +2231,14 @@ export default class Runtime { const jestObject: Jest = { advanceTimersByTime: (msToRun: number) => _getFakeTimers().advanceTimersByTime(msToRun), - advanceTimersByTimeAsync: (msToRun: number): Promise => { + advanceTimersByTimeAsync: async (msToRun: number): Promise => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.advanceTimersByTimeAsync(msToRun); + if ( + fakeTimers === this._environment.fakeTimersModern && + typeof fakeTimers.advanceTimersByTimeAsync === 'function' + ) { + await fakeTimers.advanceTimersByTimeAsync(msToRun); } else { throw new TypeError( '`jest.advanceTimersByTimeAsync()` is not available when using legacy fake timers.', @@ -2244,11 +2247,14 @@ export default class Runtime { }, advanceTimersToNextTimer: (steps?: number) => _getFakeTimers().advanceTimersToNextTimer(steps), - advanceTimersToNextTimerAsync: (): Promise => { + advanceTimersToNextTimerAsync: async (): Promise => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.advanceTimersToNextTimerAsync(); + if ( + fakeTimers === this._environment.fakeTimersModern && + typeof fakeTimers.advanceTimersToNextTimerAsync === 'function' + ) { + await fakeTimers.advanceTimersToNextTimerAsync(); } else { throw new TypeError( '`jest.advanceTimersToNextTimerAsync()` is not available when using legacy fake timers.', @@ -2317,11 +2323,14 @@ export default class Runtime { }, runAllTicks: () => _getFakeTimers().runAllTicks(), runAllTimers: () => _getFakeTimers().runAllTimers(), - runAllTimersAsync: (): Promise => { + runAllTimersAsync: async (): Promise => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.runAllTimersAsync(); + if ( + fakeTimers === this._environment.fakeTimersModern && + typeof fakeTimers.runAllTimersAsync === 'function' + ) { + await fakeTimers.runAllTimersAsync(); } else { throw new TypeError( '`jest.runAllTimersAsync()` is not available when using legacy fake timers.', @@ -2329,11 +2338,14 @@ export default class Runtime { } }, runOnlyPendingTimers: () => _getFakeTimers().runOnlyPendingTimers(), - runOnlyPendingTimersAsync: (): Promise => { + runOnlyPendingTimersAsync: async (): Promise => { const fakeTimers = _getFakeTimers(); - if (fakeTimers === this._environment.fakeTimersModern) { - return fakeTimers.runOnlyPendingTimersAsync(); + if ( + fakeTimers === this._environment.fakeTimersModern && + typeof fakeTimers.runOnlyPendingTimersAsync === 'function' + ) { + await fakeTimers.runOnlyPendingTimersAsync(); } else { throw new TypeError( '`jest.runOnlyPendingTimersAsync()` is not available when using legacy fake timers.', diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index e2c379e7166c..4e7c4143602f 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -488,10 +488,16 @@ expectAssignable>( expectType(jest.advanceTimersByTime(6000)); expectError(jest.advanceTimersByTime()); +expectType>(jest.advanceTimersByTimeAsync(6000)); +expectError(jest.advanceTimersByTimeAsync()); + expectType(jest.advanceTimersToNextTimer()); expectType(jest.advanceTimersToNextTimer(2)); expectError(jest.advanceTimersToNextTimer('2')); +expectType>(jest.advanceTimersToNextTimerAsync()); +expectError(jest.advanceTimersToNextTimerAsync('2')); + expectType(jest.clearAllTimers()); expectError(jest.clearAllTimers(false)); @@ -513,9 +519,15 @@ expectError(jest.runAllTicks(true)); expectType(jest.runAllTimers()); expectError(jest.runAllTimers(false)); +expectType>(jest.runAllTimersAsync()); +expectError(jest.runAllTimersAsync(false)); + expectType(jest.runOnlyPendingTimers()); expectError(jest.runOnlyPendingTimers(true)); +expectType>(jest.runOnlyPendingTimersAsync()); +expectError(jest.runOnlyPendingTimersAsync(true)); + expectType(jest.setSystemTime()); expectType(jest.setSystemTime(1483228800000)); expectType(jest.setSystemTime(Date.now())); @@ -574,18 +586,6 @@ expectError(jest.useFakeTimers('modern')); expectType(jest.useRealTimers()); expectError(jest.useRealTimers(true)); -expectType>(jest.advanceTimersByTimeAsync(250)); -expectError(jest.advanceTimersByTimeAsync()); - -expectType>(jest.advanceTimersToNextTimerAsync()); -expectError(jest.advanceTimersToNextTimerAsync('jest')); - -expectType>(jest.runAllTimersAsync()); -expectError(jest.runAllTimersAsync('jest')); - -expectType>(jest.runOnlyPendingTimersAsync()); -expectError(jest.runOnlyPendingTimersAsync('jest')); - // Misc expectType(jest.retryTimes(3)); From f048d1a3037da330fe598ef135dfdc10ebed9d27 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 10:32:35 +0100 Subject: [PATCH 06/12] fixed return type --- packages/jest-environment/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 5680c8707391..0bc97f30d467 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -322,7 +322,6 @@ export interface Jest { * * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. * - * @returns Fake milliseconds since the unix epoch. * @remarks * If new timers are added while it is executing they will be run as well. * @remarks From eb4c655018e1ee7bb67f04afa84339ee82107241 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 11:56:50 +0100 Subject: [PATCH 07/12] fixed documentation, added advanceTimersToNextTimerAsync steps parameter --- CHANGELOG.md | 2 +- docs/JestObjectAPI.md | 18 ++++---------- packages/jest-environment/src/index.ts | 16 +++++++++---- .../src/__tests__/modernFakeTimers.test.ts | 24 +++++++++++++++++++ .../jest-fake-timers/src/modernFakeTimers.ts | 12 ++++++++-- packages/jest-runtime/src/index.ts | 8 +++++-- .../jest-types/__typetests__/jest.test.ts | 1 + 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4cd24fb0eb6..01b8a18c6d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) - `[jest-worker]` Support passing a URL as path to worker ([#13982](https://github.com/facebook/jest/pull/13982)) -- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#13981](https://github.com/facebook/jest/pull/13981)) +- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync(steps)` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#13981](https://github.com/facebook/jest/pull/13981)) ### Fixes diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index c45f239ae0ce..a3b40b66a644 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -923,9 +923,7 @@ This is often useful for synchronously executing setTimeouts during a test in or ### `jest.runAllTimersAsync()` -Runs all pending timers until there are none remaining. - -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +Asynchronous equivalent of `jest.runAllTimers()`. :::info @@ -951,9 +949,7 @@ When this API is called, all timers are advanced by `msToRun` milliseconds. All ### `jest.advanceTimersByTimeAsync(msToRun)` -Advance the clock, firing callbacks if necessary. - -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +Asynchronous equivalent of `jest.advanceTimersByTime(msToRun)`. :::info @@ -969,9 +965,7 @@ This is useful for scenarios such as one where the module being tested schedules ### `jest.runOnlyPendingTimersAsync()` -Takes note of the last scheduled timer when it is run, and advances the clock to that time firing callbacks as necessary. - -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +Asynchronous equivalent of `jest.runOnlyPendingTimers()`. :::info @@ -985,11 +979,9 @@ Advances all timers by the needed milliseconds so that only the next timeouts/in Optionally, you can provide `steps`, so it will run `steps` amount of next timeouts/intervals. -### `jest.advanceTimersToNextTimerAsync()` - -Advances the clock to the the moment of the first scheduled timer. +### `jest.advanceTimersToNextTimerAsync(steps)` -Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. +Asynchronous equivalent of `jest.advanceTimersToNextTimer(steps)`. :::info diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 0bc97f30d467..b3159c1b165f 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -63,7 +63,8 @@ export interface Jest { /** * Advances all timers by `msToRun` milliseconds, firing callbacks if necessary. * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * Also breaks the event loop, allowing any scheduled promise callbacks + * to execute _before_ running the timers. * * @remarks * Not available when using legacy fake timers implementation. @@ -77,13 +78,16 @@ export interface Jest { advanceTimersToNextTimer(steps?: number): void; /** * Advances the clock to the the moment of the first scheduled timer, firing it. + * Optionally, you can provide steps, so it will run steps amount of + * next timeouts/intervals. * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * Also breaks the event loop, allowing any scheduled promise callbacks + * to execute _before_ running the timers. * * @remarks * Not available when using legacy fake timers implementation. */ - advanceTimersToNextTimerAsync(): Promise; + advanceTimersToNextTimerAsync(steps?: number): Promise; /** * Disables automatic mocking in the module loader. */ @@ -320,7 +324,8 @@ export interface Jest { * Exhausts the macro-task queue (i.e., all tasks queued by `setTimeout()` * and `setInterval()`). * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * Also breaks the event loop, allowing any scheduled promise callbacks + * to execute _before_ running the timers. * * @remarks * If new timers are added while it is executing they will be run as well. @@ -341,7 +346,8 @@ export interface Jest { * point). If any of the currently pending macro-tasks schedule new * macro-tasks, those new tasks will not be executed by this call. * - * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers. + * Also breaks the event loop, allowing any scheduled promise callbacks + * to execute _before_ running the timers. * * @remarks * Not available when using legacy fake timers implementation. diff --git a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts index 6dfe19001b19..4ce6749bfab5 100644 --- a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts +++ b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts @@ -986,6 +986,30 @@ describe('FakeTimers', () => { expect(timers.now()).toBe(200); expect(spy).toHaveBeenCalled(); }); + + it('should advance the clock at the moment of the n-th scheduled timer', async () => { + const global = { + Date, + Promise, + clearTimeout, + process, + setTimeout, + } as unknown as typeof globalThis; + const timers = new FakeTimers({config: makeProjectConfig(), global}); + timers.useFakeTimers(); + timers.setSystemTime(0); + + const spy = jest.fn(); + global.setTimeout(async () => { + await Promise.resolve(); + global.setTimeout(spy, 100); + }, 100); + + await timers.advanceTimersToNextTimerAsync(2); + + expect(timers.now()).toBe(200); + expect(spy).toHaveBeenCalled(); + }); }); describe('runAllTimersAsync', () => { diff --git a/packages/jest-fake-timers/src/modernFakeTimers.ts b/packages/jest-fake-timers/src/modernFakeTimers.ts index d0ec79016908..c9db7ba331c0 100644 --- a/packages/jest-fake-timers/src/modernFakeTimers.ts +++ b/packages/jest-fake-timers/src/modernFakeTimers.ts @@ -84,9 +84,17 @@ export default class FakeTimers { } } - async advanceTimersToNextTimerAsync(): Promise { + async advanceTimersToNextTimerAsync(steps = 1): Promise { if (this._checkFakeTimers()) { - await this._clock.nextAsync(); + for (let i = steps; i > 0; i--) { + await this._clock.nextAsync(); + // Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250 + await this._clock.tickAsync(0); + + if (this._clock.countTimers() === 0) { + break; + } + } } } diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index fdac8fe2d6af..d09a4318588a 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2236,6 +2236,7 @@ export default class Runtime { if ( fakeTimers === this._environment.fakeTimersModern && + // TODO: remove this check in Jest 30 typeof fakeTimers.advanceTimersByTimeAsync === 'function' ) { await fakeTimers.advanceTimersByTimeAsync(msToRun); @@ -2247,14 +2248,15 @@ export default class Runtime { }, advanceTimersToNextTimer: (steps?: number) => _getFakeTimers().advanceTimersToNextTimer(steps), - advanceTimersToNextTimerAsync: async (): Promise => { + advanceTimersToNextTimerAsync: async (steps?: number): Promise => { const fakeTimers = _getFakeTimers(); if ( fakeTimers === this._environment.fakeTimersModern && + // TODO: remove this check in Jest 30 typeof fakeTimers.advanceTimersToNextTimerAsync === 'function' ) { - await fakeTimers.advanceTimersToNextTimerAsync(); + await fakeTimers.advanceTimersToNextTimerAsync(steps); } else { throw new TypeError( '`jest.advanceTimersToNextTimerAsync()` is not available when using legacy fake timers.', @@ -2328,6 +2330,7 @@ export default class Runtime { if ( fakeTimers === this._environment.fakeTimersModern && + // TODO: remove this check in Jest 30 typeof fakeTimers.runAllTimersAsync === 'function' ) { await fakeTimers.runAllTimersAsync(); @@ -2343,6 +2346,7 @@ export default class Runtime { if ( fakeTimers === this._environment.fakeTimersModern && + // TODO: remove this check in Jest 30 typeof fakeTimers.runOnlyPendingTimersAsync === 'function' ) { await fakeTimers.runOnlyPendingTimersAsync(); diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 4e7c4143602f..8415a88db114 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -496,6 +496,7 @@ expectType(jest.advanceTimersToNextTimer(2)); expectError(jest.advanceTimersToNextTimer('2')); expectType>(jest.advanceTimersToNextTimerAsync()); +expectType>(jest.advanceTimersToNextTimerAsync(2)); expectError(jest.advanceTimersToNextTimerAsync('2')); expectType(jest.clearAllTimers()); From c4c5d466593624c4bf1731b73ed1b6dd3856170f Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 11:59:33 +0100 Subject: [PATCH 08/12] updated documentation --- packages/jest-environment/src/index.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index b3159c1b165f..191fe705dfe7 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -63,9 +63,6 @@ export interface Jest { /** * Advances all timers by `msToRun` milliseconds, firing callbacks if necessary. * - * Also breaks the event loop, allowing any scheduled promise callbacks - * to execute _before_ running the timers. - * * @remarks * Not available when using legacy fake timers implementation. */ @@ -81,9 +78,6 @@ export interface Jest { * Optionally, you can provide steps, so it will run steps amount of * next timeouts/intervals. * - * Also breaks the event loop, allowing any scheduled promise callbacks - * to execute _before_ running the timers. - * * @remarks * Not available when using legacy fake timers implementation. */ @@ -324,9 +318,6 @@ export interface Jest { * Exhausts the macro-task queue (i.e., all tasks queued by `setTimeout()` * and `setInterval()`). * - * Also breaks the event loop, allowing any scheduled promise callbacks - * to execute _before_ running the timers. - * * @remarks * If new timers are added while it is executing they will be run as well. * @remarks @@ -346,9 +337,6 @@ export interface Jest { * point). If any of the currently pending macro-tasks schedule new * macro-tasks, those new tasks will not be executed by this call. * - * Also breaks the event loop, allowing any scheduled promise callbacks - * to execute _before_ running the timers. - * * @remarks * Not available when using legacy fake timers implementation. */ From 398bc6bfcb832d72110265611623f0517e4ed5ec Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 12:43:29 +0100 Subject: [PATCH 09/12] fixed documentation --- docs/JestObjectAPI.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index a3b40b66a644..0b59e124b438 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -923,7 +923,7 @@ This is often useful for synchronously executing setTimeouts during a test in or ### `jest.runAllTimersAsync()` -Asynchronous equivalent of `jest.runAllTimers()`. +Asynchronous equivalent of `jest.runAllTimers()`. It allows any scheduled promise callbacks to execute _before_ running the timers. :::info @@ -949,7 +949,7 @@ When this API is called, all timers are advanced by `msToRun` milliseconds. All ### `jest.advanceTimersByTimeAsync(msToRun)` -Asynchronous equivalent of `jest.advanceTimersByTime(msToRun)`. +Asynchronous equivalent of `jest.advanceTimersByTime(msToRun)`. It allows any scheduled promise callbacks to execute _before_ running the timers. :::info @@ -965,7 +965,7 @@ This is useful for scenarios such as one where the module being tested schedules ### `jest.runOnlyPendingTimersAsync()` -Asynchronous equivalent of `jest.runOnlyPendingTimers()`. +Asynchronous equivalent of `jest.runOnlyPendingTimers()`. It allows any scheduled promise callbacks to execute _before_ running the timers. :::info @@ -981,7 +981,7 @@ Optionally, you can provide `steps`, so it will run `steps` amount of next timeo ### `jest.advanceTimersToNextTimerAsync(steps)` -Asynchronous equivalent of `jest.advanceTimersToNextTimer(steps)`. +Asynchronous equivalent of `jest.advanceTimersToNextTimer(steps)`. It allows any scheduled promise callbacks to execute _before_ running the timers. :::info From ab3e865a5f77d8ba8186e701f3cd231ba4d7ff17 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 6 Mar 2023 14:09:19 +0100 Subject: [PATCH 10/12] pr feedback --- CHANGELOG.md | 2 +- packages/jest-runtime/src/index.ts | 40 ++++++++++++++++++------------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01b8a18c6d7f..ae207ec6863d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,11 @@ - `[jest-message-util]` Add support for [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) ([#13946](https://github.com/facebook/jest/pull/13946) & [#13947](https://github.com/facebook/jest/pull/13947)) - `[jest-message-util]` Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in `test` and `it` ([#13935](https://github.com/facebook/jest/pull/13935) & [#13966](https://github.com/facebook/jest/pull/13966)) - `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#13895](https://github.com/facebook/jest/pull/13895)) +- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync(steps)` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#13981](https://github.com/facebook/jest/pull/13981)) - `[jest-runtime, @jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#13974](https://github.com/facebook/jest/pull/13974)) - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) - `[jest-worker]` Support passing a URL as path to worker ([#13982](https://github.com/facebook/jest/pull/13982)) -- `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync(steps)` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#13981](https://github.com/facebook/jest/pull/13981)) ### Fixes diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index d09a4318588a..3a17ab1ea75d 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2234,11 +2234,13 @@ export default class Runtime { advanceTimersByTimeAsync: async (msToRun: number): Promise => { const fakeTimers = _getFakeTimers(); - if ( - fakeTimers === this._environment.fakeTimersModern && + if (fakeTimers === this._environment.fakeTimersModern) { // TODO: remove this check in Jest 30 - typeof fakeTimers.advanceTimersByTimeAsync === 'function' - ) { + if (typeof fakeTimers.advanceTimersByTimeAsync !== 'function') { + throw new TypeError( + 'Your test environment does not support async fake timers - please ensure its Jest dependencies are updated to version 29.5 or later', + ); + } await fakeTimers.advanceTimersByTimeAsync(msToRun); } else { throw new TypeError( @@ -2251,11 +2253,13 @@ export default class Runtime { advanceTimersToNextTimerAsync: async (steps?: number): Promise => { const fakeTimers = _getFakeTimers(); - if ( - fakeTimers === this._environment.fakeTimersModern && + if (fakeTimers === this._environment.fakeTimersModern) { // TODO: remove this check in Jest 30 - typeof fakeTimers.advanceTimersToNextTimerAsync === 'function' - ) { + if (typeof fakeTimers.advanceTimersToNextTimerAsync !== 'function') { + throw new TypeError( + 'Your test environment does not support async fake timers - please ensure its Jest dependencies are updated to version 29.5 or later', + ); + } await fakeTimers.advanceTimersToNextTimerAsync(steps); } else { throw new TypeError( @@ -2328,11 +2332,13 @@ export default class Runtime { runAllTimersAsync: async (): Promise => { const fakeTimers = _getFakeTimers(); - if ( - fakeTimers === this._environment.fakeTimersModern && + if (fakeTimers === this._environment.fakeTimersModern) { // TODO: remove this check in Jest 30 - typeof fakeTimers.runAllTimersAsync === 'function' - ) { + if (typeof fakeTimers.runAllTimersAsync !== 'function') { + throw new TypeError( + 'Your test environment does not support async fake timers - please ensure its Jest dependencies are updated to version 29.5 or later', + ); + } await fakeTimers.runAllTimersAsync(); } else { throw new TypeError( @@ -2344,11 +2350,13 @@ export default class Runtime { runOnlyPendingTimersAsync: async (): Promise => { const fakeTimers = _getFakeTimers(); - if ( - fakeTimers === this._environment.fakeTimersModern && + if (fakeTimers === this._environment.fakeTimersModern) { // TODO: remove this check in Jest 30 - typeof fakeTimers.runOnlyPendingTimersAsync === 'function' - ) { + if (typeof fakeTimers.runOnlyPendingTimersAsync !== 'function') { + throw new TypeError( + 'Your test environment does not support async fake timers - please ensure its Jest dependencies are updated to version 29.5 or later', + ); + } await fakeTimers.runOnlyPendingTimersAsync(); } else { throw new TypeError( From 0f6b938e814d6528fb8ae89daa9cf1b4d8864dcd Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 6 Mar 2023 14:11:35 +0100 Subject: [PATCH 11/12] consistent style --- packages/jest-environment/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index 191fe705dfe7..6a99b3c7fe39 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -323,7 +323,7 @@ export interface Jest { * @remarks * Not available when using legacy fake timers implementation. */ - runAllTimersAsync: () => Promise; + runAllTimersAsync(): Promise; /** * Executes only the macro-tasks that are currently pending (i.e., only the * tasks that have been queued by `setTimeout()` or `setInterval()` up to this @@ -340,7 +340,7 @@ export interface Jest { * @remarks * Not available when using legacy fake timers implementation. */ - runOnlyPendingTimersAsync: () => Promise; + runOnlyPendingTimersAsync(): Promise; /** * Explicitly supplies the mock object that the module system should return * for the specified module. From 16ca0f522a356e09e54795281e53fa3487cd8afb Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 6 Mar 2023 14:14:34 +0100 Subject: [PATCH 12/12] remove unneeded explicit type annotations --- packages/jest-runtime/src/index.ts | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 3a17ab1ea75d..5fa5186fd20b 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2215,7 +2215,7 @@ export default class Runtime { ); }; - const setTimeout = (timeout: number) => { + const setTimeout: Jest['setTimeout'] = timeout => { this._environment.global[testTimeoutSymbol] = timeout; return jestObject; }; @@ -2229,9 +2229,9 @@ export default class Runtime { }; const jestObject: Jest = { - advanceTimersByTime: (msToRun: number) => + advanceTimersByTime: msToRun => _getFakeTimers().advanceTimersByTime(msToRun), - advanceTimersByTimeAsync: async (msToRun: number): Promise => { + advanceTimersByTimeAsync: async msToRun => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) { @@ -2248,9 +2248,9 @@ export default class Runtime { ); } }, - advanceTimersToNextTimer: (steps?: number) => + advanceTimersToNextTimer: steps => _getFakeTimers().advanceTimersToNextTimer(steps), - advanceTimersToNextTimerAsync: async (steps?: number): Promise => { + advanceTimersToNextTimerAsync: async steps => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) { @@ -2271,16 +2271,14 @@ export default class Runtime { autoMockOn: enableAutomock, clearAllMocks, clearAllTimers: () => _getFakeTimers().clearAllTimers(), - createMockFromModule: (moduleName: string) => - this._generateMock(from, moduleName), + createMockFromModule: moduleName => this._generateMock(from, moduleName), deepUnmock, disableAutomock, doMock: mock, dontMock: unmock, enableAutomock, fn, - genMockFromModule: (moduleName: string) => - this._generateMock(from, moduleName), + genMockFromModule: moduleName => this._generateMock(from, moduleName), getRealSystemTime: () => { const fakeTimers = _getFakeTimers(); @@ -2329,7 +2327,7 @@ export default class Runtime { }, runAllTicks: () => _getFakeTimers().runAllTicks(), runAllTimers: () => _getFakeTimers().runAllTimers(), - runAllTimersAsync: async (): Promise => { + runAllTimersAsync: async () => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) { @@ -2347,7 +2345,7 @@ export default class Runtime { } }, runOnlyPendingTimers: () => _getFakeTimers().runOnlyPendingTimers(), - runOnlyPendingTimersAsync: async (): Promise => { + runOnlyPendingTimersAsync: async () => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) { @@ -2364,9 +2362,8 @@ export default class Runtime { ); } }, - setMock: (moduleName: string, mock: unknown) => - setMockFactory(moduleName, () => mock), - setSystemTime: (now?: number | Date) => { + setMock: (moduleName, mock) => setMockFactory(moduleName, () => mock), + setSystemTime: now => { const fakeTimers = _getFakeTimers(); if (fakeTimers === this._environment.fakeTimersModern) {