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