Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options object with ignore property to modern useFakeTimers function #11661

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,6 +1,7 @@
## master

### Features
- `[@jest/fake-timers]` Add options object with ignore property to modern useFakeTimers function. ([#11661](https://github.com/facebook/jest/pull/11661))

### Fixes

Expand Down
24 changes: 24 additions & 0 deletions packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts
Expand Up @@ -798,6 +798,30 @@ describe('FakeTimers', () => {
expect(global.setImmediate).not.toBe(nativeSetImmediate);
expect(global.clearImmediate).not.toBe(nativeClearImmediate);
});

it('ignores timer functions from the ignore option', () => {
const nativeSetTimeout = jest.fn();
const nativeClearTimeout = jest.fn();
const nativeNextTick = jest.fn();
process.nextTick = nativeNextTick;
const global = {
Date,
clearTimeout: nativeClearTimeout,
process,
setTimeout: nativeSetTimeout,
};

const timers = new FakeTimers({global});
timers.useFakeTimers({
ignore: ['nextTick', 'clearTimeout'],
});

// Ignored functions don't get mocked
expect(global.process.nextTick).toBe(nativeNextTick);
expect(global.clearTimeout).toBe(nativeClearTimeout);
// check if other functions are still being mocked
expect(global.setTimeout).not.toBe(nativeSetTimeout);
});
});

describe('getTimerCount', () => {
Expand Down
14 changes: 10 additions & 4 deletions packages/jest-fake-timers/src/modernFakeTimers.ts
Expand Up @@ -12,6 +12,10 @@ import {
} from '@sinonjs/fake-timers';
import {StackTraceConfig, formatStackTrace} from 'jest-message-util';

interface ModernFakeTimersOptions {
ignore?: Array<string>;
}

export default class FakeTimers {
private _clock!: InstalledClock;
private _config: StackTraceConfig;
Expand Down Expand Up @@ -93,11 +97,13 @@ export default class FakeTimers {
}
}

useFakeTimers(): void {
useFakeTimers(options: ModernFakeTimersOptions = {}): void {
if (!this._fakingTime) {
const toFake = Object.keys(this._fakeTimers.timers) as Array<
keyof FakeTimerWithContext['timers']
>;
const toFake = Object.keys(this._fakeTimers.timers).filter(
// This is a simple attempt to fix the issue when using fakeTimers in combination with promises
// Developers can now add the nextTick function to the list timers not to mock
Comment on lines +103 to +104
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// This is a simple attempt to fix the issue when using fakeTimers in combination with promises
// Developers can now add the nextTick function to the list timers not to mock

this text is for a PR description, not the code 🙂

timerFunc => !(options?.ignore || []).includes(timerFunc),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is sorta hard to read, what about

diff --git i/packages/jest-fake-timers/src/modernFakeTimers.ts w/packages/jest-fake-timers/src/modernFakeTimers.ts
index 59c4c49321..049982792b 100644
--- i/packages/jest-fake-timers/src/modernFakeTimers.ts
+++ w/packages/jest-fake-timers/src/modernFakeTimers.ts
@@ -12,6 +12,12 @@ import {
 } from '@sinonjs/fake-timers';
 import {StackTraceConfig, formatStackTrace} from 'jest-message-util';
 
+type ValidTimers = keyof FakeTimerWithContext['timers'];
+
+interface ModernFakeTimersOptions {
+  ignore?: Array<ValidTimers>;
+}
+
 export default class FakeTimers {
   private _clock!: InstalledClock;
   private _config: StackTraceConfig;
@@ -93,16 +99,20 @@ export default class FakeTimers {
     }
   }
 
-  useFakeTimers(): void {
+  useFakeTimers(options?: ModernFakeTimersOptions): void {
     if (!this._fakingTime) {
-      const toFake = Object.keys(this._fakeTimers.timers) as Array<
-        keyof FakeTimerWithContext['timers']
-      >;
+      const toFake = new Set(
+        Object.keys(this._fakeTimers.timers) as Array<ValidTimers>,
+      );
+
+      options?.ignore?.forEach(timer => {
+        toFake.delete(timer);
+      });
 
       this._clock = this._fakeTimers.install({
         loopLimit: this._maxLoops,
         now: Date.now(),
-        toFake,
+        toFake: Array.from(toFake),
       });
 
       this._fakingTime = true;

) as Array<keyof FakeTimerWithContext['timers']>;

this._clock = this._fakeTimers.install({
loopLimit: this._maxLoops,
Expand Down