1# `@sinonjs/fake-timers` [![CircleCI](https://circleci.com/gh/sinonjs/fake-timers.svg?style=svg)](https://circleci.com/gh/sinonjs/fake-timers) [![codecov](https://codecov.io/gh/sinonjs/fake-timers/branch/master/graph/badge.svg)](https://codecov.io/gh/sinonjs/fake-timers)
2
3JavaScript implementation of the timer APIs; `setTimeout`, `clearTimeout`, `setImmediate`, `clearImmediate`, `setInterval`, `clearInterval`, `requestAnimationFrame`, `cancelAnimationFrame`, `requestIdleCallback`, and `cancelIdleCallback`, along with a clock instance that controls the flow of time. FakeTimers also provides a `Date` implementation that gets its time from the clock.
4
5In addition in browser environment `@sinonjs/fake-timers` provides a `performance` implementation that gets its time from the clock. In Node environments FakeTimers provides a `nextTick` implementation that is synchronized with the clock - and a `process.hrtime` shim that works with the clock.
6
7`@sinonjs/fake-timers` can be used to simulate passing time in automated tests and other
8situations where you want the scheduling semantics, but don't want to actually
9wait.
10
11`@sinonjs/fake-timers` is extracted from [Sinon.JS](https://github.com/sinonjs/sinon.js) and targets the [same runtimes](https://sinonjs.org/releases/latest/#supported-runtimes).
12
13## Installation
14
15`@sinonjs/fake-timers` can be used in both Node and browser environments. Installation is as easy as
16
17```sh
18npm install @sinonjs/fake-timers
19```
20
21If you want to use `@sinonjs/fake-timers` in a browser you can use [the pre-built
22version](https://github.com/sinonjs/fake-timers/blob/master/fake-timers.js) available in the repo
23and the npm package. Using npm you only need to reference `./node_modules/@sinonjs/fake-timers.js` in your `<script>` tags.
24
25You are always free to [build it yourself](https://github.com/sinonjs/@sinonjs/fake-timers/blob/53ea4d9b9e5bcff53cc7c9755dc9aa340368cf1c/package.json#L22), of course.
26
27## Usage
28
29To use `@sinonjs/fake-timers`, create a new clock, schedule events on it using the timer
30functions and pass time using the `tick` method.
31
32```js
33// In the browser distribution, a global `FakeTimers` is already available
34var FakeTimers = require("@sinonjs/fake-timers");
35var clock = FakeTimers.createClock();
36
37clock.setTimeout(function () {
38    console.log("The poblano is a mild chili pepper originating in the state of Puebla, Mexico.");
39}, 15);
40
41// ...
42
43clock.tick(15);
44```
45
46Upon executing the last line, an interesting fact about the
47[Poblano](http://en.wikipedia.org/wiki/Poblano) will be printed synchronously to
48the screen. If you want to simulate asynchronous behavior, you have to use your
49imagination when calling the various functions.
50
51The `next`, `runAll`, `runToFrame`, and `runToLast` methods are available to advance the clock. See the
52API Reference for more details.
53
54### Faking the native timers
55
56When using `@sinonjs/fake-timers` to test timers, you will most likely want to replace the native
57timers such that calling `setTimeout` actually schedules a callback with your
58clock instance, not the browser's internals.
59
60Calling `install` with no arguments achieves this. You can call `uninstall`
61later to restore things as they were again.
62
63```js
64// In the browser distribution, a global `FakeTimers` is already available
65var FakeTimers = require("@sinonjs/fake-timers");
66
67var clock = FakeTimers.install();
68// Equivalent to
69// var clock = FakeTimers.install(typeof global !== "undefined" ? global : window);
70
71setTimeout(fn, 15); // Schedules with clock.setTimeout
72
73clock.uninstall();
74// setTimeout is restored to the native implementation
75```
76
77To hijack timers in another context pass it to the `install` method.
78
79```js
80var FakeTimers = require("@sinonjs/fake-timers");
81var context = {
82    setTimeout: setTimeout // By default context.setTimeout uses the global setTimeout
83}
84var clock = FakeTimers.install({target: context});
85
86context.setTimeout(fn, 15); // Schedules with clock.setTimeout
87
88clock.uninstall();
89// context.setTimeout is restored to the original implementation
90```
91
92Usually you want to install the timers onto the global object, so call `install`
93without arguments.
94
95#### Automatically incrementing mocked time
96Since version 2.0 FakeTimers supports the possibility to attach the faked timers
97to any change in the real system time. This basically means you no longer need
98to `tick()` the clock in a situation where you won't know **when** to call `tick()`.
99
100Please note that this is achieved using the original setImmediate() API at a certain
101configurable interval `config.advanceTimeDelta` (default: 20ms). Meaning time would
102be incremented every 20ms, not in real time.
103
104An example would be:
105
106```js
107var FakeTimers = require("@sinonjs/fake-timers");
108var clock = FakeTimers.install({shouldAdvanceTime: true, advanceTimeDelta: 40});
109
110setTimeout(() => {
111    console.log('this just timed out'); //executed after 40ms
112}, 30);
113
114setImmediate(() => {
115    console.log('not so immediate'); //executed after 40ms
116});
117
118setTimeout(() => {
119    console.log('this timed out after'); //executed after 80ms
120    clock.uninstall();
121}, 50);
122```
123
124## API Reference
125
126### `var clock = FakeTimers.createClock([now[, loopLimit]])`
127
128Creates a clock. The default
129[epoch](https://en.wikipedia.org/wiki/Epoch_%28reference_date%29) is `0`.
130
131The `now` argument may be a number (in milliseconds) or a Date object.
132
133The `loopLimit` argument sets the maximum number of timers that will be run when calling `runAll()` before assuming that we have an infinite loop and throwing an error. The default is `1000`.
134
135### `var clock = FakeTimers.install([config])`
136Installs FakeTimers using the specified config (otherwise with epoch `0` on the global scope). The following configuration options are available
137
138Parameter | Type | Default | Description
139--------- | ---- | ------- | ------------
140`config.target`| Object | global | installs FakeTimers onto the specified target context
141`config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch
142`config.toFake` | String[] | ["setTimeout", "clearTimeout", "setImmediate", "clearImmediate","setInterval", "clearInterval", "Date", "requestAnimationFrame", "cancelAnimationFrame", "requestIdleCallback", "cancelIdleCallback", "hrtime"] | an array with explicit function names to hijack. *When not set, FakeTimers will automatically fake all methods **except** `nextTick`* e.g., `FakeTimers.install({ toFake: ["setTimeout","nextTick"]})` will fake only `setTimeout` and `nextTick`
143`config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll()
144`config.shouldAdvanceTime` | Boolean | false | tells FakeTimers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time)
145`config.advanceTimeDelta` | Number | 20 | relevant only when using with `shouldAdvanceTime: true`. increment mocked time by `advanceTimeDelta` ms every `advanceTimeDelta` ms change in the real system time.
146
147### `var id = clock.setTimeout(callback, timeout)`
148
149Schedules the callback to be fired once `timeout` milliseconds have ticked by.
150
151In Node.js `setTimeout` returns a timer object. FakeTimers will do the same, however
152its `ref()` and `unref()` methods have no effect.
153
154In browsers a timer ID is returned.
155
156### `clock.clearTimeout(id)`
157
158Clears the timer given the ID or timer object, as long as it was created using
159`setTimeout`.
160
161### `var id = clock.setInterval(callback, timeout)`
162
163Schedules the callback to be fired every time `timeout` milliseconds have ticked
164by.
165
166In Node.js `setInterval` returns a timer object. FakeTimers will do the same, however
167its `ref()` and `unref()` methods have no effect.
168
169In browsers a timer ID is returned.
170
171### `clock.clearInterval(id)`
172
173Clears the timer given the ID or timer object, as long as it was created using
174`setInterval`.
175
176### `var id = clock.setImmediate(callback)`
177
178Schedules the callback to be fired once `0` milliseconds have ticked by. Note
179that you'll still have to call `clock.tick()` for the callback to fire. If
180called during a tick the callback won't fire until `1` millisecond has ticked
181by.
182
183In Node.js `setImmediate` returns a timer object. FakeTimers will do the same,
184however its `ref()` and `unref()` methods have no effect.
185
186In browsers a timer ID is returned.
187
188### `clock.clearImmediate(id)`
189
190Clears the timer given the ID or timer object, as long as it was created using
191`setImmediate`.
192
193### `clock.requestAnimationFrame(callback)`
194
195Schedules the callback to be fired on the next animation frame, which runs every
19616 ticks. Returns an `id` which can be used to cancel the callback. This is
197available in both browser & node environments.
198
199### `clock.cancelAnimationFrame(id)`
200
201Cancels the callback scheduled by the provided id.
202
203### `clock.requestIdleCallback(callback[, timeout])`
204
205Queued the callback to be fired during idle periods to perform background and low priority work on the main event loop. Callbacks which have a timeout option will be fired no later than time in milliseconds. Returns an `id` which can be used to cancel the callback.
206
207### `clock.cancelIdleCallback(id)`
208
209Cancels the callback scheduled by the provided id.
210
211### `clock.countTimers()`
212
213Returns the number of waiting timers. This can be used to assert that a test
214finishes without leaking any timers.
215
216### `clock.hrtime(prevTime?)`
217Only available in Node.js, mimicks process.hrtime().
218
219### `clock.nextTick(callback)`
220
221Only available in Node.js, mimics `process.nextTick` to enable completely synchronous testing flows.
222
223### `clock.performance.now()`
224Only available in browser environments, mimicks performance.now().
225
226
227### `clock.tick(time)` / `await clock.tickAsync(time)`
228
229Advance the clock, firing callbacks if necessary. `time` may be the number of
230milliseconds to advance the clock by or a human-readable string. Valid string
231formats are `"08"` for eight seconds, `"01:00"` for one minute and `"02:34:10"`
232for two hours, 34 minutes and ten seconds.
233
234The `tickAsync()` will also break the event loop, allowing any scheduled promise
235callbacks to execute _before_ running the timers.
236
237### `clock.next()` / `await clock.nextAsync()`
238
239Advances the clock to the the moment of the first scheduled timer, firing it.
240
241The `nextAsync()` will also break the event loop, allowing any scheduled promise
242callbacks to execute _before_ running the timers.
243
244### `clock.reset()`
245
246Removes all timers and ticks without firing them, and sets `now` to `config.now`
247that was provided to `FakeTimers.install` or to `0` if `config.now` was not provided.
248Useful to reset the state of the clock without having to `uninstall` and `install` it.
249
250### `clock.runAll()` / `await clock.runAllAsync()`
251
252This runs all pending timers until there are none remaining. If new timers are added while it is executing they will be run as well.
253
254This makes it easier to run asynchronous tests to completion without worrying about the number of timers they use, or the delays in those timers.
255
256It runs a maximum of `loopLimit` times after which it assumes there is an infinite loop of timers and throws an error.
257
258The `runAllAsync()` will also break the event loop, allowing any scheduled promise
259callbacks to execute _before_ running the timers.
260
261### `clock.runMicrotasks()`
262
263This runs all pending microtasks scheduled with `nextTick` but none of the timers and is mostly useful for libraries using FakeTimers underneath and for running `nextTick` items without any timers.
264
265### `clock.runToFrame()`
266
267Advances the clock to the next frame, firing all scheduled animation frame callbacks,
268if any, for that frame as well as any other timers scheduled along the way.
269
270### `clock.runToLast()` / `await clock.runToLastAsync()`
271
272This takes note of the last scheduled timer when it is run, and advances the
273clock to that time firing callbacks as necessary.
274
275If new timers are added while it is executing they will be run only if they
276would occur before this time.
277
278This is useful when you want to run a test to completion, but the test recursively
279sets timers that would cause `runAll` to trigger an infinite loop warning.
280
281The `runToLastAsync()` will also break the event loop, allowing any scheduled promise
282callbacks to execute _before_ running the timers.
283
284### `clock.setSystemTime([now])`
285
286This simulates a user changing the system clock while your program is running.
287It affects the current time but it does not in itself cause e.g. timers to fire;
288they will fire exactly as they would have done without the call to
289setSystemTime().
290
291### `clock.uninstall()`
292
293Restores the original methods on the `target` that was passed to
294`FakeTimers.install`, or the native timers if no `target` was given.
295
296### `Date`
297
298Implements the `Date` object but using the clock to provide the correct time.
299
300### `Performance`
301
302Implements the `now` method of the [`Performance`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) object but using the clock to provide the correct time. Only available in environments that support the Performance object (browsers mostly).
303
304### `FakeTimers.withGlobal`
305
306In order to support creating clocks based on separate or sandboxed environments (such as JSDOM), FakeTimers exports a factory method which takes single argument `global`, which it inspects to figure out what to mock and what features to support. When invoking this function with a global, you will get back an object with `timers`, `createClock` and `install` - same as the regular FakeTimers exports only based on the passed in global instead of the global environment.
307
308## Running tests
309
310FakeTimers has a comprehensive test suite. If you're thinking of contributing bug
311fixes or suggesting new features, you need to make sure you have not broken any
312tests. You are also expected to add tests for any new behavior.
313
314### On node:
315
316```sh
317npm test
318```
319
320Or, if you prefer more verbose output:
321
322```
323$(npm bin)/mocha ./test/fake-timers-test.js
324```
325
326### In the browser
327
328[Mochify](https://github.com/mantoni/mochify.js) is used to run the tests in
329PhantomJS. Make sure you have `phantomjs` installed. Then:
330
331```sh
332npm test-headless
333```
334
335## License
336
337BSD 3-clause "New" or "Revised" License  (see LICENSE file)
338