forked from react/react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTimerMock.js
More file actions
90 lines (82 loc) · 2.47 KB
/
Copy pathTimerMock.js
File metadata and controls
90 lines (82 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import {runWorkLoop} from './index';
import NativeFantom from 'react-native/src/private/testing/fantom/specs/NativeFantom';
/**
* Controls the deterministic timer mock for `setTimeout`/`setInterval`.
*/
export interface TimerMock {
// Advances the virtual clock by `deltaMs`, firing every timer that becomes
// due (in order), then runs the work loop so the callbacks execute.
advanceTimersByTime(deltaMs: number): void;
// Fires all pending timers (bounded to avoid infinite loops), then runs the
// work loop so the callbacks execute.
runAllTimers(): void;
// Returns the number of currently pending (scheduled but not yet fired)
// timers.
getPendingTimerCount(): number;
uninstall(): void;
}
let activeMock: ?TimerMock;
/**
* Installs a deterministic timer mock. While installed, `setTimeout` and
* `setInterval` callbacks do not fire on their own; they only fire when the
* virtual clock is advanced via `advanceTimersByTime` or drained via
* `runAllTimers`. This is the timer equivalent of `installHighResTimeStampMock`.
*
* @example
* ```
* let timers;
*
* afterEach(() => {
* timers?.uninstall();
* timers = null;
* });
*
* it('fires after the delay elapses', () => {
* timers = Fantom.installTimerMock();
* const callback = jest.fn();
*
* setTimeout(callback, 100);
* timers.advanceTimersByTime(50);
* expect(callback).toHaveBeenCalledTimes(0);
*
* timers.advanceTimersByTime(50);
* expect(callback).toHaveBeenCalledTimes(1);
* });
* ```
*/
export function installTimerMock(): TimerMock {
if (activeMock != null) {
throw new Error(
'Cannot install timer mock because there is another mock installed already. Reuse the same mock or uninstall the previous one first.',
);
}
NativeFantom.setTimerMockEnabled(true);
const mock: TimerMock = {
advanceTimersByTime: deltaMs => {
NativeFantom.advanceTimers(deltaMs);
runWorkLoop();
},
runAllTimers: () => {
NativeFantom.runAllTimers();
runWorkLoop();
},
getPendingTimerCount: () => NativeFantom.getPendingTimerCount(),
uninstall: () => {
if (activeMock === mock) {
NativeFantom.setTimerMockEnabled(false);
activeMock = null;
}
},
};
activeMock = mock;
return mock;
}