UNPKG

11 kBTypeScriptView Raw
1/**
2 * Names of clock methods that may be faked by install.
3 */
4type FakeMethod =
5 | "setTimeout"
6 | "clearTimeout"
7 | "setImmediate"
8 | "clearImmediate"
9 | "setInterval"
10 | "clearInterval"
11 | "Date"
12 | "nextTick"
13 | "hrtime"
14 | "requestAnimationFrame"
15 | "cancelAnimationFrame"
16 | "requestIdleCallback"
17 | "cancelIdleCallback";
18
19/**
20 * Global methods avaliable to every clock and also as standalone methods (inside `timers` global object).
21 */
22export interface GlobalTimers<TTimerId extends TimerId> {
23 /**
24 * Schedules a callback to be fired once timeout milliseconds have ticked by.
25 *
26 * @param callback Callback to be fired.
27 * @param timeout How many ticks to wait to run the callback.
28 * @param args Any extra arguments to pass to the callback.
29 * @returns Time identifier for cancellation.
30 */
31 setTimeout: (callback: () => void, timeout: number, ...args: any[]) => TTimerId;
32
33 /**
34 * Clears a timer, as long as it was created using setTimeout.
35 *
36 * @param id Timer ID or object.
37 */
38 clearTimeout: (id: TimerId) => void;
39
40 /**
41 * Schedules a callback to be fired every time timeout milliseconds have ticked by.
42 *
43 * @param callback Callback to be fired.
44 * @param timeout How many ticks to wait between callbacks.
45 * @param args Any extra arguments to pass to the callback.
46 * @returns Time identifier for cancellation.
47 */
48 setInterval: (callback: () => void, timeout: number, ...args: any[]) => TTimerId;
49
50 /**
51 * Clears a timer, as long as it was created using setInterval.
52 *
53 * @param id Timer ID or object.
54 */
55 clearInterval: (id: TTimerId) => void;
56
57 /**
58 * Schedules the callback to be fired once 0 milliseconds have ticked by.
59 *
60 * @param callback Callback to be fired.
61 * @remarks You'll still have to call clock.tick() for the callback to fire.
62 * @remarks If called during a tick the callback won't fire until 1 millisecond has ticked by.
63 */
64 setImmediate: (callback: () => void) => TTimerId;
65
66 /**
67 * Clears a timer, as long as it was created using setImmediate.
68 *
69 * @param id Timer ID or object.
70 */
71 clearImmediate: (id: TTimerId) => void;
72
73 /**
74 * Implements the Date object but using this clock to provide the correct time.
75 */
76 Date: typeof Date;
77}
78
79/**
80 * Timer object used in node.
81 */
82export interface NodeTimer {
83 /**
84 * Stub method call. Does nothing.
85 */
86 ref(): void;
87
88 /**
89 * Stub method call. Does nothing.
90 */
91 unref(): void;
92}
93
94/**
95 * Timer identifier for clock scheduling.
96 */
97export type TimerId = number | NodeTimer;
98
99/**
100 * Controls the flow of time.
101 */
102export interface LolexClock<TTimerId extends TimerId> extends GlobalTimers<TTimerId> {
103 /**
104 * Current clock time.
105 */
106 now: number;
107
108 /**
109 * Don't know what this prop is for, but it was included in the clocks that `createClock` or
110 * `install` return (it is never used in the code, for now).
111 */
112 timeouts: {};
113
114 /**
115 * Maximum number of timers that will be run when calling runAll().
116 */
117 loopLimit: number;
118
119 /**
120 * Schedule callback to run in the next animation frame.
121 *
122 * @param callback Callback to be fired.
123 * @returns Request id.
124 */
125 requestAnimationFrame: (callback: (time: number) => void) => TTimerId;
126
127 /**
128 * Cancel animation frame request.
129 *
130 * @param id The id returned from requestAnimationFrame method.
131 */
132 cancelAnimationFrame: (id: TTimerId) => void;
133
134 /**
135 * Queues the callback to be fired during idle periods to perform background and low priority work on the main event loop.
136 *
137 * @param callback Callback to be fired.
138 * @param timeout The maximum number of ticks before the callback must be fired.
139 * @remarks Callbacks which have a timeout option will be fired no later than time in milliseconds.
140 */
141 requestIdleCallback: (callback: () => void, timeout?: number) => TTimerId;
142
143 /**
144 * Clears a timer, as long as it was created using requestIdleCallback.
145 *
146 * @param id Timer ID or object.
147 */
148 cancelIdleCallback: (id: TTimerId) => void;
149
150 /**
151 * Get the number of waiting timers.
152 *
153 * @returns number of waiting timers.
154 */
155 countTimers: () => number;
156
157 /**
158 * Advances the clock to the the moment of the first scheduled timer, firing it.
159 */
160 next: () => void;
161
162 /**
163 * Advances the clock to the the moment of the first scheduled timer, firing it.
164 *
165 * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers.
166 */
167 nextAsync: () => Promise<void>;
168
169 /**
170 * Advance the clock, firing callbacks if necessary.
171 *
172 * @param time How many ticks to advance by.
173 */
174 tick: (time: number | string) => void;
175
176 /**
177 * Advance the clock, firing callbacks if necessary.
178 *
179 * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers.
180 *
181 * @param time How many ticks to advance by.
182 */
183 tickAsync: (time: number | string) => Promise<void>;
184
185 /**
186 * Removes all timers and tick without firing them and restore now to its original value.
187 */
188 reset: () => void;
189
190 /**
191 * Runs all pending timers until there are none remaining.
192 *
193 * @remarks If new timers are added while it is executing they will be run as well.
194 */
195 runAll: () => void;
196
197 /**
198 * Runs all pending timers until there are none remaining.
199 *
200 * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers.
201 *
202 * @remarks If new timers are added while it is executing they will be run as well.
203 */
204 runAllAsync: () => Promise<void>;
205
206 /**
207 * Advanced the clock to the next animation frame while firing all scheduled callbacks.
208 */
209 runToFrame: () => void;
210
211 /**
212 * Takes note of the last scheduled timer when it is run, and advances the clock to
213 * that time firing callbacks as necessary.
214 */
215 runToLast: () => void;
216
217 /**
218 * Takes note of the last scheduled timer when it is run, and advances the clock to
219 * that time firing callbacks as necessary.
220 *
221 * Also breaks the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers.
222 */
223 runToLastAsync: () => Promise<void>;
224
225 /**
226 * Simulates a user changing the system clock.
227 *
228 * @param now New system time.
229 * @remarks This affects the current time but it does not in itself cause timers to fire.
230 */
231 setSystemTime: (now?: number | Date) => void;
232}
233
234/**
235 * Lolex clock for a browser environment.
236 */
237type BrowserClock = LolexClock<number> & {
238 /**
239 * Mimics performance.now().
240 */
241 performance: {
242 now: () => number;
243 };
244};
245
246/**
247 * Lolex clock for a Node environment.
248 */
249type NodeClock = LolexClock<NodeTimer> & {
250 /**
251 * Mimicks process.hrtime().
252 *
253 * @param prevTime Previous system time to calculate time elapsed.
254 * @returns High resolution real time as [seconds, nanoseconds].
255 */
256 hrtime(prevTime?: [number, number]): [number, number];
257
258 /**
259 * Mimics process.nextTick() explicitly dropping additional arguments.
260 */
261 queueMicrotask: (callback: () => void) => void;
262
263 /**
264 * Simulates process.nextTick().
265 */
266 nextTick: (callback: () => void) => void;
267
268 /**
269 * Run all pending microtasks scheduled with nextTick.
270 */
271 runMicrotasks: () => void;
272};
273
274/**
275 * Clock object created by lolex.
276 */
277type Clock = BrowserClock | NodeClock;
278
279/**
280 * Additional methods that installed clock have.
281 */
282type InstalledMethods = {
283 /**
284 * Restores the original methods on the context that was passed to lolex.install,
285 * or the native timers if no context was given.
286 */
287 uninstall: () => void;
288
289 methods: FakeMethod[];
290};
291
292/**
293 * Clock object created by calling `install();`.
294 *
295 * @typeparam {TClock} type of base clock (e.g BrowserClock).
296 */
297type InstalledClock<TClock extends Clock = Clock> = TClock & InstalledMethods;
298
299/**
300 * Creates a clock.
301 *
302 * @param now Current time for the clock.
303 * @param loopLimit Maximum number of timers that will be run when calling runAll()
304 * before assuming that we have an infinite loop and throwing an error
305 * (by default, 1000).
306 * @typeparam {TClock} Type of clock to create.
307 * @remarks The default epoch is 0.
308 */
309export declare function createClock<TClock extends Clock = Clock>(now?: number | Date, loopLimit?: number): TClock;
310
311export interface LolexInstallOpts {
312 /**
313 * Installs lolex onto the specified target context (default: global)
314 */
315 target?: any;
316
317 /**
318 * Installs lolex with the specified unix epoch (default: 0)
319 */
320 now?: number | Date | undefined;
321
322 /**
323 * An array with explicit function names to hijack. When not set, lolex will automatically fake all methods except nextTick
324 * e.g., lolex.install({ toFake: ["setTimeout", "nextTick"]}) will fake only setTimeout and nextTick
325 */
326 toFake?: FakeMethod[] | undefined;
327
328 /**
329 * The maximum number of timers that will be run when calling runAll() (default: 1000)
330 */
331 loopLimit?: number | undefined;
332
333 /**
334 * Tells lolex to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by
335 * 20ms for every 20ms change in the real system time) (default: false)
336 */
337 shouldAdvanceTime?: boolean | undefined;
338
339 /**
340 * Relevant only when using with shouldAdvanceTime: true. increment mocked time by advanceTimeDelta ms every advanceTimeDelta ms change
341 * in the real system time (default: 20)
342 */
343 advanceTimeDelta?: number | undefined;
344}
345
346/**
347 * Creates a clock and installs it globally.
348 *
349 * @param now Current time for the clock, as with lolex.createClock().
350 * @param toFake Names of methods that should be faked.
351 * @typeparam {TClock} Type of clock to create.
352 */
353export declare function install<TClock extends Clock = Clock>(opts?: LolexInstallOpts): InstalledClock<TClock>;
354
355export interface LolexWithContext {
356 timers: GlobalTimers<TimerId>;
357 createClock: <TClock extends Clock = Clock>(now?: number | Date, loopLimit?: number) => TClock;
358 install: <TClock extends Clock = Clock>(opts?: LolexInstallOpts) => InstalledClock<TClock>;
359 withGlobal: (global: Object) => LolexWithContext;
360}
361
362/**
363 * Apply new context to lolex.
364 *
365 * @param global New context to apply like `window` (in browsers) or `global` (in node).
366 */
367export declare function withGlobal(global: Object): LolexWithContext;
368
369export declare const timers: GlobalTimers<TimerId>;