Skip to content

Commit eeadc85

Browse files
committed
fix: modern jest timers
1 parent 362d372 commit eeadc85

File tree

4 files changed

+74
-5
lines changed

4 files changed

+74
-5
lines changed

src/__tests__/auto-cleanup.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,22 @@ class Test extends React.Component<*> {
2525
test('component is mounted, but not umounted before test ends', () => {
2626
const fn = jest.fn();
2727
render(<Test onUnmount={fn} />);
28+
expect(isMounted).toEqual(true);
2829
expect(fn).not.toHaveBeenCalled();
2930
});
3031

3132
test('component is automatically umounted after first test ends', () => {
3233
expect(isMounted).toEqual(false);
3334
});
35+
36+
test('does not time out with fake timers', () => {
37+
jest.useFakeTimers();
38+
render(<Test />);
39+
expect(isMounted).toEqual(true);
40+
});
41+
42+
test('does not time out with modern fake timers', () => {
43+
jest.useFakeTimers('modern');
44+
render(<Test />);
45+
expect(isMounted).toEqual(true);
46+
});

src/__tests__/waitFor.test.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class BananaContainer extends React.Component<{}, any> {
3535
}
3636
}
3737

38+
afterEach(() => {
39+
jest.useRealTimers();
40+
});
41+
3842
test('waits for element until it stops throwing', async () => {
3943
const { getByText, queryByText } = render(<BananaContainer />);
4044

@@ -87,9 +91,24 @@ test('works with fake timers', async () => {
8791
} catch (e) {
8892
// suppress
8993
}
90-
jest.runTimersToTime(400);
94+
jest.advanceTimersByTime(400);
9195

9296
expect(mockFn).toHaveBeenCalledTimes(3);
97+
});
9398

94-
jest.useRealTimers();
99+
test('works with modern fake timers', async () => {
100+
jest.useFakeTimers('modern');
101+
102+
const mockFn = jest.fn(() => {
103+
throw Error('test');
104+
});
105+
106+
try {
107+
waitFor(() => mockFn(), { timeout: 400, interval: 200 });
108+
} catch (e) {
109+
// suppress
110+
}
111+
jest.advanceTimersByTime(400);
112+
113+
expect(mockFn).toHaveBeenCalledTimes(3);
95114
});

src/__tests__/waitForElementToBeRemoved.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ const TestSetup = ({ shouldUseDelay = true }) => {
2525
);
2626
};
2727

28+
afterEach(() => {
29+
jest.useRealTimers();
30+
});
31+
2832
test('waits when using getBy query', async () => {
2933
const screen = render(<TestSetup />);
3034

@@ -139,3 +143,17 @@ test('works with fake timers', async () => {
139143
jest.advanceTimersByTime(400);
140144
expect(mockFn).toHaveBeenCalledTimes(4);
141145
});
146+
147+
test('works with modern fake timers', async () => {
148+
jest.useFakeTimers('modern');
149+
150+
const mockFn = jest.fn(() => <View />);
151+
152+
waitForElementToBeRemoved(() => mockFn(), {
153+
timeout: 400,
154+
interval: 200,
155+
});
156+
157+
jest.advanceTimersByTime(400);
158+
expect(mockFn).toHaveBeenCalledTimes(4);
159+
});

src/flushMicroTasks.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,33 @@
22

33
import { printDeprecationWarning } from './helpers/errors';
44

5+
type SimpleThenable = { then: (() => mixed) => mixed };
6+
57
/**
68
* Wait for microtasks queue to flush
79
*/
8-
export default function flushMicrotasksQueue(): Promise<any> {
10+
export default function flushMicrotasksQueue(): SimpleThenable {
911
printDeprecationWarning('flushMicrotasksQueue');
1012
return flushMicroTasks();
1113
}
1214

13-
export function flushMicroTasks(): Promise<any> {
14-
return new Promise((resolve) => setImmediate(resolve));
15+
let enqueueTask;
16+
try {
17+
// assuming we're in node, let's try to get node's
18+
// version of setImmediate, bypassing fake timers if any.
19+
// $FlowFixMe - timers is internal Node module
20+
enqueueTask = require('timers').setImmediate;
21+
} catch (_err) {
22+
// we're in a browser, do nothing
23+
enqueueTask = (resolve) => {
24+
resolve();
25+
};
26+
}
27+
28+
export function flushMicroTasks(): SimpleThenable {
29+
return {
30+
then(resolve) {
31+
enqueueTask(resolve);
32+
},
33+
};
1534
}

0 commit comments

Comments
 (0)