Update checked-in dependencies

This commit is contained in:
github-actions[bot] 2021-07-27 22:26:09 +00:00
parent 3ba511a8f1
commit 1c4c64199f
175 changed files with 13227 additions and 15136 deletions

View file

@ -1,4 +1,79 @@
7.1.2 / 2021-05-28
==================
* Fix #382 by making config fields optional (#383)
* Fix #347 : Support util.promisify
7.1.1 / 2021-05-27
==================
* Fix JSDoc for createClock
7.1.0 / 2021-05-20
==================
* Remove Safari from Sauce Lab (ref #380)
* Bump hosted-git-info from 2.6.0 to 2.8.9
* Bump handlebars from 4.7.6 to 4.7.7
* Bump lodash from 4.17.19 to 4.17.21
* Add in latest Safari and evergreen Edge
* Drop IE11 and Safari 9
* chore: add type tests (#373)
* remove constructor types
* use globalThis to avoid conflicts
* Update yargs-parser
* Update mkdirp
* Upgrade jsdom
* Upgrade mochify to latest
* Upgrade Mocha to latest
* Bump y18n from 4.0.0 to 4.0.1
* make config optional
* add a bunch more types
7.0.5 / 2021-04-11
==================
* Fix up some clock types in JSDoc (becomes `.d.ts`) (#370)
* Fix refresh arguments forwarding (#369)
7.0.4 / 2021-04-08
==================
* Fix usage with TypeScript
7.0.3 / 2021-03-02
==================
* Removing the use of eval in Node.js (#331)
* Drop Node 8
* Add docs about typings (#357)
7.0.2 / 2021-01-18
==================
* Make config options optional in TypeScript defs (#354)
7.0.1 / 2021-01-14
==================
* Update README section about browser use
7.0.0 / 2021-01-12
==================
* Remove bundle from package. If you're loading `fake-timers` via
script tag, you'll now have to provide your own bundled version
* Add .d.ts files to package
* Revert "Add stack trace to code recursively scheduling timers" (#338)
* Remove unnecessary durations and use globals
* Support timeout.refresh in node environments
* Fix #319: Error message changed to TypeError
* Fix #319: The use of 'eval' has been removed
* Fix #304: clearTimeout clears setInterval and clearInterval clears setTimeout
* Remove config.target (#318)
6.0.1 / 2020-03-24
==================

View file

@ -14,6 +14,28 @@ wait.
`@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).
## Help us get our TypeScript definitions production ready!
In version 7 we introduced TypeScript definitions that are generated from our JSDoc. This makes importing types from [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/sinonjs__fake-timers/index.d.ts) superfluous, but we have just gotten started and we need your work for this to be up to the same quality. Until that happens typings from DefinitelyTyped still can be used:
```sh
npm install -D @types/sinonjs__fake-timers
```
Add this to tsconfig.json
```
{
"compilerOptions": {
...
"paths": {
...
"@sinonjs/fake-timers": ["node_modules/@types/sinonjs__fake-timers"]
}
}
}
```
## Installation
`@sinonjs/fake-timers` can be used in both Node and browser environments. Installation is as easy as
@ -22,11 +44,7 @@ wait.
npm install @sinonjs/fake-timers
```
If you want to use `@sinonjs/fake-timers` in a browser you can use [the pre-built
version](https://github.com/sinonjs/fake-timers/blob/master/fake-timers.js) available in the repo
and the npm package. Using npm you only need to reference `./node_modules/@sinonjs/fake-timers/fake-timers.js` in your `<script>` tags.
You are always free to [build it yourself](https://github.com/sinonjs/fake-timers/blob/53ea4d9b9e5bcff53cc7c9755dc9aa340368cf1c/package.json#L22), of course.
If you want to use `@sinonjs/fake-timers` in a browser you can either build your own bundle or use [Skypack](https://www.skypack.dev).
## Usage
@ -39,7 +57,9 @@ var FakeTimers = require("@sinonjs/fake-timers");
var clock = FakeTimers.createClock();
clock.setTimeout(function () {
console.log("The poblano is a mild chili pepper originating in the state of Puebla, Mexico.");
console.log(
"The poblano is a mild chili pepper originating in the state of Puebla, Mexico."
);
}, 15);
// ...
@ -48,7 +68,7 @@ clock.tick(15);
```
Upon executing the last line, an interesting fact about the
[Poblano](http://en.wikipedia.org/wiki/Poblano) will be printed synchronously to
[Poblano](https://en.wikipedia.org/wiki/Poblano) will be printed synchronously to
the screen. If you want to simulate asynchronous behavior, you have to use your
imagination when calling the various functions.
@ -83,9 +103,9 @@ To hijack timers in another context pass it to the `install` method.
```js
var FakeTimers = require("@sinonjs/fake-timers");
var context = {
setTimeout: setTimeout // By default context.setTimeout uses the global setTimeout
}
var clock = FakeTimers.install({target: context});
setTimeout: setTimeout, // By default context.setTimeout uses the global setTimeout
};
var clock = FakeTimers.withGlobal(context).install();
context.setTimeout(fn, 15); // Schedules with clock.setTimeout
@ -97,9 +117,10 @@ Usually you want to install the timers onto the global object, so call `install`
without arguments.
#### Automatically incrementing mocked time
Since version 2.0 FakeTimers supports the possibility to attach the faked timers
to any change in the real system time. This basically means you no longer need
to `tick()` the clock in a situation where you won't know **when** to call `tick()`.
FakeTimers supports the possibility to attach the faked timers to any change
in the real system time. This means that there is no need to `tick()` the
clock in a situation where you won't know **when** to call `tick()`.
Please note that this is achieved using the original setImmediate() API at a certain
configurable interval `config.advanceTimeDelta` (default: 20ms). Meaning time would
@ -109,18 +130,21 @@ An example would be:
```js
var FakeTimers = require("@sinonjs/fake-timers");
var clock = FakeTimers.install({shouldAdvanceTime: true, advanceTimeDelta: 40});
setTimeout(() => {
console.log('this just timed out'); //executed after 40ms
}, 30);
setImmediate(() => {
console.log('not so immediate'); //executed after 40ms
var clock = FakeTimers.install({
shouldAdvanceTime: true,
advanceTimeDelta: 40,
});
setTimeout(() => {
console.log('this timed out after'); //executed after 80ms
console.log("this just timed out"); //executed after 40ms
}, 30);
setImmediate(() => {
console.log("not so immediate"); //executed after 40ms
});
setTimeout(() => {
console.log("this timed out after"); //executed after 80ms
clock.uninstall();
}, 50);
```
@ -137,16 +161,16 @@ The `now` argument may be a number (in milliseconds) or a Date object.
The `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`.
### `var clock = FakeTimers.install([config])`
Installs FakeTimers using the specified config (otherwise with epoch `0` on the global scope). The following configuration options are available
Parameter | Type | Default | Description
--------- | ---- | ------- | ------------
`config.target`| Object | global | installs FakeTimers onto the specified target context
`config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch
`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`
`config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll()
`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)
`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.
| Parameter | Type | Default | Description |
| -------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch |
| `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` |
| `config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll() |
| `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) |
| `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. |
### `var id = clock.setTimeout(callback, timeout)`
@ -218,6 +242,7 @@ Returns the number of waiting timers. This can be used to assert that a test
finishes without leaking any timers.
### `clock.hrtime(prevTime?)`
Only available in Node.js, mimicks process.hrtime().
### `clock.nextTick(callback)`
@ -225,8 +250,8 @@ Only available in Node.js, mimicks process.hrtime().
Only available in Node.js, mimics `process.nextTick` to enable completely synchronous testing flows.
### `clock.performance.now()`
Only available in browser environments, mimicks performance.now().
Only available in browser environments, mimicks performance.now().
### `clock.tick(time)` / `await clock.tickAsync(time)`
@ -294,8 +319,8 @@ setSystemTime().
### `clock.uninstall()`
Restores the original methods on the `target` that was passed to
`FakeTimers.install`, or the native timers if no `target` was given.
Restores the original methods of the native timers or the methods on the object
that was passed to `FakeTimers.withGlobal`
### `Date`
@ -338,4 +363,4 @@ npm test-headless
## License
BSD 3-clause "New" or "Revised" License (see LICENSE file)
BSD 3-clause "New" or "Revised" License (see LICENSE file)

File diff suppressed because it is too large Load diff

View file

@ -1,42 +1,45 @@
{
"name": "@sinonjs/fake-timers",
"description": "Fake JavaScript timers",
"version": "6.0.1",
"homepage": "http://github.com/sinonjs/fake-timers",
"version": "7.1.2",
"homepage": "https://github.com/sinonjs/fake-timers",
"author": "Christian Johansen",
"repository": {
"type": "git",
"url": "http://github.com/sinonjs/fake-timers.git"
"url": "https://github.com/sinonjs/fake-timers.git"
},
"bugs": {
"mail": "christian@cjohansen.no",
"url": "http://github.com/sinonjs/fake-timers/issues"
"url": "https://github.com/sinonjs/fake-timers/issues"
},
"license": "BSD-3-Clause",
"scripts": {
"build": "rm -rf types && tsc",
"lint": "eslint .",
"test-node": "mocha test/ integration-test/ -R dot --check-leaks",
"test-headless": "mochify --no-detect-globals --timeout=10000",
"test-check-coverage": "npm run test-coverage && nyc check-coverage",
"test-cloud": "mochify --wd --no-detect-globals --timeout=10000",
"test-coverage": "nyc --all --reporter text --reporter html --reporter lcovonly npm run test-node",
"test": "npm run lint && npm run test-node && npm run test-headless",
"bundle": "browserify --no-detect-globals -s FakeTimers -o fake-timers.js src/fake-timers-src.js",
"prepublishOnly": "npm run bundle",
"test-types": "tsd && tsc --noEmit test/check-types.ts",
"test": "npm run test-node && npm run test-headless",
"prettier:check": "prettier --check '**/*.{js,css,md,ts}'",
"prettier:write": "prettier --write '**/*.{js,css,md,ts}'",
"prepublishOnly": "npm run build",
"preversion": "./scripts/preversion.sh",
"version": "./scripts/version.sh",
"postversion": "./scripts/postversion.sh"
},
"lint-staged": {
"*.{js,css,md}": "prettier --check",
"*.js": "eslint"
},
"files": [
"src/",
"fake-timers.js"
"types"
],
"devDependencies": {
"@sinonjs/referee-sinon": "6.0.1",
"browserify": "16.5.0",
"eslint": "6.8.0",
"eslint-config-prettier": "6.10.0",
"eslint-config-sinon": "3.0.1",
@ -44,42 +47,23 @@
"eslint-plugin-mocha": "6.2.2",
"eslint-plugin-prettier": "3.1.1",
"husky": "4.2.1",
"jsdom": "15.1.1",
"jsdom": "16.5.2",
"lint-staged": "10.0.7",
"mocha": "7.0.1",
"mochify": "6.6.0",
"npm-run-all": "4.1.5",
"mocha": "8.3.2",
"mochify": "7.0.0",
"nyc": "14.1.1",
"prettier": "1.19.1"
"prettier": "2.2.1",
"tsd": "0.14.0",
"typescript": "4.1.3"
},
"eslintConfig": {
"extends": "eslint-config-sinon",
"plugins": [
"ie11"
],
"rules": {
"ie11/no-collection-args": [
"error"
],
"ie11/no-for-in-const": [
"error"
],
"ie11/no-loop-func": [
"warn"
],
"ie11/no-weak-collections": [
"error"
]
}
},
"module": "./fake-timers.js",
"main": "./src/fake-timers-src.js",
"types": "./types/fake-timers-src.d.ts",
"dependencies": {
"@sinonjs/commons": "^1.7.0"
},
"husky": {
"hooks": {
"pre-commit": "run-p lint test-node"
"pre-commit": "npm run lint"
}
},
"nyc": {
@ -90,7 +74,11 @@
"exclude": [
"**/*-test.js",
"coverage/**",
"types/**",
"fake-timers.js"
]
},
"tsd": {
"directory": "test"
}
}

View file

@ -2,15 +2,76 @@
var globalObject = require("@sinonjs/commons").global;
// eslint-disable-next-line complexity
/**
* @typedef {object} Clock
* @property {number} now
* @property {any} timeouts
* @property {typeof globalThis.Date} Date
* @property {number} loopLimit
* @property {(func: Function, timeout: number) => number} requestIdleCallback
* @property {(timerId: number) => void} cancelIdleCallback
* @property {setTimeout} setTimeout
* @property {clearTimeout} clearTimeout
* @property {(func: Function, ...args: any[]) => void} nextTick
* @property {queueMicrotask} queueMicrotask
* @property {setInterval} setInterval
* @property {clearInterval} clearInterval
* @property {(func: (...args: any[]) => void, ...args: any[]) => NodeTimer} setImmediate
* @property {(timerId: NodeTimer) => void} clearImmediate
* @property {() => number} countTimers
* @property {(func: (timer: number) => void) => number} requestAnimationFrame
* @property {(timerId: number) => void} cancelAnimationFrame
* @property {() => void} runMicrotasks
* @property {(tickValue: string | number) => number} tick
* @property {(tickValue: string | number) => Promise<number>} tickAsync
* @property {() => number} next
* @property {() => Promise<number>} nextAsync
* @property {() => number} runAll
* @property {() => number} runToFrame
* @property {() => Promise<number>} runAllAsync
* @property {() => number} runToLast
* @property {() => Promise<number>} runToLastAsync
* @property {() => void} reset
* @property {(systemTime: number | Date) => void} setSystemTime
* @property {({now(): number})} performance
* @property {(prev: any) => number[]} hrTime
* @property {() => void} uninstall Uninstall the clock.
* @property {any} methods
*/
/**
* Configuration object for the `install` method.
*
* @typedef {object} Config
* @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
* @property {string[]} [toFake] names of the methods that should be faked.
* @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
* @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
* @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
*/
/**
* @typedef {object} NodeTimer
* @property {() => boolean} hasRef
* @property {() => any} ref
* @property {() => any} unref
*/
/* eslint-disable complexity */
/**
* Mocks available features in the specified global namespace.
*
* @param {*} _global Namespace to mock (e.g. `window`)
*/
function withGlobal(_global) {
var userAgent = _global.navigator && _global.navigator.userAgent;
var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1;
var maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint
var NOOP = function() {
var NOOP = function () {
return undefined;
};
var NOOP_ARRAY = function() {
var NOOP_ARRAY = function () {
return [];
};
var timeoutResult = _global.setTimeout(NOOP, 0);
@ -44,7 +105,7 @@ function withGlobal(_global) {
_global.setImmediate && typeof _global.setImmediate === "function";
// Make properties writable in IE, as per
// http://www.adequatelygood.com/Replacing-setTimeout-Globally.html
// https://www.adequatelygood.com/Replacing-setTimeout-Globally.html
/* eslint-disable no-self-assign */
if (isRunningInIE) {
_global.setTimeout = _global.setTimeout;
@ -72,10 +133,6 @@ function withGlobal(_global) {
return Number.isFinite(num);
}
if (typeof num !== "number") {
return false;
}
return isFinite(num);
}
@ -117,8 +174,8 @@ function withGlobal(_global) {
/**
* Get the decimal part of the millisecond value as nanoseconds
*
* @param {Number} msFloat the number of milliseconds
* @returns {Number} an integer number of nanoseconds in the range [0,1e6)
* @param {number} msFloat the number of milliseconds
* @returns {number} an integer number of nanoseconds in the range [0,1e6)
*
* Example: nanoRemainer(123.456789) -> 456789
*/
@ -132,7 +189,7 @@ function withGlobal(_global) {
/**
* Used to grok the `now` parameter to createClock.
* @param epoch {Date|number} the system time
* @param {Date|number} epoch the system time
*/
function getEpoch(epoch) {
if (!epoch) {
@ -271,9 +328,25 @@ function withGlobal(_global) {
throw new Error("Callback must be provided to timer calls");
}
if (addTimerReturnsObject) {
// Node.js environment
if (typeof timer.func !== "function") {
throw new TypeError(
"[ERR_INVALID_CALLBACK]: Callback must be a function. Received " +
timer.func +
" of type " +
typeof timer.func
);
}
}
timer.type = timer.immediate ? "Immediate" : "Timeout";
if (timer.hasOwnProperty("delay")) {
if (typeof timer.delay !== "number") {
timer.delay = parseInt(timer.delay, 10);
}
if (!isNumberFinite(timer.delay)) {
timer.delay = 0;
}
@ -305,15 +378,17 @@ function withGlobal(_global) {
if (addTimerReturnsObject) {
var res = {
id: timer.id,
ref: function() {
ref: function () {
return res;
},
unref: function() {
unref: function () {
return res;
},
refresh: function() {
return res;
}
refresh: function () {
clearTimeout(timer.id);
var args = [timer.func, timer.delay].concat(timer.args);
return setTimeout.apply(null, args);
},
};
return res;
}
@ -422,7 +497,10 @@ function withGlobal(_global) {
timer.func.apply(null, timer.args);
} else {
/* eslint no-eval: "off" */
eval(timer.func);
var eval2 = eval;
(function () {
eval2(timer.func);
})();
}
}
@ -444,7 +522,11 @@ function withGlobal(_global) {
if (clock.timers.hasOwnProperty(id)) {
// check that the ID matches a timer of the correct type
var timer = clock.timers[id];
if (timer.type === ttype) {
if (
timer.type === ttype ||
(timer.type === "Timeout" && ttype === "Interval") ||
(timer.type === "Interval" && ttype === "Timeout")
) {
delete clock.timers[id];
} else {
var clear =
@ -466,17 +548,17 @@ function withGlobal(_global) {
}
}
function uninstall(clock, target, config) {
function uninstall(clock, config) {
var method, i, l;
var installedHrTime = "_hrtime";
var installedNextTick = "_nextTick";
for (i = 0, l = clock.methods.length; i < l; i++) {
method = clock.methods[i];
if (method === "hrtime" && target.process) {
target.process.hrtime = clock[installedHrTime];
} else if (method === "nextTick" && target.process) {
target.process.nextTick = clock[installedNextTick];
if (method === "hrtime" && _global.process) {
_global.process.hrtime = clock[installedHrTime];
} else if (method === "nextTick" && _global.process) {
_global.process.nextTick = clock[installedNextTick];
} else if (method === "performance") {
var originalPerfDescriptor = Object.getOwnPropertyDescriptor(
clock,
@ -488,25 +570,25 @@ function withGlobal(_global) {
!originalPerfDescriptor.set
) {
Object.defineProperty(
target,
_global,
method,
originalPerfDescriptor
);
} else if (originalPerfDescriptor.configurable) {
target[method] = clock["_" + method];
_global[method] = clock["_" + method];
}
} else {
if (target[method] && target[method].hadOwnProperty) {
target[method] = clock["_" + method];
if (_global[method] && _global[method].hadOwnProperty) {
_global[method] = clock["_" + method];
if (
method === "clearInterval" &&
config.shouldAdvanceTime === true
) {
target[method](clock.attachedInterval);
_global[method](clock.attachedInterval);
}
} else {
try {
delete target[method];
delete _global[method];
} catch (ignore) {
/* eslint no-empty: "off" */
}
@ -527,7 +609,6 @@ function withGlobal(_global) {
}
function hijackMethod(target, method, clock) {
var prop;
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(
target,
method
@ -563,15 +644,14 @@ function withGlobal(_global) {
target[method] = clock[method];
}
} else {
target[method] = function() {
target[method] = function () {
return clock[method].apply(clock, arguments);
};
for (prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
target[method][prop] = clock[method][prop];
}
}
Object.defineProperties(
target[method],
Object.getOwnPropertyDescriptors(clock[method])
);
}
target[method].clock = clock;
@ -581,12 +661,32 @@ function withGlobal(_global) {
clock.tick(advanceTimeDelta);
}
/**
* @typedef {object} Timers
* @property {setTimeout} setTimeout
* @property {clearTimeout} clearTimeout
* @property {setInterval} setInterval
* @property {clearInterval} clearInterval
* @property {typeof globalThis.Date} Date
* @property {((fn: (...args: any[]) => void, ...args: any[]) => NodeTimer)=} setImmediate
* @property {((id: NodeTimer) => void)=} clearImmediate
* @property {((time?: [number, number]) => [number, number])=} hrtime
* @property {((fn: Function, ...args: any[]) => void)=} nextTick
* @property {({now(): number})=} performance
* @property {((fn: (timer: number) => void) => number)=} requestAnimationFrame
* @property {boolean=} queueMicrotask
* @property {((id: number) => void)=} cancelAnimationFrame
* @property {((fn: (deadline: any) => void, options?: any) => number)=} requestIdleCallback
* @property {((id: number) => void)=} cancelIdleCallback
*/
/** @type {Timers} */
var timers = {
setTimeout: _global.setTimeout,
clearTimeout: _global.clearTimeout,
setInterval: _global.setInterval,
clearInterval: _global.clearInterval,
Date: _global.Date
Date: _global.Date,
};
if (setImmediatePresent) {
@ -626,26 +726,12 @@ function withGlobal(_global) {
timers.cancelIdleCallback = _global.cancelIdleCallback;
}
var keys =
Object.keys ||
function(obj) {
var ks = [];
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
ks.push(key);
}
}
return ks;
};
var originalSetTimeout = _global.setImmediate || _global.setTimeout;
/**
* @param start {Date|number} the system time - non-integer values are floored
* @param loopLimit {number} maximum number of timers that will be run when calling runAll()
* @param {Date|number} [start] the system time - non-integer values are floored
* @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
* @returns {Clock}
*/
function createClock(start, loopLimit) {
// eslint-disable-next-line no-param-reassign
@ -666,7 +752,7 @@ function withGlobal(_global) {
now: start,
timeouts: {},
Date: createDate(),
loopLimit: loopLimit
loopLimit: loopLimit,
};
clock.Date.clock = clock;
@ -705,7 +791,7 @@ function withGlobal(_global) {
}
if (hrtimeBigintPresent) {
hrtime.bigint = function() {
hrtime.bigint = function () {
var parts = hrtime();
return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line
};
@ -727,7 +813,7 @@ function withGlobal(_global) {
delay:
typeof timeout === "undefined"
? timeToNextIdlePeriod
: Math.min(timeout, timeToNextIdlePeriod)
: Math.min(timeout, timeToNextIdlePeriod),
});
return result.id || result;
@ -741,7 +827,7 @@ function withGlobal(_global) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout
delay: timeout,
});
};
if (typeof _global.Promise !== "undefined" && utilPromisify) {
@ -754,7 +840,7 @@ function withGlobal(_global) {
addTimer(clock, {
func: resolve,
args: [arg],
delay: timeout
delay: timeout,
});
});
};
@ -767,7 +853,7 @@ function withGlobal(_global) {
clock.nextTick = function nextTick(func) {
return enqueueJob(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 1)
args: Array.prototype.slice.call(arguments, 1),
});
};
@ -782,7 +868,7 @@ function withGlobal(_global) {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout,
interval: timeout
interval: timeout,
});
};
@ -795,7 +881,7 @@ function withGlobal(_global) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 1),
immediate: true
immediate: true,
});
};
@ -809,7 +895,7 @@ function withGlobal(_global) {
addTimer(clock, {
func: resolve,
args: [arg],
immediate: true
immediate: true,
});
});
};
@ -832,7 +918,7 @@ function withGlobal(_global) {
func: func,
delay: getTimeToNextFrame(),
args: [clock.now + getTimeToNextFrame()],
animation: true
animation: true,
});
return result.id || result;
@ -955,7 +1041,7 @@ function withGlobal(_global) {
nextPromiseTick =
isAsync &&
function() {
function () {
try {
compensationCheck();
postTimerCall();
@ -965,7 +1051,7 @@ function withGlobal(_global) {
}
};
compensationCheck = function() {
compensationCheck = function () {
// compensate for any setSystemTime() call during timer callback
if (oldNow !== clock.now) {
tickFrom += clock.now - oldNow;
@ -974,7 +1060,7 @@ function withGlobal(_global) {
}
};
postTimerCall = function() {
postTimerCall = function () {
timer = firstTimerInRange(clock, previous, tickTo);
previous = tickFrom;
};
@ -983,7 +1069,7 @@ function withGlobal(_global) {
}
/**
* @param {tickValue} {String|Number} number of milliseconds or a human-readable value like "01:11:15"
* @param {tickValue} {string|number} number of milliseconds or a human-readable value like "01:11:15"
*/
clock.tick = function tick(tickValue) {
return doTick(tickValue, false);
@ -991,8 +1077,8 @@ function withGlobal(_global) {
if (typeof _global.Promise !== "undefined") {
clock.tickAsync = function tickAsync(ms) {
return new _global.Promise(function(resolve, reject) {
originalSetTimeout(function() {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
doTick(ms, true, resolve, reject);
} catch (e) {
@ -1023,8 +1109,8 @@ function withGlobal(_global) {
if (typeof _global.Promise !== "undefined") {
clock.nextAsync = function nextAsync() {
return new _global.Promise(function(resolve, reject) {
originalSetTimeout(function() {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
var timer = firstTimer(clock);
if (!timer) {
@ -1042,7 +1128,7 @@ function withGlobal(_global) {
}
clock.duringTick = false;
originalSetTimeout(function() {
originalSetTimeout(function () {
if (err) {
reject(err);
} else {
@ -1065,7 +1151,7 @@ function withGlobal(_global) {
return clock.now;
}
numTimers = keys(clock.timers).length;
numTimers = Object.keys(clock.timers).length;
if (numTimers === 0) {
return clock.now;
}
@ -1086,10 +1172,10 @@ function withGlobal(_global) {
if (typeof _global.Promise !== "undefined") {
clock.runAllAsync = function runAllAsync() {
return new _global.Promise(function(resolve, reject) {
return new _global.Promise(function (resolve, reject) {
var i = 0;
function doRun() {
originalSetTimeout(function() {
originalSetTimeout(function () {
try {
var numTimers;
if (i < clock.loopLimit) {
@ -1142,8 +1228,8 @@ function withGlobal(_global) {
if (typeof _global.Promise !== "undefined") {
clock.runToLastAsync = function runToLastAsync() {
return new _global.Promise(function(resolve, reject) {
originalSetTimeout(function() {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
var timer = lastTimer(clock);
if (!timer) {
@ -1194,7 +1280,7 @@ function withGlobal(_global) {
if (hasPerformancePrototype) {
var proto = _global.Performance.prototype;
Object.getOwnPropertyNames(proto).forEach(function(name) {
Object.getOwnPropertyNames(proto).forEach(function (name) {
if (name.indexOf("getEntries") === 0) {
// match expected return type for getEntries functions
clock.performance[name] = NOOP_ARRAY;
@ -1218,16 +1304,12 @@ function withGlobal(_global) {
return clock;
}
/* eslint-disable complexity */
/**
* @param config {Object} optional config
* @param config.target {Object} the target to install timers in (default `window`)
* @param config.now {number|Date} a number (in milliseconds) or a Date object (default epoch)
* @param config.toFake {string[]} names of the methods that should be faked.
* @param config.loopLimit {number} the maximum number of timers that will be run when calling runAll()
* @param config.shouldAdvanceTime {Boolean} tells FakeTimers to increment mocked time automatically (default false)
* @param config.advanceTimeDelta {Number} increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
* @param {Config=} [config] Optional config
* @returns {Clock}
*/
// eslint-disable-next-line complexity
function install(config) {
if (
arguments.length > 1 ||
@ -1247,19 +1329,24 @@ function withGlobal(_global) {
config.shouldAdvanceTime = config.shouldAdvanceTime || false;
config.advanceTimeDelta = config.advanceTimeDelta || 20;
if (config.target) {
throw new TypeError(
"config.target is no longer supported. Use `withGlobal(target)` instead."
);
}
var i, l;
var target = config.target || _global;
var clock = createClock(config.now, config.loopLimit);
clock.uninstall = function() {
return uninstall(clock, target, config);
clock.uninstall = function () {
return uninstall(clock, config);
};
clock.methods = config.toFake || [];
if (clock.methods.length === 0) {
// do not fake nextTick by default - GitHub#126
clock.methods = keys(timers).filter(function(key) {
clock.methods = Object.keys(timers).filter(function (key) {
return key !== "nextTick" && key !== "queueMicrotask";
});
}
@ -1267,17 +1354,17 @@ function withGlobal(_global) {
for (i = 0, l = clock.methods.length; i < l; i++) {
if (clock.methods[i] === "hrtime") {
if (
target.process &&
typeof target.process.hrtime === "function"
_global.process &&
typeof _global.process.hrtime === "function"
) {
hijackMethod(target.process, clock.methods[i], clock);
hijackMethod(_global.process, clock.methods[i], clock);
}
} else if (clock.methods[i] === "nextTick") {
if (
target.process &&
typeof target.process.nextTick === "function"
_global.process &&
typeof _global.process.nextTick === "function"
) {
hijackMethod(target.process, clock.methods[i], clock);
hijackMethod(_global.process, clock.methods[i], clock);
}
} else {
if (
@ -1289,27 +1376,31 @@ function withGlobal(_global) {
clock,
config.advanceTimeDelta
);
var intervalId = target[clock.methods[i]](
var intervalId = _global[clock.methods[i]](
intervalTick,
config.advanceTimeDelta
);
clock.attachedInterval = intervalId;
}
hijackMethod(target, clock.methods[i], clock);
hijackMethod(_global, clock.methods[i], clock);
}
}
return clock;
}
/* eslint-enable complexity */
return {
timers: timers,
createClock: createClock,
install: install,
withGlobal: withGlobal
withGlobal: withGlobal,
};
}
/* eslint-enable complexity */
var defaultImplementation = withGlobal(globalObject);
exports.timers = defaultImplementation.timers;

View file

@ -0,0 +1,187 @@
export type Clock = {
now: number;
timeouts: any;
Date: typeof globalThis.Date;
loopLimit: number;
requestIdleCallback: (func: Function, timeout: number) => number;
cancelIdleCallback: (timerId: number) => void;
setTimeout: typeof setTimeout;
clearTimeout: typeof clearTimeout;
nextTick: (func: Function, ...args: any[]) => void;
queueMicrotask: typeof queueMicrotask;
setInterval: typeof setInterval;
clearInterval: typeof clearInterval;
setImmediate: (func: (...args: any[]) => void, ...args: any[]) => NodeTimer;
clearImmediate: (timerId: NodeTimer) => void;
countTimers: () => number;
requestAnimationFrame: (func: (timer: number) => void) => number;
cancelAnimationFrame: (timerId: number) => void;
runMicrotasks: () => void;
tick: (tickValue: string | number) => number;
tickAsync: (tickValue: string | number) => Promise<number>;
next: () => number;
nextAsync: () => Promise<number>;
runAll: () => number;
runToFrame: () => number;
runAllAsync: () => Promise<number>;
runToLast: () => number;
runToLastAsync: () => Promise<number>;
reset: () => void;
setSystemTime: (systemTime: number | Date) => void;
performance: ({
now(): number;
});
hrTime: (prev: any) => number[];
/**
* Uninstall the clock.
*/
uninstall: () => void;
methods: any;
};
/**
* Configuration object for the `install` method.
*/
export type Config = {
/**
* a number (in milliseconds) or a Date object (default epoch)
*/
now?: number | Date;
/**
* names of the methods that should be faked.
*/
toFake?: string[];
/**
* the maximum number of timers that will be run when calling runAll()
*/
loopLimit?: number;
/**
* tells FakeTimers to increment mocked time automatically (default false)
*/
shouldAdvanceTime?: boolean;
/**
* increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
*/
advanceTimeDelta?: number;
};
export type NodeTimer = {
hasRef: () => boolean;
ref: () => any;
unref: () => any;
};
export namespace timers {
const setTimeout_1: typeof globalThis.setTimeout;
export { setTimeout_1 as setTimeout };
const clearTimeout_1: typeof globalThis.clearTimeout;
export { clearTimeout_1 as clearTimeout };
const setInterval_1: typeof globalThis.setInterval;
export { setInterval_1 as setInterval };
const clearInterval_1: typeof globalThis.clearInterval;
export { clearInterval_1 as clearInterval };
const Date_1: typeof globalThis.Date;
export { Date_1 as Date };
export const setImmediate: (fn: (...args: any[]) => void, ...args: any[]) => NodeTimer;
export const clearImmediate: (id: NodeTimer) => void;
export const hrtime: (time?: [number, number]) => [number, number];
export const nextTick: (fn: Function, ...args: any[]) => void;
export const performance: ({
now(): number;
}) | undefined;
export const requestAnimationFrame: (fn: (timer: number) => void) => number;
const queueMicrotask_1: boolean | undefined;
export { queueMicrotask_1 as queueMicrotask };
export const cancelAnimationFrame: (id: number) => void;
export const requestIdleCallback: (fn: (deadline: any) => void, options?: any) => number;
export const cancelIdleCallback: (id: number) => void;
}
/**
* @param {Date|number} [start] the system time - non-integer values are floored
* @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
* @returns {Clock}
*/
export function createClock(start?: Date | number, loopLimit?: number): Clock;
/**
* @param {Config=} [config] Optional config
* @returns {Clock}
*/
export function install(config?: Config | undefined, ...args: any[]): Clock;
/**
* @typedef {object} Clock
* @property {number} now
* @property {any} timeouts
* @property {typeof globalThis.Date} Date
* @property {number} loopLimit
* @property {(func: Function, timeout: number) => number} requestIdleCallback
* @property {(timerId: number) => void} cancelIdleCallback
* @property {setTimeout} setTimeout
* @property {clearTimeout} clearTimeout
* @property {(func: Function, ...args: any[]) => void} nextTick
* @property {queueMicrotask} queueMicrotask
* @property {setInterval} setInterval
* @property {clearInterval} clearInterval
* @property {(func: (...args: any[]) => void, ...args: any[]) => NodeTimer} setImmediate
* @property {(timerId: NodeTimer) => void} clearImmediate
* @property {() => number} countTimers
* @property {(func: (timer: number) => void) => number} requestAnimationFrame
* @property {(timerId: number) => void} cancelAnimationFrame
* @property {() => void} runMicrotasks
* @property {(tickValue: string | number) => number} tick
* @property {(tickValue: string | number) => Promise<number>} tickAsync
* @property {() => number} next
* @property {() => Promise<number>} nextAsync
* @property {() => number} runAll
* @property {() => number} runToFrame
* @property {() => Promise<number>} runAllAsync
* @property {() => number} runToLast
* @property {() => Promise<number>} runToLastAsync
* @property {() => void} reset
* @property {(systemTime: number | Date) => void} setSystemTime
* @property {({now(): number})} performance
* @property {(prev: any) => number[]} hrTime
* @property {() => void} uninstall Uninstall the clock.
* @property {any} methods
*/
/**
* Configuration object for the `install` method.
*
* @typedef {object} Config
* @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
* @property {string[]} [toFake] names of the methods that should be faked.
* @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
* @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
* @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
*/
/**
* @typedef {object} NodeTimer
* @property {() => boolean} hasRef
* @property {() => any} ref
* @property {() => any} unref
*/
/**
* Mocks available features in the specified global namespace.
*
* @param {*} _global Namespace to mock (e.g. `window`)
*/
export function withGlobal(_global: any): {
timers: {
setTimeout: typeof setTimeout;
clearTimeout: typeof clearTimeout;
setInterval: typeof setInterval;
clearInterval: typeof clearInterval;
Date: typeof globalThis.Date;
setImmediate?: (fn: (...args: any[]) => void, ...args: any[]) => NodeTimer;
clearImmediate?: (id: NodeTimer) => void;
hrtime?: (time?: [number, number]) => [number, number];
nextTick?: (fn: Function, ...args: any[]) => void;
performance?: ({
now(): number;
}) | undefined;
requestAnimationFrame?: (fn: (timer: number) => void) => number;
queueMicrotask?: boolean | undefined;
cancelAnimationFrame?: (id: number) => void;
requestIdleCallback?: (fn: (deadline: any) => void, options?: any) => number;
cancelIdleCallback?: (id: number) => void;
};
createClock: (start?: Date | number, loopLimit?: number) => Clock;
install: (config?: Config | undefined, ...args: any[]) => Clock;
withGlobal: typeof withGlobal;
};