aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
diff options
context:
space:
mode:
Diffstat (limited to 'vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js')
-rw-r--r--vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js3919
1 files changed, 0 insertions, 3919 deletions
diff --git a/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js b/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
deleted file mode 100644
index 1e3d35a..0000000
--- a/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
+++ /dev/null
@@ -1,3919 +0,0 @@
-import { chai, equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, JestAsymmetricMatchers, GLOBAL_EXPECT, ASYMMETRIC_MATCHERS_OBJECT, getState, setState, addCustomEqualityTesters, customMatchers } from '@vitest/expect';
-import { getCurrentTest } from '@vitest/runner';
-import { g as getWorkerState, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.DvEY5TfP.js';
-import { getSafeTimers, delay } from '@vitest/utils/timers';
-import { getNames } from '@vitest/runner/utils';
-import { stripSnapshotIndentation, addSerializer, SnapshotClient } from '@vitest/snapshot';
-import '@vitest/utils/error';
-import { assertTypes, createSimpleStackTrace } from '@vitest/utils/helpers';
-import { fn, spyOn, restoreAllMocks, resetAllMocks, clearAllMocks, isMockFunction } from '@vitest/spy';
-import '@vitest/utils/offset';
-import { parseSingleStack } from '@vitest/utils/source-map';
-import { c as commonjsGlobal } from './_commonjsHelpers.D26ty3Ew.js';
-import { R as RealDate, r as resetDate, m as mockDate } from './date.Bq6ZW5rf.js';
-
-// these matchers are not supported because they don't make sense with poll
-const unsupported = [
- "matchSnapshot",
- "toMatchSnapshot",
- "toMatchInlineSnapshot",
- "toThrowErrorMatchingSnapshot",
- "toThrowErrorMatchingInlineSnapshot",
- "throws",
- "Throw",
- "throw",
- "toThrow",
- "toThrowError"
-];
-/**
-* Attaches a `cause` property to the error if missing, copies the stack trace from the source, and throws.
-*
-* @param error - The error to throw
-* @param source - Error to copy the stack trace from
-*
-* @throws Always throws the provided error with an amended stack trace
-*/
-function throwWithCause(error, source) {
- if (error.cause == null) error.cause = /* @__PURE__ */ new Error("Matcher did not succeed in time.");
- throw copyStackTrace$1(error, source);
-}
-function createExpectPoll(expect) {
- return function poll(fn, options = {}) {
- const defaults = getWorkerState().config.expect?.poll ?? {};
- const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options;
- // @ts-expect-error private poll access
- const assertion = expect(null, message).withContext({ poll: true });
- fn = fn.bind(assertion);
- const test = chai.util.flag(assertion, "vitest-test");
- if (!test) throw new Error("expect.poll() must be called inside a test");
- const proxy = new Proxy(assertion, { get(target, key, receiver) {
- const assertionFunction = Reflect.get(target, key, receiver);
- if (typeof assertionFunction !== "function") return assertionFunction instanceof chai.Assertion ? proxy : assertionFunction;
- if (key === "assert") return assertionFunction;
- if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`);
- return function(...args) {
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
- const promise = async () => {
- const { setTimeout, clearTimeout } = getSafeTimers();
- let executionPhase = "fn";
- let hasTimedOut = false;
- const timerId = setTimeout(() => {
- hasTimedOut = true;
- }, timeout);
- chai.util.flag(assertion, "_name", key);
- try {
- while (true) {
- const isLastAttempt = hasTimedOut;
- if (isLastAttempt) chai.util.flag(assertion, "_isLastPollAttempt", true);
- try {
- executionPhase = "fn";
- const obj = await fn();
- chai.util.flag(assertion, "object", obj);
- executionPhase = "assertion";
- return await assertionFunction.call(assertion, ...args);
- } catch (err) {
- if (isLastAttempt || executionPhase === "assertion" && chai.util.flag(assertion, "_poll.assert_once")) throwWithCause(err, STACK_TRACE_ERROR);
- await delay(interval, setTimeout);
- }
- }
- } finally {
- clearTimeout(timerId);
- }
- };
- let awaited = false;
- test.onFinished ??= [];
- test.onFinished.push(() => {
- if (!awaited) {
- const negated = chai.util.flag(assertion, "negate") ? "not." : "";
- const assertionString = `expect.${chai.util.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"}.${negated}${String(key)}()`;
- throw copyStackTrace$1(/* @__PURE__ */ new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`), STACK_TRACE_ERROR);
- }
- });
- let resultPromise;
- // only .then is enough to check awaited, but we type this as `Promise<void>` in global types
- // so let's follow it
- return {
- then(onFulfilled, onRejected) {
- awaited = true;
- return (resultPromise ||= promise()).then(onFulfilled, onRejected);
- },
- catch(onRejected) {
- return (resultPromise ||= promise()).catch(onRejected);
- },
- finally(onFinally) {
- return (resultPromise ||= promise()).finally(onFinally);
- },
- [Symbol.toStringTag]: "Promise"
- };
- };
- } });
- return proxy;
- };
-}
-function copyStackTrace$1(target, source) {
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
- return target;
-}
-
-function createAssertionMessage(util, assertion, hasArgs) {
- const not = util.flag(assertion, "negate") ? "not." : "";
- const name = `${util.flag(assertion, "_name")}(${"expected" })`;
- const promiseName = util.flag(assertion, "promise");
- return `expect(actual)${promiseName ? `.${promiseName}` : ""}.${not}${name}`;
-}
-function recordAsyncExpect(_test, promise, assertion, error) {
- const test = _test;
- // record promise for test, that resolves before test ends
- if (test && promise instanceof Promise) {
- // if promise is explicitly awaited, remove it from the list
- promise = promise.finally(() => {
- if (!test.promises) return;
- const index = test.promises.indexOf(promise);
- if (index !== -1) test.promises.splice(index, 1);
- });
- // record promise
- if (!test.promises) test.promises = [];
- test.promises.push(promise);
- let resolved = false;
- test.onFinished ??= [];
- test.onFinished.push(() => {
- if (!resolved) {
- const stack = (globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""))(error.stack);
- console.warn([
- `Promise returned by \`${assertion}\` was not awaited. `,
- "Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. ",
- "Please remember to await the assertion.\n",
- stack
- ].join(""));
- }
- });
- return {
- then(onFulfilled, onRejected) {
- resolved = true;
- return promise.then(onFulfilled, onRejected);
- },
- catch(onRejected) {
- return promise.catch(onRejected);
- },
- finally(onFinally) {
- return promise.finally(onFinally);
- },
- [Symbol.toStringTag]: "Promise"
- };
- }
- return promise;
-}
-
-let _client;
-function getSnapshotClient() {
- if (!_client) _client = new SnapshotClient({ isEqual: (received, expected) => {
- return equals(received, expected, [iterableEquality, subsetEquality]);
- } });
- return _client;
-}
-function getError(expected, promise) {
- if (typeof expected !== "function") {
- if (!promise) throw new Error(`expected must be a function, received ${typeof expected}`);
- // when "promised", it receives thrown error
- return expected;
- }
- try {
- expected();
- } catch (e) {
- return e;
- }
- throw new Error("snapshot function didn't throw");
-}
-function getTestNames(test) {
- return {
- filepath: test.file.filepath,
- name: getNames(test).slice(1).join(" > "),
- testId: test.id
- };
-}
-const SnapshotPlugin = (chai, utils) => {
- function getTest(assertionName, obj) {
- const test = utils.flag(obj, "vitest-test");
- if (!test) throw new Error(`'${assertionName}' cannot be used without test context`);
- return test;
- }
- for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, function(properties, message) {
- utils.flag(this, "_name", key);
- if (utils.flag(this, "negate")) throw new Error(`${key} cannot be used with "not"`);
- const expected = utils.flag(this, "object");
- const test = getTest(key, this);
- if (typeof properties === "string" && typeof message === "undefined") {
- message = properties;
- properties = void 0;
- }
- const errorMessage = utils.flag(this, "message");
- getSnapshotClient().assert({
- received: expected,
- message,
- isInline: false,
- properties,
- errorMessage,
- ...getTestNames(test)
- });
- });
- utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(file, message) {
- utils.flag(this, "_name", "toMatchFileSnapshot");
- if (utils.flag(this, "negate")) throw new Error("toMatchFileSnapshot cannot be used with \"not\"");
- const error = /* @__PURE__ */ new Error("resolves");
- const expected = utils.flag(this, "object");
- const test = getTest("toMatchFileSnapshot", this);
- const errorMessage = utils.flag(this, "message");
- return recordAsyncExpect(test, getSnapshotClient().assertRaw({
- received: expected,
- message,
- isInline: false,
- rawSnapshot: { file },
- errorMessage,
- ...getTestNames(test)
- }), createAssertionMessage(utils, this), error);
- });
- utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT__(properties, inlineSnapshot, message) {
- utils.flag(this, "_name", "toMatchInlineSnapshot");
- if (utils.flag(this, "negate")) throw new Error("toMatchInlineSnapshot cannot be used with \"not\"");
- const test = getTest("toMatchInlineSnapshot", this);
- if (test.each || test.suite?.each) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
- const expected = utils.flag(this, "object");
- const error = utils.flag(this, "error");
- if (typeof properties === "string") {
- message = inlineSnapshot;
- inlineSnapshot = properties;
- properties = void 0;
- }
- if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
- const errorMessage = utils.flag(this, "message");
- getSnapshotClient().assert({
- received: expected,
- message,
- isInline: true,
- properties,
- inlineSnapshot,
- error,
- errorMessage,
- ...getTestNames(test)
- });
- });
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", function(message) {
- utils.flag(this, "_name", "toThrowErrorMatchingSnapshot");
- if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingSnapshot cannot be used with \"not\"");
- const expected = utils.flag(this, "object");
- const test = getTest("toThrowErrorMatchingSnapshot", this);
- const promise = utils.flag(this, "promise");
- const errorMessage = utils.flag(this, "message");
- getSnapshotClient().assert({
- received: getError(expected, promise),
- message,
- errorMessage,
- ...getTestNames(test)
- });
- });
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT__(inlineSnapshot, message) {
- if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingInlineSnapshot cannot be used with \"not\"");
- const test = getTest("toThrowErrorMatchingInlineSnapshot", this);
- if (test.each || test.suite?.each) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
- const expected = utils.flag(this, "object");
- const error = utils.flag(this, "error");
- const promise = utils.flag(this, "promise");
- const errorMessage = utils.flag(this, "message");
- if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
- getSnapshotClient().assert({
- received: getError(expected, promise),
- message,
- inlineSnapshot,
- isInline: true,
- error,
- errorMessage,
- ...getTestNames(test)
- });
- });
- utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer);
-};
-
-chai.use(JestExtend);
-chai.use(JestChaiExpect);
-chai.use(SnapshotPlugin);
-chai.use(JestAsymmetricMatchers);
-
-function createExpect(test) {
- const expect = ((value, message) => {
- const { assertionCalls } = getState(expect);
- setState({ assertionCalls: assertionCalls + 1 }, expect);
- const assert = chai.expect(value, message);
- const _test = test || getCurrentTest();
- if (_test)
- // @ts-expect-error internal
- return assert.withTest(_test);
- else return assert;
- });
- Object.assign(expect, chai.expect);
- Object.assign(expect, globalThis[ASYMMETRIC_MATCHERS_OBJECT]);
- expect.getState = () => getState(expect);
- expect.setState = (state) => setState(state, expect);
- // @ts-expect-error global is not typed
- const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
- setState({
- ...globalState,
- assertionCalls: 0,
- isExpectingAssertions: false,
- isExpectingAssertionsError: null,
- expectedAssertionsNumber: null,
- expectedAssertionsNumberErrorGen: null,
- get testPath() {
- return getWorkerState().filepath;
- },
- currentTestName: test ? test.fullTestName ?? "" : globalState.currentTestName
- }, expect);
- expect.assert = chai.assert;
- // @ts-expect-error untyped
- expect.extend = (matchers) => chai.expect.extend(expect, matchers);
- expect.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
- expect.soft = (...args) => {
- // @ts-expect-error private soft access
- return expect(...args).withContext({ soft: true });
- };
- expect.poll = createExpectPoll(expect);
- expect.unreachable = (message) => {
- chai.assert.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
- };
- function assertions(expected) {
- const errorGen = () => /* @__PURE__ */ new Error(`expected number of assertions to be ${expected}, but got ${expect.getState().assertionCalls}`);
- if (Error.captureStackTrace) Error.captureStackTrace(errorGen(), assertions);
- expect.setState({
- expectedAssertionsNumber: expected,
- expectedAssertionsNumberErrorGen: errorGen
- });
- }
- function hasAssertions() {
- const error = /* @__PURE__ */ new Error("expected any number of assertion, but got none");
- if (Error.captureStackTrace) Error.captureStackTrace(error, hasAssertions);
- expect.setState({
- isExpectingAssertions: true,
- isExpectingAssertionsError: error
- });
- }
- chai.util.addMethod(expect, "assertions", assertions);
- chai.util.addMethod(expect, "hasAssertions", hasAssertions);
- expect.extend(customMatchers);
- return expect;
-}
-const globalExpect = createExpect();
-Object.defineProperty(globalThis, GLOBAL_EXPECT, {
- value: globalExpect,
- writable: true,
- configurable: true
-});
-const assert = chai.assert;
-const should = chai.should;
-
-/**
-* Gives access to injected context provided from the main thread.
-* This usually returns a value provided by `globalSetup` or an external library.
-*/
-function inject(key) {
- return getWorkerState().providedContext[key];
-}
-
-var fakeTimersSrc = {};
-
-var global;
-var hasRequiredGlobal;
-
-function requireGlobal () {
- if (hasRequiredGlobal) return global;
- hasRequiredGlobal = 1;
-
- /**
- * A reference to the global object
- * @type {object} globalObject
- */
- var globalObject;
-
- /* istanbul ignore else */
- if (typeof commonjsGlobal !== "undefined") {
- // Node
- globalObject = commonjsGlobal;
- } else if (typeof window !== "undefined") {
- // Browser
- globalObject = window;
- } else {
- // WebWorker
- globalObject = self;
- }
-
- global = globalObject;
- return global;
-}
-
-var throwsOnProto_1;
-var hasRequiredThrowsOnProto;
-
-function requireThrowsOnProto () {
- if (hasRequiredThrowsOnProto) return throwsOnProto_1;
- hasRequiredThrowsOnProto = 1;
-
- /**
- * Is true when the environment causes an error to be thrown for accessing the
- * __proto__ property.
- * This is necessary in order to support `node --disable-proto=throw`.
- *
- * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
- * @type {boolean}
- */
- let throwsOnProto;
- try {
- const object = {};
- // eslint-disable-next-line no-proto, no-unused-expressions
- object.__proto__;
- throwsOnProto = false;
- } catch (_) {
- // This branch is covered when tests are run with `--disable-proto=throw`,
- // however we can test both branches at the same time, so this is ignored
- /* istanbul ignore next */
- throwsOnProto = true;
- }
-
- throwsOnProto_1 = throwsOnProto;
- return throwsOnProto_1;
-}
-
-var copyPrototypeMethods;
-var hasRequiredCopyPrototypeMethods;
-
-function requireCopyPrototypeMethods () {
- if (hasRequiredCopyPrototypeMethods) return copyPrototypeMethods;
- hasRequiredCopyPrototypeMethods = 1;
-
- var call = Function.call;
- var throwsOnProto = requireThrowsOnProto();
-
- var disallowedProperties = [
- // ignore size because it throws from Map
- "size",
- "caller",
- "callee",
- "arguments",
- ];
-
- // This branch is covered when tests are run with `--disable-proto=throw`,
- // however we can test both branches at the same time, so this is ignored
- /* istanbul ignore next */
- if (throwsOnProto) {
- disallowedProperties.push("__proto__");
- }
-
- copyPrototypeMethods = function copyPrototypeMethods(prototype) {
- // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
- return Object.getOwnPropertyNames(prototype).reduce(function (
- result,
- name
- ) {
- if (disallowedProperties.includes(name)) {
- return result;
- }
-
- if (typeof prototype[name] !== "function") {
- return result;
- }
-
- result[name] = call.bind(prototype[name]);
-
- return result;
- },
- Object.create(null));
- };
- return copyPrototypeMethods;
-}
-
-var array;
-var hasRequiredArray;
-
-function requireArray () {
- if (hasRequiredArray) return array;
- hasRequiredArray = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- array = copyPrototype(Array.prototype);
- return array;
-}
-
-var calledInOrder_1;
-var hasRequiredCalledInOrder;
-
-function requireCalledInOrder () {
- if (hasRequiredCalledInOrder) return calledInOrder_1;
- hasRequiredCalledInOrder = 1;
-
- var every = requireArray().every;
-
- /**
- * @private
- */
- function hasCallsLeft(callMap, spy) {
- if (callMap[spy.id] === undefined) {
- callMap[spy.id] = 0;
- }
-
- return callMap[spy.id] < spy.callCount;
- }
-
- /**
- * @private
- */
- function checkAdjacentCalls(callMap, spy, index, spies) {
- var calledBeforeNext = true;
-
- if (index !== spies.length - 1) {
- calledBeforeNext = spy.calledBefore(spies[index + 1]);
- }
-
- if (hasCallsLeft(callMap, spy) && calledBeforeNext) {
- callMap[spy.id] += 1;
- return true;
- }
-
- return false;
- }
-
- /**
- * A Sinon proxy object (fake, spy, stub)
- * @typedef {object} SinonProxy
- * @property {Function} calledBefore - A method that determines if this proxy was called before another one
- * @property {string} id - Some id
- * @property {number} callCount - Number of times this proxy has been called
- */
-
- /**
- * Returns true when the spies have been called in the order they were supplied in
- * @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments
- * @returns {boolean} true when spies are called in order, false otherwise
- */
- function calledInOrder(spies) {
- var callMap = {};
- // eslint-disable-next-line no-underscore-dangle
- var _spies = arguments.length > 1 ? arguments : spies;
-
- return every(_spies, checkAdjacentCalls.bind(null, callMap));
- }
-
- calledInOrder_1 = calledInOrder;
- return calledInOrder_1;
-}
-
-var className_1;
-var hasRequiredClassName;
-
-function requireClassName () {
- if (hasRequiredClassName) return className_1;
- hasRequiredClassName = 1;
-
- /**
- * Returns a display name for a value from a constructor
- * @param {object} value A value to examine
- * @returns {(string|null)} A string or null
- */
- function className(value) {
- const name = value.constructor && value.constructor.name;
- return name || null;
- }
-
- className_1 = className;
- return className_1;
-}
-
-var deprecated = {};
-
-/* eslint-disable no-console */
-
-var hasRequiredDeprecated;
-
-function requireDeprecated () {
- if (hasRequiredDeprecated) return deprecated;
- hasRequiredDeprecated = 1;
- (function (exports$1) {
-
- /**
- * Returns a function that will invoke the supplied function and print a
- * deprecation warning to the console each time it is called.
- * @param {Function} func
- * @param {string} msg
- * @returns {Function}
- */
- exports$1.wrap = function (func, msg) {
- var wrapped = function () {
- exports$1.printWarning(msg);
- return func.apply(this, arguments);
- };
- if (func.prototype) {
- wrapped.prototype = func.prototype;
- }
- return wrapped;
- };
-
- /**
- * Returns a string which can be supplied to `wrap()` to notify the user that a
- * particular part of the sinon API has been deprecated.
- * @param {string} packageName
- * @param {string} funcName
- * @returns {string}
- */
- exports$1.defaultMsg = function (packageName, funcName) {
- return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
- };
-
- /**
- * Prints a warning on the console, when it exists
- * @param {string} msg
- * @returns {undefined}
- */
- exports$1.printWarning = function (msg) {
- /* istanbul ignore next */
- if (typeof process === "object" && process.emitWarning) {
- // Emit Warnings in Node
- process.emitWarning(msg);
- } else if (console.info) {
- console.info(msg);
- } else {
- console.log(msg);
- }
- };
- } (deprecated));
- return deprecated;
-}
-
-var every;
-var hasRequiredEvery;
-
-function requireEvery () {
- if (hasRequiredEvery) return every;
- hasRequiredEvery = 1;
-
- /**
- * Returns true when fn returns true for all members of obj.
- * This is an every implementation that works for all iterables
- * @param {object} obj
- * @param {Function} fn
- * @returns {boolean}
- */
- every = function every(obj, fn) {
- var pass = true;
-
- try {
- // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
- obj.forEach(function () {
- if (!fn.apply(this, arguments)) {
- // Throwing an error is the only way to break `forEach`
- throw new Error();
- }
- });
- } catch (e) {
- pass = false;
- }
-
- return pass;
- };
- return every;
-}
-
-var functionName;
-var hasRequiredFunctionName;
-
-function requireFunctionName () {
- if (hasRequiredFunctionName) return functionName;
- hasRequiredFunctionName = 1;
-
- /**
- * Returns a display name for a function
- * @param {Function} func
- * @returns {string}
- */
- functionName = function functionName(func) {
- if (!func) {
- return "";
- }
-
- try {
- return (
- func.displayName ||
- func.name ||
- // Use function decomposition as a last resort to get function
- // name. Does not rely on function decomposition to work - if it
- // doesn't debugging will be slightly less informative
- // (i.e. toString will say 'spy' rather than 'myFunc').
- (String(func).match(/function ([^\s(]+)/) || [])[1]
- );
- } catch (e) {
- // Stringify may fail and we might get an exception, as a last-last
- // resort fall back to empty string.
- return "";
- }
- };
- return functionName;
-}
-
-var orderByFirstCall_1;
-var hasRequiredOrderByFirstCall;
-
-function requireOrderByFirstCall () {
- if (hasRequiredOrderByFirstCall) return orderByFirstCall_1;
- hasRequiredOrderByFirstCall = 1;
-
- var sort = requireArray().sort;
- var slice = requireArray().slice;
-
- /**
- * @private
- */
- function comparator(a, b) {
- // uuid, won't ever be equal
- var aCall = a.getCall(0);
- var bCall = b.getCall(0);
- var aId = (aCall && aCall.callId) || -1;
- var bId = (bCall && bCall.callId) || -1;
-
- return aId < bId ? -1 : 1;
- }
-
- /**
- * A Sinon proxy object (fake, spy, stub)
- * @typedef {object} SinonProxy
- * @property {Function} getCall - A method that can return the first call
- */
-
- /**
- * Sorts an array of SinonProxy instances (fake, spy, stub) by their first call
- * @param {SinonProxy[] | SinonProxy} spies
- * @returns {SinonProxy[]}
- */
- function orderByFirstCall(spies) {
- return sort(slice(spies), comparator);
- }
-
- orderByFirstCall_1 = orderByFirstCall;
- return orderByFirstCall_1;
-}
-
-var _function;
-var hasRequired_function;
-
-function require_function () {
- if (hasRequired_function) return _function;
- hasRequired_function = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- _function = copyPrototype(Function.prototype);
- return _function;
-}
-
-var map;
-var hasRequiredMap;
-
-function requireMap () {
- if (hasRequiredMap) return map;
- hasRequiredMap = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- map = copyPrototype(Map.prototype);
- return map;
-}
-
-var object;
-var hasRequiredObject;
-
-function requireObject () {
- if (hasRequiredObject) return object;
- hasRequiredObject = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- object = copyPrototype(Object.prototype);
- return object;
-}
-
-var set;
-var hasRequiredSet;
-
-function requireSet () {
- if (hasRequiredSet) return set;
- hasRequiredSet = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- set = copyPrototype(Set.prototype);
- return set;
-}
-
-var string;
-var hasRequiredString;
-
-function requireString () {
- if (hasRequiredString) return string;
- hasRequiredString = 1;
-
- var copyPrototype = requireCopyPrototypeMethods();
-
- string = copyPrototype(String.prototype);
- return string;
-}
-
-var prototypes;
-var hasRequiredPrototypes;
-
-function requirePrototypes () {
- if (hasRequiredPrototypes) return prototypes;
- hasRequiredPrototypes = 1;
-
- prototypes = {
- array: requireArray(),
- function: require_function(),
- map: requireMap(),
- object: requireObject(),
- set: requireSet(),
- string: requireString(),
- };
- return prototypes;
-}
-
-var typeDetect$1 = {exports: {}};
-
-var typeDetect = typeDetect$1.exports;
-
-var hasRequiredTypeDetect;
-
-function requireTypeDetect () {
- if (hasRequiredTypeDetect) return typeDetect$1.exports;
- hasRequiredTypeDetect = 1;
- (function (module, exports$1) {
- (function (global, factory) {
- module.exports = factory() ;
- }(typeDetect, (function () {
- /* !
- * type-detect
- * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
- var promiseExists = typeof Promise === 'function';
-
- /* eslint-disable no-undef */
- var globalObject = typeof self === 'object' ? self : commonjsGlobal; // eslint-disable-line id-blacklist
-
- var symbolExists = typeof Symbol !== 'undefined';
- var mapExists = typeof Map !== 'undefined';
- var setExists = typeof Set !== 'undefined';
- var weakMapExists = typeof WeakMap !== 'undefined';
- var weakSetExists = typeof WeakSet !== 'undefined';
- var dataViewExists = typeof DataView !== 'undefined';
- var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
- var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
- var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
- var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
- var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
- var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
- var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
- var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
- var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
- var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
- var toStringLeftSliceLength = 8;
- var toStringRightSliceLength = -1;
- /**
- * ### typeOf (obj)
- *
- * Uses `Object.prototype.toString` to determine the type of an object,
- * normalising behaviour across engine versions & well optimised.
- *
- * @param {Mixed} object
- * @return {String} object type
- * @api public
- */
- function typeDetect(obj) {
- /* ! Speed optimisation
- * Pre:
- * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
- * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
- * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
- * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
- * function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
- * Post:
- * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
- * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
- * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
- * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
- * function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
- */
- var typeofObj = typeof obj;
- if (typeofObj !== 'object') {
- return typeofObj;
- }
-
- /* ! Speed optimisation
- * Pre:
- * null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
- * Post:
- * null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
- */
- if (obj === null) {
- return 'null';
- }
-
- /* ! Spec Conformance
- * Test: `Object.prototype.toString.call(window)``
- * - Node === "[object global]"
- * - Chrome === "[object global]"
- * - Firefox === "[object Window]"
- * - PhantomJS === "[object Window]"
- * - Safari === "[object Window]"
- * - IE 11 === "[object Window]"
- * - IE Edge === "[object Window]"
- * Test: `Object.prototype.toString.call(this)``
- * - Chrome Worker === "[object global]"
- * - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
- * - Safari Worker === "[object DedicatedWorkerGlobalScope]"
- * - IE 11 Worker === "[object WorkerGlobalScope]"
- * - IE Edge Worker === "[object WorkerGlobalScope]"
- */
- if (obj === globalObject) {
- return 'global';
- }
-
- /* ! Speed optimisation
- * Pre:
- * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
- * Post:
- * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
- */
- if (
- Array.isArray(obj) &&
- (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
- ) {
- return 'Array';
- }
-
- // Not caching existence of `window` and related properties due to potential
- // for `window` to be unset before tests in quasi-browser environments.
- if (typeof window === 'object' && window !== null) {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/browsers.html#location)
- * WhatWG HTML$7.7.3 - The `Location` interface
- * Test: `Object.prototype.toString.call(window.location)``
- * - IE <=11 === "[object Object]"
- * - IE Edge <=13 === "[object Object]"
- */
- if (typeof window.location === 'object' && obj === window.location) {
- return 'Location';
- }
-
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#document)
- * WhatWG HTML$3.1.1 - The `Document` object
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * WhatWG HTML states:
- * > For historical reasons, Window objects must also have a
- * > writable, configurable, non-enumerable property named
- * > HTMLDocument whose value is the Document interface object.
- * Test: `Object.prototype.toString.call(document)``
- * - Chrome === "[object HTMLDocument]"
- * - Firefox === "[object HTMLDocument]"
- * - Safari === "[object HTMLDocument]"
- * - IE <=10 === "[object Document]"
- * - IE 11 === "[object HTMLDocument]"
- * - IE Edge <=13 === "[object HTMLDocument]"
- */
- if (typeof window.document === 'object' && obj === window.document) {
- return 'Document';
- }
-
- if (typeof window.navigator === 'object') {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
- * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
- * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
- * - IE <=10 === "[object MSMimeTypesCollection]"
- */
- if (typeof window.navigator.mimeTypes === 'object' &&
- obj === window.navigator.mimeTypes) {
- return 'MimeTypeArray';
- }
-
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
- * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
- * Test: `Object.prototype.toString.call(navigator.plugins)``
- * - IE <=10 === "[object MSPluginsCollection]"
- */
- if (typeof window.navigator.plugins === 'object' &&
- obj === window.navigator.plugins) {
- return 'PluginArray';
- }
- }
-
- if ((typeof window.HTMLElement === 'function' ||
- typeof window.HTMLElement === 'object') &&
- obj instanceof window.HTMLElement) {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
- * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
- * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
- * - IE <=10 === "[object HTMLBlockElement]"
- */
- if (obj.tagName === 'BLOCKQUOTE') {
- return 'HTMLQuoteElement';
- }
-
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#htmltabledatacellelement)
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * Test: Object.prototype.toString.call(document.createElement('td'))
- * - Chrome === "[object HTMLTableCellElement]"
- * - Firefox === "[object HTMLTableCellElement]"
- * - Safari === "[object HTMLTableCellElement]"
- */
- if (obj.tagName === 'TD') {
- return 'HTMLTableDataCellElement';
- }
-
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#htmltableheadercellelement)
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * Test: Object.prototype.toString.call(document.createElement('th'))
- * - Chrome === "[object HTMLTableCellElement]"
- * - Firefox === "[object HTMLTableCellElement]"
- * - Safari === "[object HTMLTableCellElement]"
- */
- if (obj.tagName === 'TH') {
- return 'HTMLTableHeaderCellElement';
- }
- }
- }
-
- /* ! Speed optimisation
- * Pre:
- * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
- * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
- * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
- * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
- * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
- * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
- * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
- * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
- * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
- * Post:
- * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
- * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
- * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
- * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
- * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
- * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
- * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
- * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
- * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
- */
- var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
- if (typeof stringTag === 'string') {
- return stringTag;
- }
-
- var objPrototype = Object.getPrototypeOf(obj);
- /* ! Speed optimisation
- * Pre:
- * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
- * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
- * Post:
- * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
- * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
- */
- if (objPrototype === RegExp.prototype) {
- return 'RegExp';
- }
-
- /* ! Speed optimisation
- * Pre:
- * date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
- * Post:
- * date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
- */
- if (objPrototype === Date.prototype) {
- return 'Date';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
- * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
- * Test: `Object.prototype.toString.call(Promise.resolve())``
- * - Chrome <=47 === "[object Object]"
- * - Edge <=20 === "[object Object]"
- * - Firefox 29-Latest === "[object Promise]"
- * - Safari 7.1-Latest === "[object Promise]"
- */
- if (promiseExists && objPrototype === Promise.prototype) {
- return 'Promise';
- }
-
- /* ! Speed optimisation
- * Pre:
- * set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
- * Post:
- * set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
- */
- if (setExists && objPrototype === Set.prototype) {
- return 'Set';
- }
-
- /* ! Speed optimisation
- * Pre:
- * map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
- * Post:
- * map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
- */
- if (mapExists && objPrototype === Map.prototype) {
- return 'Map';
- }
-
- /* ! Speed optimisation
- * Pre:
- * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
- * Post:
- * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
- */
- if (weakSetExists && objPrototype === WeakSet.prototype) {
- return 'WeakSet';
- }
-
- /* ! Speed optimisation
- * Pre:
- * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
- * Post:
- * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
- */
- if (weakMapExists && objPrototype === WeakMap.prototype) {
- return 'WeakMap';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
- * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
- * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
- * - Edge <=13 === "[object Object]"
- */
- if (dataViewExists && objPrototype === DataView.prototype) {
- return 'DataView';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
- * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
- * Test: `Object.prototype.toString.call(new Map().entries())``
- * - Edge <=13 === "[object Object]"
- */
- if (mapExists && objPrototype === mapIteratorPrototype) {
- return 'Map Iterator';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
- * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
- * Test: `Object.prototype.toString.call(new Set().entries())``
- * - Edge <=13 === "[object Object]"
- */
- if (setExists && objPrototype === setIteratorPrototype) {
- return 'Set Iterator';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
- * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
- * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
- * - Edge <=13 === "[object Object]"
- */
- if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
- return 'Array Iterator';
- }
-
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
- * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
- * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
- * - Edge <=13 === "[object Object]"
- */
- if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
- return 'String Iterator';
- }
-
- /* ! Speed optimisation
- * Pre:
- * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
- * Post:
- * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
- */
- if (objPrototype === null) {
- return 'Object';
- }
-
- return Object
- .prototype
- .toString
- .call(obj)
- .slice(toStringLeftSliceLength, toStringRightSliceLength);
- }
-
- return typeDetect;
-
- })));
- } (typeDetect$1));
- return typeDetect$1.exports;
-}
-
-var typeOf;
-var hasRequiredTypeOf;
-
-function requireTypeOf () {
- if (hasRequiredTypeOf) return typeOf;
- hasRequiredTypeOf = 1;
-
- var type = requireTypeDetect();
-
- /**
- * Returns the lower-case result of running type from type-detect on the value
- * @param {*} value
- * @returns {string}
- */
- typeOf = function typeOf(value) {
- return type(value).toLowerCase();
- };
- return typeOf;
-}
-
-var valueToString_1;
-var hasRequiredValueToString;
-
-function requireValueToString () {
- if (hasRequiredValueToString) return valueToString_1;
- hasRequiredValueToString = 1;
-
- /**
- * Returns a string representation of the value
- * @param {*} value
- * @returns {string}
- */
- function valueToString(value) {
- if (value && value.toString) {
- // eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
- return value.toString();
- }
- return String(value);
- }
-
- valueToString_1 = valueToString;
- return valueToString_1;
-}
-
-var lib;
-var hasRequiredLib;
-
-function requireLib () {
- if (hasRequiredLib) return lib;
- hasRequiredLib = 1;
-
- lib = {
- global: requireGlobal(),
- calledInOrder: requireCalledInOrder(),
- className: requireClassName(),
- deprecated: requireDeprecated(),
- every: requireEvery(),
- functionName: requireFunctionName(),
- orderByFirstCall: requireOrderByFirstCall(),
- prototypes: requirePrototypes(),
- typeOf: requireTypeOf(),
- valueToString: requireValueToString(),
- };
- return lib;
-}
-
-var hasRequiredFakeTimersSrc;
-
-function requireFakeTimersSrc () {
- if (hasRequiredFakeTimersSrc) return fakeTimersSrc;
- hasRequiredFakeTimersSrc = 1;
-
- const globalObject = requireLib().global;
- let timersModule, timersPromisesModule;
- if (typeof __vitest_required__ !== 'undefined') {
- try {
- timersModule = __vitest_required__.timers;
- } catch (e) {
- // ignored
- }
- try {
- timersPromisesModule = __vitest_required__.timersPromises;
- } catch (e) {
- // ignored
- }
- }
-
- /**
- * @typedef {object} IdleDeadline
- * @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
- * @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period
- */
-
- /**
- * Queues a function to be called during a browser's idle periods
- * @callback RequestIdleCallback
- * @param {function(IdleDeadline)} callback
- * @param {{timeout: number}} options - an options object
- * @returns {number} the id
- */
-
- /**
- * @callback NextTick
- * @param {VoidVarArgsFunc} callback - the callback to run
- * @param {...*} args - optional arguments to call the callback with
- * @returns {void}
- */
-
- /**
- * @callback SetImmediate
- * @param {VoidVarArgsFunc} callback - the callback to run
- * @param {...*} args - optional arguments to call the callback with
- * @returns {NodeImmediate}
- */
-
- /**
- * @callback VoidVarArgsFunc
- * @param {...*} callback - the callback to run
- * @returns {void}
- */
-
- /**
- * @typedef RequestAnimationFrame
- * @property {function(number):void} requestAnimationFrame
- * @returns {number} - the id
- */
-
- /**
- * @typedef Performance
- * @property {function(): number} now
- */
-
- /* eslint-disable jsdoc/require-property-description */
- /**
- * @typedef {object} Clock
- * @property {number} now - the current time
- * @property {Date} Date - the Date constructor
- * @property {number} loopLimit - the maximum number of timers before assuming an infinite loop
- * @property {RequestIdleCallback} requestIdleCallback
- * @property {function(number):void} cancelIdleCallback
- * @property {setTimeout} setTimeout
- * @property {clearTimeout} clearTimeout
- * @property {NextTick} nextTick
- * @property {queueMicrotask} queueMicrotask
- * @property {setInterval} setInterval
- * @property {clearInterval} clearInterval
- * @property {SetImmediate} setImmediate
- * @property {function(NodeImmediate):void} clearImmediate
- * @property {function():number} countTimers
- * @property {RequestAnimationFrame} requestAnimationFrame
- * @property {function(number):void} cancelAnimationFrame
- * @property {function():void} runMicrotasks
- * @property {function(string | number): number} tick
- * @property {function(string | number): Promise<number>} tickAsync
- * @property {function(): number} next
- * @property {function(): Promise<number>} nextAsync
- * @property {function(): number} runAll
- * @property {function(): number} runToFrame
- * @property {function(): Promise<number>} runAllAsync
- * @property {function(): number} runToLast
- * @property {function(): Promise<number>} runToLastAsync
- * @property {function(): void} reset
- * @property {function(number | Date): void} setSystemTime
- * @property {function(number): void} jump
- * @property {Performance} performance
- * @property {function(number[]): number[]} hrtime - process.hrtime (legacy)
- * @property {function(): void} uninstall Uninstall the clock.
- * @property {Function[]} methods - the methods that are faked
- * @property {boolean} [shouldClearNativeTimers] inherited from config
- * @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
- * @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods
- * @property {Map<function(): void, AbortSignal>} abortListenerMap
- */
- /* eslint-enable jsdoc/require-property-description */
-
- /**
- * 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)
- * @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)
- * @property {boolean} [ignoreMissingTimers] default is false, meaning asking to fake timers that are not present will throw an error
- */
-
- /* eslint-disable jsdoc/require-property-description */
- /**
- * The internal structure to describe a scheduled fake timer
- * @typedef {object} Timer
- * @property {Function} func
- * @property {*[]} args
- * @property {number} delay
- * @property {number} callAt
- * @property {number} createdAt
- * @property {boolean} immediate
- * @property {number} id
- * @property {Error} [error]
- */
-
- /**
- * A Node timer
- * @typedef {object} NodeImmediate
- * @property {function(): boolean} hasRef
- * @property {function(): NodeImmediate} ref
- * @property {function(): NodeImmediate} unref
- */
- /* eslint-enable jsdoc/require-property-description */
-
- /* eslint-disable complexity */
-
- /**
- * Mocks available features in the specified global namespace.
- * @param {*} _global Namespace to mock (e.g. `window`)
- * @returns {FakeTimers}
- */
- function withGlobal(_global) {
- const maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint
- const idCounterStart = 1e12; // arbitrarily large number to avoid collisions with native timer IDs
- const NOOP = function () {
- return undefined;
- };
- const NOOP_ARRAY = function () {
- return [];
- };
- const isPresent = {};
- let timeoutResult,
- addTimerReturnsObject = false;
-
- if (_global.setTimeout) {
- isPresent.setTimeout = true;
- timeoutResult = _global.setTimeout(NOOP, 0);
- addTimerReturnsObject = typeof timeoutResult === "object";
- }
- isPresent.clearTimeout = Boolean(_global.clearTimeout);
- isPresent.setInterval = Boolean(_global.setInterval);
- isPresent.clearInterval = Boolean(_global.clearInterval);
- isPresent.hrtime =
- _global.process && typeof _global.process.hrtime === "function";
- isPresent.hrtimeBigint =
- isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
- isPresent.nextTick =
- _global.process && typeof _global.process.nextTick === "function";
- const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify;
- isPresent.performance =
- _global.performance && typeof _global.performance.now === "function";
- const hasPerformancePrototype =
- _global.Performance &&
- (typeof _global.Performance).match(/^(function|object)$/);
- const hasPerformanceConstructorPrototype =
- _global.performance &&
- _global.performance.constructor &&
- _global.performance.constructor.prototype;
- isPresent.queueMicrotask = _global.hasOwnProperty("queueMicrotask");
- isPresent.requestAnimationFrame =
- _global.requestAnimationFrame &&
- typeof _global.requestAnimationFrame === "function";
- isPresent.cancelAnimationFrame =
- _global.cancelAnimationFrame &&
- typeof _global.cancelAnimationFrame === "function";
- isPresent.requestIdleCallback =
- _global.requestIdleCallback &&
- typeof _global.requestIdleCallback === "function";
- isPresent.cancelIdleCallbackPresent =
- _global.cancelIdleCallback &&
- typeof _global.cancelIdleCallback === "function";
- isPresent.setImmediate =
- _global.setImmediate && typeof _global.setImmediate === "function";
- isPresent.clearImmediate =
- _global.clearImmediate && typeof _global.clearImmediate === "function";
- isPresent.Intl = _global.Intl && typeof _global.Intl === "object";
-
- if (_global.clearTimeout) {
- _global.clearTimeout(timeoutResult);
- }
-
- const NativeDate = _global.Date;
- const NativeIntl = isPresent.Intl
- ? Object.defineProperties(
- Object.create(null),
- Object.getOwnPropertyDescriptors(_global.Intl),
- )
- : undefined;
- let uniqueTimerId = idCounterStart;
-
- if (NativeDate === undefined) {
- throw new Error(
- "The global scope doesn't have a `Date` object" +
- " (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)",
- );
- }
- isPresent.Date = true;
-
- /**
- * The PerformanceEntry object encapsulates a single performance metric
- * that is part of the browser's performance timeline.
- *
- * This is an object returned by the `mark` and `measure` methods on the Performance prototype
- */
- class FakePerformanceEntry {
- constructor(name, entryType, startTime, duration) {
- this.name = name;
- this.entryType = entryType;
- this.startTime = startTime;
- this.duration = duration;
- }
-
- toJSON() {
- return JSON.stringify({ ...this });
- }
- }
-
- /**
- * @param {number} num
- * @returns {boolean}
- */
- function isNumberFinite(num) {
- if (Number.isFinite) {
- return Number.isFinite(num);
- }
-
- return isFinite(num);
- }
-
- let isNearInfiniteLimit = false;
-
- /**
- * @param {Clock} clock
- * @param {number} i
- */
- function checkIsNearInfiniteLimit(clock, i) {
- if (clock.loopLimit && i === clock.loopLimit - 1) {
- isNearInfiniteLimit = true;
- }
- }
-
- /**
- *
- */
- function resetIsNearInfiniteLimit() {
- isNearInfiniteLimit = false;
- }
-
- /**
- * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
- * number of milliseconds. This is used to support human-readable strings passed
- * to clock.tick()
- * @param {string} str
- * @returns {number}
- */
- function parseTime(str) {
- if (!str) {
- return 0;
- }
-
- const strings = str.split(":");
- const l = strings.length;
- let i = l;
- let ms = 0;
- let parsed;
-
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
- throw new Error(
- "tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits",
- );
- }
-
- while (i--) {
- parsed = parseInt(strings[i], 10);
-
- if (parsed >= 60) {
- throw new Error(`Invalid time ${str}`);
- }
-
- ms += parsed * Math.pow(60, l - i - 1);
- }
-
- return ms * 1000;
- }
-
- /**
- * 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)
- *
- * Example: nanoRemainer(123.456789) -> 456789
- */
- function nanoRemainder(msFloat) {
- const modulo = 1e6;
- const remainder = (msFloat * 1e6) % modulo;
- const positiveRemainder =
- remainder < 0 ? remainder + modulo : remainder;
-
- return Math.floor(positiveRemainder);
- }
-
- /**
- * Used to grok the `now` parameter to createClock.
- * @param {Date|number} epoch the system time
- * @returns {number}
- */
- function getEpoch(epoch) {
- if (!epoch) {
- return 0;
- }
- if (typeof epoch.getTime === "function") {
- return epoch.getTime();
- }
- if (typeof epoch === "number") {
- return epoch;
- }
- throw new TypeError("now should be milliseconds since UNIX epoch");
- }
-
- /**
- * @param {number} from
- * @param {number} to
- * @param {Timer} timer
- * @returns {boolean}
- */
- function inRange(from, to, timer) {
- return timer && timer.callAt >= from && timer.callAt <= to;
- }
-
- /**
- * @param {Clock} clock
- * @param {Timer} job
- */
- function getInfiniteLoopError(clock, job) {
- const infiniteLoopError = new Error(
- `Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`,
- );
-
- if (!job.error) {
- return infiniteLoopError;
- }
-
- // pattern never matched in Node
- const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/;
- let clockMethodPattern = new RegExp(
- String(Object.keys(clock).join("|")),
- );
-
- if (addTimerReturnsObject) {
- // node.js environment
- clockMethodPattern = new RegExp(
- `\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`,
- );
- }
-
- let matchedLineIndex = -1;
- job.error.stack.split("\n").some(function (line, i) {
- // If we've matched a computed target line (e.g. setTimeout) then we
- // don't need to look any further. Return true to stop iterating.
- const matchedComputedTarget = line.match(computedTargetPattern);
- /* istanbul ignore if */
- if (matchedComputedTarget) {
- matchedLineIndex = i;
- return true;
- }
-
- // If we've matched a clock method line, then there may still be
- // others further down the trace. Return false to keep iterating.
- const matchedClockMethod = line.match(clockMethodPattern);
- if (matchedClockMethod) {
- matchedLineIndex = i;
- return false;
- }
-
- // If we haven't matched anything on this line, but we matched
- // previously and set the matched line index, then we can stop.
- // If we haven't matched previously, then we should keep iterating.
- return matchedLineIndex >= 0;
- });
-
- const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${
- job.func.name || "anonymous"
- }\n${job.error.stack
- .split("\n")
- .slice(matchedLineIndex + 1)
- .join("\n")}`;
-
- try {
- Object.defineProperty(infiniteLoopError, "stack", {
- value: stack,
- });
- } catch (e) {
- // noop
- }
-
- return infiniteLoopError;
- }
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function createDate() {
- class ClockDate extends NativeDate {
- /**
- * @param {number} year
- * @param {number} month
- * @param {number} date
- * @param {number} hour
- * @param {number} minute
- * @param {number} second
- * @param {number} ms
- * @returns void
- */
- // eslint-disable-next-line no-unused-vars
- constructor(year, month, date, hour, minute, second, ms) {
- // Defensive and verbose to avoid potential harm in passing
- // explicit undefined when user does not pass argument
- if (arguments.length === 0) {
- super(ClockDate.clock.now);
- } else {
- super(...arguments);
- }
-
- // ensures identity checks using the constructor prop still works
- // this should have no other functional effect
- Object.defineProperty(this, "constructor", {
- value: NativeDate,
- enumerable: false,
- });
- }
-
- static [Symbol.hasInstance](instance) {
- return instance instanceof NativeDate;
- }
- }
-
- ClockDate.isFake = true;
-
- if (NativeDate.now) {
- ClockDate.now = function now() {
- return ClockDate.clock.now;
- };
- }
-
- if (NativeDate.toSource) {
- ClockDate.toSource = function toSource() {
- return NativeDate.toSource();
- };
- }
-
- ClockDate.toString = function toString() {
- return NativeDate.toString();
- };
-
- // noinspection UnnecessaryLocalVariableJS
- /**
- * A normal Class constructor cannot be called without `new`, but Date can, so we need
- * to wrap it in a Proxy in order to ensure this functionality of Date is kept intact
- * @type {ClockDate}
- */
- const ClockDateProxy = new Proxy(ClockDate, {
- // handler for [[Call]] invocations (i.e. not using `new`)
- apply() {
- // the Date constructor called as a function, ref Ecma-262 Edition 5.1, section 15.9.2.
- // This remains so in the 10th edition of 2019 as well.
- if (this instanceof ClockDate) {
- throw new TypeError(
- "A Proxy should only capture `new` calls with the `construct` handler. This is not supposed to be possible, so check the logic.",
- );
- }
-
- return new NativeDate(ClockDate.clock.now).toString();
- },
- });
-
- return ClockDateProxy;
- }
-
- /**
- * Mirror Intl by default on our fake implementation
- *
- * Most of the properties are the original native ones,
- * but we need to take control of those that have a
- * dependency on the current clock.
- * @returns {object} the partly fake Intl implementation
- */
- function createIntl() {
- const ClockIntl = {};
- /*
- * All properties of Intl are non-enumerable, so we need
- * to do a bit of work to get them out.
- */
- Object.getOwnPropertyNames(NativeIntl).forEach(
- (property) => (ClockIntl[property] = NativeIntl[property]),
- );
-
- ClockIntl.DateTimeFormat = function (...args) {
- const realFormatter = new NativeIntl.DateTimeFormat(...args);
- const formatter = {};
-
- ["formatRange", "formatRangeToParts", "resolvedOptions"].forEach(
- (method) => {
- formatter[method] =
- realFormatter[method].bind(realFormatter);
- },
- );
-
- ["format", "formatToParts"].forEach((method) => {
- formatter[method] = function (date) {
- return realFormatter[method](date || ClockIntl.clock.now);
- };
- });
-
- return formatter;
- };
-
- ClockIntl.DateTimeFormat.prototype = Object.create(
- NativeIntl.DateTimeFormat.prototype,
- );
-
- ClockIntl.DateTimeFormat.supportedLocalesOf =
- NativeIntl.DateTimeFormat.supportedLocalesOf;
-
- return ClockIntl;
- }
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function enqueueJob(clock, job) {
- // enqueues a microtick-deferred task - ecma262/#sec-enqueuejob
- if (!clock.jobs) {
- clock.jobs = [];
- }
- clock.jobs.push(job);
- }
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function runJobs(clock) {
- // runs all microtick-deferred tasks - ecma262/#sec-runjobs
- if (!clock.jobs) {
- return;
- }
- for (let i = 0; i < clock.jobs.length; i++) {
- const job = clock.jobs[i];
- job.func.apply(null, job.args);
-
- checkIsNearInfiniteLimit(clock, i);
- if (clock.loopLimit && i > clock.loopLimit) {
- throw getInfiniteLoopError(clock, job);
- }
- }
- resetIsNearInfiniteLimit();
- clock.jobs = [];
- }
-
- /**
- * @param {Clock} clock
- * @param {Timer} timer
- * @returns {number} id of the created timer
- */
- function addTimer(clock, timer) {
- if (timer.func === undefined) {
- 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}`,
- );
- }
- }
-
- if (isNearInfiniteLimit) {
- timer.error = new Error();
- }
-
- 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;
- }
- timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
- timer.delay = Math.max(0, timer.delay);
- }
-
- if (timer.hasOwnProperty("interval")) {
- timer.type = "Interval";
- timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
- }
-
- if (timer.hasOwnProperty("animation")) {
- timer.type = "AnimationFrame";
- timer.animation = true;
- }
-
- if (timer.hasOwnProperty("idleCallback")) {
- timer.type = "IdleCallback";
- timer.idleCallback = true;
- }
-
- if (!clock.timers) {
- clock.timers = {};
- }
-
- timer.id = uniqueTimerId++;
- timer.createdAt = clock.now;
- timer.callAt =
- clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
-
- clock.timers[timer.id] = timer;
-
- if (addTimerReturnsObject) {
- const res = {
- refed: true,
- ref: function () {
- this.refed = true;
- return res;
- },
- unref: function () {
- this.refed = false;
- return res;
- },
- hasRef: function () {
- return this.refed;
- },
- refresh: function () {
- timer.callAt =
- clock.now +
- (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
-
- // it _might_ have been removed, but if not the assignment is perfectly fine
- clock.timers[timer.id] = timer;
-
- return res;
- },
- [Symbol.toPrimitive]: function () {
- return timer.id;
- },
- };
- return res;
- }
-
- return timer.id;
- }
-
- /* eslint consistent-return: "off" */
- /**
- * Timer comparitor
- * @param {Timer} a
- * @param {Timer} b
- * @returns {number}
- */
- function compareTimers(a, b) {
- // Sort first by absolute timing
- if (a.callAt < b.callAt) {
- return -1;
- }
- if (a.callAt > b.callAt) {
- return 1;
- }
-
- // Sort next by immediate, immediate timers take precedence
- if (a.immediate && !b.immediate) {
- return -1;
- }
- if (!a.immediate && b.immediate) {
- return 1;
- }
-
- // Sort next by creation time, earlier-created timers take precedence
- if (a.createdAt < b.createdAt) {
- return -1;
- }
- if (a.createdAt > b.createdAt) {
- return 1;
- }
-
- // Sort next by id, lower-id timers take precedence
- if (a.id < b.id) {
- return -1;
- }
- if (a.id > b.id) {
- return 1;
- }
-
- // As timer ids are unique, no fallback `0` is necessary
- }
-
- /**
- * @param {Clock} clock
- * @param {number} from
- * @param {number} to
- * @returns {Timer}
- */
- function firstTimerInRange(clock, from, to) {
- const timers = clock.timers;
- let timer = null;
- let id, isInRange;
-
- for (id in timers) {
- if (timers.hasOwnProperty(id)) {
- isInRange = inRange(from, to, timers[id]);
-
- if (
- isInRange &&
- (!timer || compareTimers(timer, timers[id]) === 1)
- ) {
- timer = timers[id];
- }
- }
- }
-
- return timer;
- }
-
- /**
- * @param {Clock} clock
- * @returns {Timer}
- */
- function firstTimer(clock) {
- const timers = clock.timers;
- let timer = null;
- let id;
-
- for (id in timers) {
- if (timers.hasOwnProperty(id)) {
- if (!timer || compareTimers(timer, timers[id]) === 1) {
- timer = timers[id];
- }
- }
- }
-
- return timer;
- }
-
- /**
- * @param {Clock} clock
- * @returns {Timer}
- */
- function lastTimer(clock) {
- const timers = clock.timers;
- let timer = null;
- let id;
-
- for (id in timers) {
- if (timers.hasOwnProperty(id)) {
- if (!timer || compareTimers(timer, timers[id]) === -1) {
- timer = timers[id];
- }
- }
- }
-
- return timer;
- }
-
- /**
- * @param {Clock} clock
- * @param {Timer} timer
- */
- function callTimer(clock, timer) {
- if (typeof timer.interval === "number") {
- clock.timers[timer.id].callAt += timer.interval;
- } else {
- delete clock.timers[timer.id];
- }
-
- if (typeof timer.func === "function") {
- timer.func.apply(null, timer.args);
- } else {
- /* eslint no-eval: "off" */
- const eval2 = eval;
- (function () {
- eval2(timer.func);
- })();
- }
- }
-
- /**
- * Gets clear handler name for a given timer type
- * @param {string} ttype
- */
- function getClearHandler(ttype) {
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") {
- return `cancel${ttype}`;
- }
- return `clear${ttype}`;
- }
-
- /**
- * Gets schedule handler name for a given timer type
- * @param {string} ttype
- */
- function getScheduleHandler(ttype) {
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") {
- return `request${ttype}`;
- }
- return `set${ttype}`;
- }
-
- /**
- * Creates an anonymous function to warn only once
- */
- function createWarnOnce() {
- let calls = 0;
- return function (msg) {
- // eslint-disable-next-line
- !calls++ && console.warn(msg);
- };
- }
- const warnOnce = createWarnOnce();
-
- /**
- * @param {Clock} clock
- * @param {number} timerId
- * @param {string} ttype
- */
- function clearTimer(clock, timerId, ttype) {
- if (!timerId) {
- // null appears to be allowed in most browsers, and appears to be
- // relied upon by some libraries, like Bootstrap carousel
- return;
- }
-
- if (!clock.timers) {
- clock.timers = {};
- }
-
- // in Node, the ID is stored as the primitive value for `Timeout` objects
- // for `Immediate` objects, no ID exists, so it gets coerced to NaN
- const id = Number(timerId);
-
- if (Number.isNaN(id) || id < idCounterStart) {
- const handlerName = getClearHandler(ttype);
-
- if (clock.shouldClearNativeTimers === true) {
- const nativeHandler = clock[`_${handlerName}`];
- return typeof nativeHandler === "function"
- ? nativeHandler(timerId)
- : undefined;
- }
- warnOnce(
- `FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.` +
- "\nTo automatically clean-up native timers, use `shouldClearNativeTimers`.",
- );
- }
-
- if (clock.timers.hasOwnProperty(id)) {
- // check that the ID matches a timer of the correct type
- const timer = clock.timers[id];
- if (
- timer.type === ttype ||
- (timer.type === "Timeout" && ttype === "Interval") ||
- (timer.type === "Interval" && ttype === "Timeout")
- ) {
- delete clock.timers[id];
- } else {
- const clear = getClearHandler(ttype);
- const schedule = getScheduleHandler(timer.type);
- throw new Error(
- `Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`,
- );
- }
- }
- }
-
- /**
- * @param {Clock} clock
- * @param {Config} config
- * @returns {Timer[]}
- */
- function uninstall(clock, config) {
- let method, i, l;
- const installedHrTime = "_hrtime";
- const installedNextTick = "_nextTick";
-
- for (i = 0, l = clock.methods.length; i < l; i++) {
- method = clock.methods[i];
- 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") {
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(
- clock,
- `_${method}`,
- );
- if (
- originalPerfDescriptor &&
- originalPerfDescriptor.get &&
- !originalPerfDescriptor.set
- ) {
- Object.defineProperty(
- _global,
- method,
- originalPerfDescriptor,
- );
- } else if (originalPerfDescriptor.configurable) {
- _global[method] = clock[`_${method}`];
- }
- } else {
- if (_global[method] && _global[method].hadOwnProperty) {
- _global[method] = clock[`_${method}`];
- } else {
- try {
- delete _global[method];
- } catch (ignore) {
- /* eslint no-empty: "off" */
- }
- }
- }
- if (clock.timersModuleMethods !== undefined) {
- for (let j = 0; j < clock.timersModuleMethods.length; j++) {
- const entry = clock.timersModuleMethods[j];
- timersModule[entry.methodName] = entry.original;
- }
- }
- if (clock.timersPromisesModuleMethods !== undefined) {
- for (
- let j = 0;
- j < clock.timersPromisesModuleMethods.length;
- j++
- ) {
- const entry = clock.timersPromisesModuleMethods[j];
- timersPromisesModule[entry.methodName] = entry.original;
- }
- }
- }
-
- if (config.shouldAdvanceTime === true) {
- _global.clearInterval(clock.attachedInterval);
- }
-
- // Prevent multiple executions which will completely remove these props
- clock.methods = [];
-
- for (const [listener, signal] of clock.abortListenerMap.entries()) {
- signal.removeEventListener("abort", listener);
- clock.abortListenerMap.delete(listener);
- }
-
- // return pending timers, to enable checking what timers remained on uninstall
- if (!clock.timers) {
- return [];
- }
- return Object.keys(clock.timers).map(function mapper(key) {
- return clock.timers[key];
- });
- }
-
- /**
- * @param {object} target the target containing the method to replace
- * @param {string} method the keyname of the method on the target
- * @param {Clock} clock
- */
- function hijackMethod(target, method, clock) {
- clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(
- target,
- method,
- );
- clock[`_${method}`] = target[method];
-
- if (method === "Date") {
- target[method] = clock[method];
- } else if (method === "Intl") {
- target[method] = clock[method];
- } else if (method === "performance") {
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(
- target,
- method,
- );
- // JSDOM has a read only performance field so we have to save/copy it differently
- if (
- originalPerfDescriptor &&
- originalPerfDescriptor.get &&
- !originalPerfDescriptor.set
- ) {
- Object.defineProperty(
- clock,
- `_${method}`,
- originalPerfDescriptor,
- );
-
- const perfDescriptor = Object.getOwnPropertyDescriptor(
- clock,
- method,
- );
- Object.defineProperty(target, method, perfDescriptor);
- } else {
- target[method] = clock[method];
- }
- } else {
- target[method] = function () {
- return clock[method].apply(clock, arguments);
- };
-
- Object.defineProperties(
- target[method],
- Object.getOwnPropertyDescriptors(clock[method]),
- );
- }
-
- target[method].clock = clock;
- }
-
- /**
- * @param {Clock} clock
- * @param {number} advanceTimeDelta
- */
- function doIntervalTick(clock, advanceTimeDelta) {
- clock.tick(advanceTimeDelta);
- }
-
- /**
- * @typedef {object} Timers
- * @property {setTimeout} setTimeout
- * @property {clearTimeout} clearTimeout
- * @property {setInterval} setInterval
- * @property {clearInterval} clearInterval
- * @property {Date} Date
- * @property {Intl} Intl
- * @property {SetImmediate=} setImmediate
- * @property {function(NodeImmediate): void=} clearImmediate
- * @property {function(number[]):number[]=} hrtime
- * @property {NextTick=} nextTick
- * @property {Performance=} performance
- * @property {RequestAnimationFrame=} requestAnimationFrame
- * @property {boolean=} queueMicrotask
- * @property {function(number): void=} cancelAnimationFrame
- * @property {RequestIdleCallback=} requestIdleCallback
- * @property {function(number): void=} cancelIdleCallback
- */
-
- /** @type {Timers} */
- const timers = {
- setTimeout: _global.setTimeout,
- clearTimeout: _global.clearTimeout,
- setInterval: _global.setInterval,
- clearInterval: _global.clearInterval,
- Date: _global.Date,
- };
-
- if (isPresent.setImmediate) {
- timers.setImmediate = _global.setImmediate;
- }
-
- if (isPresent.clearImmediate) {
- timers.clearImmediate = _global.clearImmediate;
- }
-
- if (isPresent.hrtime) {
- timers.hrtime = _global.process.hrtime;
- }
-
- if (isPresent.nextTick) {
- timers.nextTick = _global.process.nextTick;
- }
-
- if (isPresent.performance) {
- timers.performance = _global.performance;
- }
-
- if (isPresent.requestAnimationFrame) {
- timers.requestAnimationFrame = _global.requestAnimationFrame;
- }
-
- if (isPresent.queueMicrotask) {
- timers.queueMicrotask = _global.queueMicrotask;
- }
-
- if (isPresent.cancelAnimationFrame) {
- timers.cancelAnimationFrame = _global.cancelAnimationFrame;
- }
-
- if (isPresent.requestIdleCallback) {
- timers.requestIdleCallback = _global.requestIdleCallback;
- }
-
- if (isPresent.cancelIdleCallback) {
- timers.cancelIdleCallback = _global.cancelIdleCallback;
- }
-
- if (isPresent.Intl) {
- timers.Intl = NativeIntl;
- }
-
- const originalSetTimeout = _global.setImmediate || _global.setTimeout;
-
- /**
- * @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
- start = Math.floor(getEpoch(start));
- // eslint-disable-next-line no-param-reassign
- loopLimit = loopLimit || 1000;
- let nanos = 0;
- const adjustedSystemTime = [0, 0]; // [millis, nanoremainder]
-
- const clock = {
- now: start,
- Date: createDate(),
- loopLimit: loopLimit,
- };
-
- clock.Date.clock = clock;
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function getTimeToNextFrame() {
- return 16 - ((clock.now - start) % 16);
- }
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function hrtime(prev) {
- const millisSinceStart = clock.now - adjustedSystemTime[0] - start;
- const secsSinceStart = Math.floor(millisSinceStart / 1000);
- const remainderInNanos =
- (millisSinceStart - secsSinceStart * 1e3) * 1e6 +
- nanos -
- adjustedSystemTime[1];
-
- if (Array.isArray(prev)) {
- if (prev[1] > 1e9) {
- throw new TypeError(
- "Number of nanoseconds can't exceed a billion",
- );
- }
-
- const oldSecs = prev[0];
- let nanoDiff = remainderInNanos - prev[1];
- let secDiff = secsSinceStart - oldSecs;
-
- if (nanoDiff < 0) {
- nanoDiff += 1e9;
- secDiff -= 1;
- }
-
- return [secDiff, nanoDiff];
- }
- return [secsSinceStart, remainderInNanos];
- }
-
- /**
- * A high resolution timestamp in milliseconds.
- * @typedef {number} DOMHighResTimeStamp
- */
-
- /**
- * performance.now()
- * @returns {DOMHighResTimeStamp}
- */
- function fakePerformanceNow() {
- const hrt = hrtime();
- const millis = hrt[0] * 1000 + hrt[1] / 1e6;
- return millis;
- }
-
- if (isPresent.hrtimeBigint) {
- hrtime.bigint = function () {
- const parts = hrtime();
- return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line
- };
- }
-
- if (isPresent.Intl) {
- clock.Intl = createIntl();
- clock.Intl.clock = clock;
- }
-
- clock.requestIdleCallback = function requestIdleCallback(
- func,
- timeout,
- ) {
- let timeToNextIdlePeriod = 0;
-
- if (clock.countTimers() > 0) {
- timeToNextIdlePeriod = 50; // const for now
- }
-
- const result = addTimer(clock, {
- func: func,
- args: Array.prototype.slice.call(arguments, 2),
- delay:
- typeof timeout === "undefined"
- ? timeToNextIdlePeriod
- : Math.min(timeout, timeToNextIdlePeriod),
- idleCallback: true,
- });
-
- return Number(result);
- };
-
- clock.cancelIdleCallback = function cancelIdleCallback(timerId) {
- return clearTimer(clock, timerId, "IdleCallback");
- };
-
- clock.setTimeout = function setTimeout(func, timeout) {
- return addTimer(clock, {
- func: func,
- args: Array.prototype.slice.call(arguments, 2),
- delay: timeout,
- });
- };
- if (typeof _global.Promise !== "undefined" && utilPromisify) {
- clock.setTimeout[utilPromisify.custom] =
- function promisifiedSetTimeout(timeout, arg) {
- return new _global.Promise(function setTimeoutExecutor(
- resolve,
- ) {
- addTimer(clock, {
- func: resolve,
- args: [arg],
- delay: timeout,
- });
- });
- };
- }
-
- clock.clearTimeout = function clearTimeout(timerId) {
- return clearTimer(clock, timerId, "Timeout");
- };
-
- clock.nextTick = function nextTick(func) {
- return enqueueJob(clock, {
- func: func,
- args: Array.prototype.slice.call(arguments, 1),
- error: isNearInfiniteLimit ? new Error() : null,
- });
- };
-
- clock.queueMicrotask = function queueMicrotask(func) {
- return clock.nextTick(func); // explicitly drop additional arguments
- };
-
- clock.setInterval = function setInterval(func, timeout) {
- // eslint-disable-next-line no-param-reassign
- timeout = parseInt(timeout, 10);
- return addTimer(clock, {
- func: func,
- args: Array.prototype.slice.call(arguments, 2),
- delay: timeout,
- interval: timeout,
- });
- };
-
- clock.clearInterval = function clearInterval(timerId) {
- return clearTimer(clock, timerId, "Interval");
- };
-
- if (isPresent.setImmediate) {
- clock.setImmediate = function setImmediate(func) {
- return addTimer(clock, {
- func: func,
- args: Array.prototype.slice.call(arguments, 1),
- immediate: true,
- });
- };
-
- if (typeof _global.Promise !== "undefined" && utilPromisify) {
- clock.setImmediate[utilPromisify.custom] =
- function promisifiedSetImmediate(arg) {
- return new _global.Promise(
- function setImmediateExecutor(resolve) {
- addTimer(clock, {
- func: resolve,
- args: [arg],
- immediate: true,
- });
- },
- );
- };
- }
-
- clock.clearImmediate = function clearImmediate(timerId) {
- return clearTimer(clock, timerId, "Immediate");
- };
- }
-
- clock.countTimers = function countTimers() {
- return (
- Object.keys(clock.timers || {}).length +
- (clock.jobs || []).length
- );
- };
-
- clock.requestAnimationFrame = function requestAnimationFrame(func) {
- const result = addTimer(clock, {
- func: func,
- delay: getTimeToNextFrame(),
- get args() {
- return [fakePerformanceNow()];
- },
- animation: true,
- });
-
- return Number(result);
- };
-
- clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
- return clearTimer(clock, timerId, "AnimationFrame");
- };
-
- clock.runMicrotasks = function runMicrotasks() {
- runJobs(clock);
- };
-
- /**
- * @param {number|string} tickValue milliseconds or a string parseable by parseTime
- * @param {boolean} isAsync
- * @param {Function} resolve
- * @param {Function} reject
- * @returns {number|undefined} will return the new `now` value or nothing for async
- */
- function doTick(tickValue, isAsync, resolve, reject) {
- const msFloat =
- typeof tickValue === "number"
- ? tickValue
- : parseTime(tickValue);
- const ms = Math.floor(msFloat);
- const remainder = nanoRemainder(msFloat);
- let nanosTotal = nanos + remainder;
- let tickTo = clock.now + ms;
-
- if (msFloat < 0) {
- throw new TypeError("Negative ticks are not supported");
- }
-
- // adjust for positive overflow
- if (nanosTotal >= 1e6) {
- tickTo += 1;
- nanosTotal -= 1e6;
- }
-
- nanos = nanosTotal;
- let tickFrom = clock.now;
- let previous = clock.now;
- // ESLint fails to detect this correctly
- /* eslint-disable prefer-const */
- let timer,
- firstException,
- oldNow,
- nextPromiseTick,
- compensationCheck,
- postTimerCall;
- /* eslint-enable prefer-const */
-
- clock.duringTick = true;
-
- // perform microtasks
- oldNow = clock.now;
- runJobs(clock);
- if (oldNow !== clock.now) {
- // compensate for any setSystemTime() call during microtask callback
- tickFrom += clock.now - oldNow;
- tickTo += clock.now - oldNow;
- }
-
- //eslint-disable-next-line jsdoc/require-jsdoc
- function doTickInner() {
- // perform each timer in the requested range
- timer = firstTimerInRange(clock, tickFrom, tickTo);
- // eslint-disable-next-line no-unmodified-loop-condition
- while (timer && tickFrom <= tickTo) {
- if (clock.timers[timer.id]) {
- tickFrom = timer.callAt;
- clock.now = timer.callAt;
- oldNow = clock.now;
- try {
- runJobs(clock);
- callTimer(clock, timer);
- } catch (e) {
- firstException = firstException || e;
- }
-
- if (isAsync) {
- // finish up after native setImmediate callback to allow
- // all native es6 promises to process their callbacks after
- // each timer fires.
- originalSetTimeout(nextPromiseTick);
- return;
- }
-
- compensationCheck();
- }
-
- postTimerCall();
- }
-
- // perform process.nextTick()s again
- oldNow = clock.now;
- runJobs(clock);
- if (oldNow !== clock.now) {
- // compensate for any setSystemTime() call during process.nextTick() callback
- tickFrom += clock.now - oldNow;
- tickTo += clock.now - oldNow;
- }
- clock.duringTick = false;
-
- // corner case: during runJobs new timers were scheduled which could be in the range [clock.now, tickTo]
- timer = firstTimerInRange(clock, tickFrom, tickTo);
- if (timer) {
- try {
- clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range
- } catch (e) {
- firstException = firstException || e;
- }
- } else {
- // no timers remaining in the requested range: move the clock all the way to the end
- clock.now = tickTo;
-
- // update nanos
- nanos = nanosTotal;
- }
- if (firstException) {
- throw firstException;
- }
-
- if (isAsync) {
- resolve(clock.now);
- } else {
- return clock.now;
- }
- }
-
- nextPromiseTick =
- isAsync &&
- function () {
- try {
- compensationCheck();
- postTimerCall();
- doTickInner();
- } catch (e) {
- reject(e);
- }
- };
-
- compensationCheck = function () {
- // compensate for any setSystemTime() call during timer callback
- if (oldNow !== clock.now) {
- tickFrom += clock.now - oldNow;
- tickTo += clock.now - oldNow;
- previous += clock.now - oldNow;
- }
- };
-
- postTimerCall = function () {
- timer = firstTimerInRange(clock, previous, tickTo);
- previous = tickFrom;
- };
-
- return doTickInner();
- }
-
- /**
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
- * @returns {number} will return the new `now` value
- */
- clock.tick = function tick(tickValue) {
- return doTick(tickValue, false);
- };
-
- if (typeof _global.Promise !== "undefined") {
- /**
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
- * @returns {Promise}
- */
- clock.tickAsync = function tickAsync(tickValue) {
- return new _global.Promise(function (resolve, reject) {
- originalSetTimeout(function () {
- try {
- doTick(tickValue, true, resolve, reject);
- } catch (e) {
- reject(e);
- }
- });
- });
- };
- }
-
- clock.next = function next() {
- runJobs(clock);
- const timer = firstTimer(clock);
- if (!timer) {
- return clock.now;
- }
-
- clock.duringTick = true;
- try {
- clock.now = timer.callAt;
- callTimer(clock, timer);
- runJobs(clock);
- return clock.now;
- } finally {
- clock.duringTick = false;
- }
- };
-
- if (typeof _global.Promise !== "undefined") {
- clock.nextAsync = function nextAsync() {
- return new _global.Promise(function (resolve, reject) {
- originalSetTimeout(function () {
- try {
- const timer = firstTimer(clock);
- if (!timer) {
- resolve(clock.now);
- return;
- }
-
- let err;
- clock.duringTick = true;
- clock.now = timer.callAt;
- try {
- callTimer(clock, timer);
- } catch (e) {
- err = e;
- }
- clock.duringTick = false;
-
- originalSetTimeout(function () {
- if (err) {
- reject(err);
- } else {
- resolve(clock.now);
- }
- });
- } catch (e) {
- reject(e);
- }
- });
- });
- };
- }
-
- clock.runAll = function runAll() {
- let numTimers, i;
- runJobs(clock);
- for (i = 0; i < clock.loopLimit; i++) {
- if (!clock.timers) {
- resetIsNearInfiniteLimit();
- return clock.now;
- }
-
- numTimers = Object.keys(clock.timers).length;
- if (numTimers === 0) {
- resetIsNearInfiniteLimit();
- return clock.now;
- }
-
- clock.next();
- checkIsNearInfiniteLimit(clock, i);
- }
-
- const excessJob = firstTimer(clock);
- throw getInfiniteLoopError(clock, excessJob);
- };
-
- clock.runToFrame = function runToFrame() {
- return clock.tick(getTimeToNextFrame());
- };
-
- if (typeof _global.Promise !== "undefined") {
- clock.runAllAsync = function runAllAsync() {
- return new _global.Promise(function (resolve, reject) {
- let i = 0;
- /**
- *
- */
- function doRun() {
- originalSetTimeout(function () {
- try {
- runJobs(clock);
-
- let numTimers;
- if (i < clock.loopLimit) {
- if (!clock.timers) {
- resetIsNearInfiniteLimit();
- resolve(clock.now);
- return;
- }
-
- numTimers = Object.keys(
- clock.timers,
- ).length;
- if (numTimers === 0) {
- resetIsNearInfiniteLimit();
- resolve(clock.now);
- return;
- }
-
- clock.next();
-
- i++;
-
- doRun();
- checkIsNearInfiniteLimit(clock, i);
- return;
- }
-
- const excessJob = firstTimer(clock);
- reject(getInfiniteLoopError(clock, excessJob));
- } catch (e) {
- reject(e);
- }
- });
- }
- doRun();
- });
- };
- }
-
- clock.runToLast = function runToLast() {
- const timer = lastTimer(clock);
- if (!timer) {
- runJobs(clock);
- return clock.now;
- }
-
- return clock.tick(timer.callAt - clock.now);
- };
-
- if (typeof _global.Promise !== "undefined") {
- clock.runToLastAsync = function runToLastAsync() {
- return new _global.Promise(function (resolve, reject) {
- originalSetTimeout(function () {
- try {
- const timer = lastTimer(clock);
- if (!timer) {
- runJobs(clock);
- resolve(clock.now);
- }
-
- resolve(clock.tickAsync(timer.callAt - clock.now));
- } catch (e) {
- reject(e);
- }
- });
- });
- };
- }
-
- clock.reset = function reset() {
- nanos = 0;
- clock.timers = {};
- clock.jobs = [];
- clock.now = start;
- };
-
- clock.setSystemTime = function setSystemTime(systemTime) {
- // determine time difference
- const newNow = getEpoch(systemTime);
- const difference = newNow - clock.now;
- let id, timer;
-
- adjustedSystemTime[0] = adjustedSystemTime[0] + difference;
- adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;
- // update 'system clock'
- clock.now = newNow;
- nanos = 0;
-
- // update timers and intervals to keep them stable
- for (id in clock.timers) {
- if (clock.timers.hasOwnProperty(id)) {
- timer = clock.timers[id];
- timer.createdAt += difference;
- timer.callAt += difference;
- }
- }
- };
-
- /**
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
- * @returns {number} will return the new `now` value
- */
- clock.jump = function jump(tickValue) {
- const msFloat =
- typeof tickValue === "number"
- ? tickValue
- : parseTime(tickValue);
- const ms = Math.floor(msFloat);
-
- for (const timer of Object.values(clock.timers)) {
- if (clock.now + ms > timer.callAt) {
- timer.callAt = clock.now + ms;
- }
- }
- clock.tick(ms);
- };
-
- if (isPresent.performance) {
- clock.performance = Object.create(null);
- clock.performance.now = fakePerformanceNow;
- }
-
- if (isPresent.hrtime) {
- clock.hrtime = hrtime;
- }
-
- return clock;
- }
-
- /* eslint-disable complexity */
-
- /**
- * @param {Config=} [config] Optional config
- * @returns {Clock}
- */
- function install(config) {
- if (
- arguments.length > 1 ||
- config instanceof Date ||
- Array.isArray(config) ||
- typeof config === "number"
- ) {
- throw new TypeError(
- `FakeTimers.install called with ${String(
- config,
- )} install requires an object parameter`,
- );
- }
-
- if (_global.Date.isFake === true) {
- // Timers are already faked; this is a problem.
- // Make the user reset timers before continuing.
- throw new TypeError(
- "Can't install fake timers twice on the same global object.",
- );
- }
-
- // eslint-disable-next-line no-param-reassign
- config = typeof config !== "undefined" ? config : {};
- config.shouldAdvanceTime = config.shouldAdvanceTime || false;
- config.advanceTimeDelta = config.advanceTimeDelta || 20;
- config.shouldClearNativeTimers =
- config.shouldClearNativeTimers || false;
-
- if (config.target) {
- throw new TypeError(
- "config.target is no longer supported. Use `withGlobal(target)` instead.",
- );
- }
-
- /**
- * @param {string} timer/object the name of the thing that is not present
- * @param timer
- */
- function handleMissingTimer(timer) {
- if (config.ignoreMissingTimers) {
- return;
- }
-
- throw new ReferenceError(
- `non-existent timers and/or objects cannot be faked: '${timer}'`,
- );
- }
-
- let i, l;
- const clock = createClock(config.now, config.loopLimit);
- clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
-
- clock.uninstall = function () {
- return uninstall(clock, config);
- };
-
- clock.abortListenerMap = new Map();
-
- clock.methods = config.toFake || [];
-
- if (clock.methods.length === 0) {
- clock.methods = Object.keys(timers);
- }
-
- if (config.shouldAdvanceTime === true) {
- const intervalTick = doIntervalTick.bind(
- null,
- clock,
- config.advanceTimeDelta,
- );
- const intervalId = _global.setInterval(
- intervalTick,
- config.advanceTimeDelta,
- );
- clock.attachedInterval = intervalId;
- }
-
- if (clock.methods.includes("performance")) {
- const proto = (() => {
- if (hasPerformanceConstructorPrototype) {
- return _global.performance.constructor.prototype;
- }
- if (hasPerformancePrototype) {
- return _global.Performance.prototype;
- }
- })();
- if (proto) {
- Object.getOwnPropertyNames(proto).forEach(function (name) {
- if (name !== "now") {
- clock.performance[name] =
- name.indexOf("getEntries") === 0
- ? NOOP_ARRAY
- : NOOP;
- }
- });
- // ensure `mark` returns a value that is valid
- clock.performance.mark = (name) =>
- new FakePerformanceEntry(name, "mark", 0, 0);
- clock.performance.measure = (name) =>
- new FakePerformanceEntry(name, "measure", 0, 100);
- // `timeOrigin` should return the time of when the Window session started
- // (or the Worker was installed)
- clock.performance.timeOrigin = getEpoch(config.now);
- } else if ((config.toFake || []).includes("performance")) {
- return handleMissingTimer("performance");
- }
- }
- if (_global === globalObject && timersModule) {
- clock.timersModuleMethods = [];
- }
- if (_global === globalObject && timersPromisesModule) {
- clock.timersPromisesModuleMethods = [];
- }
- for (i = 0, l = clock.methods.length; i < l; i++) {
- const nameOfMethodToReplace = clock.methods[i];
-
- if (!isPresent[nameOfMethodToReplace]) {
- handleMissingTimer(nameOfMethodToReplace);
- // eslint-disable-next-line
- continue;
- }
-
- if (nameOfMethodToReplace === "hrtime") {
- if (
- _global.process &&
- typeof _global.process.hrtime === "function"
- ) {
- hijackMethod(_global.process, nameOfMethodToReplace, clock);
- }
- } else if (nameOfMethodToReplace === "nextTick") {
- if (
- _global.process &&
- typeof _global.process.nextTick === "function"
- ) {
- hijackMethod(_global.process, nameOfMethodToReplace, clock);
- }
- } else {
- hijackMethod(_global, nameOfMethodToReplace, clock);
- }
- if (
- clock.timersModuleMethods !== undefined &&
- timersModule[nameOfMethodToReplace]
- ) {
- const original = timersModule[nameOfMethodToReplace];
- clock.timersModuleMethods.push({
- methodName: nameOfMethodToReplace,
- original: original,
- });
- timersModule[nameOfMethodToReplace] =
- _global[nameOfMethodToReplace];
- }
- if (clock.timersPromisesModuleMethods !== undefined) {
- if (nameOfMethodToReplace === "setTimeout") {
- clock.timersPromisesModuleMethods.push({
- methodName: "setTimeout",
- original: timersPromisesModule.setTimeout,
- });
-
- timersPromisesModule.setTimeout = (
- delay,
- value,
- options = {},
- ) =>
- new Promise((resolve, reject) => {
- const abort = () => {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
-
- // This is safe, there is no code path that leads to this function
- // being invoked before handle has been assigned.
- // eslint-disable-next-line no-use-before-define
- clock.clearTimeout(handle);
- reject(options.signal.reason);
- };
-
- const handle = clock.setTimeout(() => {
- if (options.signal) {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
- }
-
- resolve(value);
- }, delay);
-
- if (options.signal) {
- if (options.signal.aborted) {
- abort();
- } else {
- options.signal.addEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.set(
- abort,
- options.signal,
- );
- }
- }
- });
- } else if (nameOfMethodToReplace === "setImmediate") {
- clock.timersPromisesModuleMethods.push({
- methodName: "setImmediate",
- original: timersPromisesModule.setImmediate,
- });
-
- timersPromisesModule.setImmediate = (value, options = {}) =>
- new Promise((resolve, reject) => {
- const abort = () => {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
-
- // This is safe, there is no code path that leads to this function
- // being invoked before handle has been assigned.
- // eslint-disable-next-line no-use-before-define
- clock.clearImmediate(handle);
- reject(options.signal.reason);
- };
-
- const handle = clock.setImmediate(() => {
- if (options.signal) {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
- }
-
- resolve(value);
- });
-
- if (options.signal) {
- if (options.signal.aborted) {
- abort();
- } else {
- options.signal.addEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.set(
- abort,
- options.signal,
- );
- }
- }
- });
- } else if (nameOfMethodToReplace === "setInterval") {
- clock.timersPromisesModuleMethods.push({
- methodName: "setInterval",
- original: timersPromisesModule.setInterval,
- });
-
- timersPromisesModule.setInterval = (
- delay,
- value,
- options = {},
- ) => ({
- [Symbol.asyncIterator]: () => {
- const createResolvable = () => {
- let resolve, reject;
- const promise = new Promise((res, rej) => {
- resolve = res;
- reject = rej;
- });
- promise.resolve = resolve;
- promise.reject = reject;
- return promise;
- };
-
- let done = false;
- let hasThrown = false;
- let returnCall;
- let nextAvailable = 0;
- const nextQueue = [];
-
- const handle = clock.setInterval(() => {
- if (nextQueue.length > 0) {
- nextQueue.shift().resolve();
- } else {
- nextAvailable++;
- }
- }, delay);
-
- const abort = () => {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
-
- clock.clearInterval(handle);
- done = true;
- for (const resolvable of nextQueue) {
- resolvable.resolve();
- }
- };
-
- if (options.signal) {
- if (options.signal.aborted) {
- done = true;
- } else {
- options.signal.addEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.set(
- abort,
- options.signal,
- );
- }
- }
-
- return {
- next: async () => {
- if (options.signal?.aborted && !hasThrown) {
- hasThrown = true;
- throw options.signal.reason;
- }
-
- if (done) {
- return { done: true, value: undefined };
- }
-
- if (nextAvailable > 0) {
- nextAvailable--;
- return { done: false, value: value };
- }
-
- const resolvable = createResolvable();
- nextQueue.push(resolvable);
-
- await resolvable;
-
- if (returnCall && nextQueue.length === 0) {
- returnCall.resolve();
- }
-
- if (options.signal?.aborted && !hasThrown) {
- hasThrown = true;
- throw options.signal.reason;
- }
-
- if (done) {
- return { done: true, value: undefined };
- }
-
- return { done: false, value: value };
- },
- return: async () => {
- if (done) {
- return { done: true, value: undefined };
- }
-
- if (nextQueue.length > 0) {
- returnCall = createResolvable();
- await returnCall;
- }
-
- clock.clearInterval(handle);
- done = true;
-
- if (options.signal) {
- options.signal.removeEventListener(
- "abort",
- abort,
- );
- clock.abortListenerMap.delete(abort);
- }
-
- return { done: true, value: undefined };
- },
- };
- },
- });
- }
- }
- }
-
- return clock;
- }
-
- /* eslint-enable complexity */
-
- return {
- timers: timers,
- createClock: createClock,
- install: install,
- withGlobal: withGlobal,
- };
- }
-
- /**
- * @typedef {object} FakeTimers
- * @property {Timers} timers
- * @property {createClock} createClock
- * @property {Function} install
- * @property {withGlobal} withGlobal
- */
-
- /* eslint-enable complexity */
-
- /** @type {FakeTimers} */
- const defaultImplementation = withGlobal(globalObject);
-
- fakeTimersSrc.timers = defaultImplementation.timers;
- fakeTimersSrc.createClock = defaultImplementation.createClock;
- fakeTimersSrc.install = defaultImplementation.install;
- fakeTimersSrc.withGlobal = withGlobal;
- return fakeTimersSrc;
-}
-
-var fakeTimersSrcExports = requireFakeTimersSrc();
-
-class FakeTimers {
- _global;
- _clock;
- // | _fakingTime | _fakingDate |
- // +-------------+-------------+
- // | false | falsy | initial
- // | false | truthy | vi.setSystemTime called first (for mocking only Date without fake timers)
- // | true | falsy | vi.useFakeTimers called first
- // | true | truthy | unreachable
- _fakingTime;
- _fakingDate;
- _fakeTimers;
- _userConfig;
- _now = RealDate.now;
- constructor({ global, config }) {
- this._userConfig = config;
- this._fakingDate = null;
- this._fakingTime = false;
- this._fakeTimers = fakeTimersSrcExports.withGlobal(global);
- this._global = global;
- }
- clearAllTimers() {
- if (this._fakingTime) this._clock.reset();
- }
- dispose() {
- this.useRealTimers();
- }
- runAllTimers() {
- if (this._checkFakeTimers()) this._clock.runAll();
- }
- async runAllTimersAsync() {
- if (this._checkFakeTimers()) await this._clock.runAllAsync();
- }
- runOnlyPendingTimers() {
- if (this._checkFakeTimers()) this._clock.runToLast();
- }
- async runOnlyPendingTimersAsync() {
- if (this._checkFakeTimers()) await this._clock.runToLastAsync();
- }
- advanceTimersToNextTimer(steps = 1) {
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
- this._clock.next();
- // Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
- this._clock.tick(0);
- if (this._clock.countTimers() === 0) break;
- }
- }
- async advanceTimersToNextTimerAsync(steps = 1) {
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
- await this._clock.nextAsync();
- // Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
- this._clock.tick(0);
- if (this._clock.countTimers() === 0) break;
- }
- }
- advanceTimersByTime(msToRun) {
- if (this._checkFakeTimers()) this._clock.tick(msToRun);
- }
- async advanceTimersByTimeAsync(msToRun) {
- if (this._checkFakeTimers()) await this._clock.tickAsync(msToRun);
- }
- advanceTimersToNextFrame() {
- if (this._checkFakeTimers()) this._clock.runToFrame();
- }
- runAllTicks() {
- if (this._checkFakeTimers())
- // @ts-expect-error method not exposed
- this._clock.runMicrotasks();
- }
- useRealTimers() {
- if (this._fakingDate) {
- resetDate();
- this._fakingDate = null;
- }
- if (this._fakingTime) {
- this._clock.uninstall();
- this._fakingTime = false;
- }
- }
- useFakeTimers() {
- const fakeDate = this._fakingDate || Date.now();
- if (this._fakingDate) {
- resetDate();
- this._fakingDate = null;
- }
- if (this._fakingTime) this._clock.uninstall();
- const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask");
- if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process");
- this._clock = this._fakeTimers.install({
- now: fakeDate,
- ...this._userConfig,
- toFake: this._userConfig?.toFake || toFake,
- ignoreMissingTimers: true
- });
- this._fakingTime = true;
- }
- reset() {
- if (this._checkFakeTimers()) {
- const { now } = this._clock;
- this._clock.reset();
- this._clock.setSystemTime(now);
- }
- }
- setSystemTime(now) {
- const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now);
- if (this._fakingTime) this._clock.setSystemTime(date);
- else {
- this._fakingDate = date ?? new Date(this.getRealSystemTime());
- mockDate(this._fakingDate);
- }
- }
- getMockedSystemTime() {
- return this._fakingTime ? new Date(this._clock.now) : this._fakingDate;
- }
- getRealSystemTime() {
- return this._now();
- }
- getTimerCount() {
- if (this._checkFakeTimers()) return this._clock.countTimers();
- return 0;
- }
- configure(config) {
- this._userConfig = config;
- }
- isFakeTimers() {
- return this._fakingTime;
- }
- _checkFakeTimers() {
- if (!this._fakingTime) throw new Error("A function to advance timers was called but the timers APIs are not mocked. Call `vi.useFakeTimers()` in the test file first.");
- return this._fakingTime;
- }
-}
-
-function copyStackTrace(target, source) {
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
- return target;
-}
-function waitFor(callback, options = {}) {
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
- return new Promise((resolve, reject) => {
- let lastError;
- let promiseStatus = "idle";
- let timeoutId;
- let intervalId;
- const onResolve = (result) => {
- if (timeoutId) clearTimeout(timeoutId);
- if (intervalId) clearInterval(intervalId);
- resolve(result);
- };
- const handleTimeout = () => {
- if (intervalId) clearInterval(intervalId);
- let error = lastError;
- if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
- reject(error);
- };
- const checkCallback = () => {
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
- if (promiseStatus === "pending") return;
- try {
- const result = callback();
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
- const thenable = result;
- promiseStatus = "pending";
- thenable.then((resolvedValue) => {
- promiseStatus = "resolved";
- onResolve(resolvedValue);
- }, (rejectedValue) => {
- promiseStatus = "rejected";
- lastError = rejectedValue;
- });
- } else {
- onResolve(result);
- return true;
- }
- } catch (error) {
- lastError = error;
- }
- };
- if (checkCallback() === true) return;
- timeoutId = setTimeout(handleTimeout, timeout);
- intervalId = setInterval(checkCallback, interval);
- });
-}
-function waitUntil(callback, options = {}) {
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
- return new Promise((resolve, reject) => {
- let promiseStatus = "idle";
- let timeoutId;
- let intervalId;
- const onReject = (error) => {
- if (intervalId) clearInterval(intervalId);
- if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
- reject(error);
- };
- const onResolve = (result) => {
- if (!result) return;
- if (timeoutId) clearTimeout(timeoutId);
- if (intervalId) clearInterval(intervalId);
- resolve(result);
- return true;
- };
- const checkCallback = () => {
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
- if (promiseStatus === "pending") return;
- try {
- const result = callback();
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
- const thenable = result;
- promiseStatus = "pending";
- thenable.then((resolvedValue) => {
- promiseStatus = "resolved";
- onResolve(resolvedValue);
- }, (rejectedValue) => {
- promiseStatus = "rejected";
- onReject(rejectedValue);
- });
- } else return onResolve(result);
- } catch (error) {
- onReject(error);
- }
- };
- if (checkCallback() === true) return;
- timeoutId = setTimeout(onReject, timeout);
- intervalId = setInterval(checkCallback, interval);
- });
-}
-
-function createVitest() {
- let _config = null;
- const state = () => getWorkerState();
- let _timers;
- const timers = () => _timers ||= new FakeTimers({
- global: globalThis,
- config: state().config.fakeTimers
- });
- const _stubsGlobal = /* @__PURE__ */ new Map();
- const _stubsEnv = /* @__PURE__ */ new Map();
- const _envBooleans = [
- "PROD",
- "DEV",
- "SSR"
- ];
- const utils = {
- useFakeTimers(config) {
- if (isChildProcess()) {
- if (config?.toFake?.includes("nextTick") || state().config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.");
- }
- if (config) timers().configure({
- ...state().config.fakeTimers,
- ...config
- });
- else timers().configure(state().config.fakeTimers);
- timers().useFakeTimers();
- return utils;
- },
- isFakeTimers() {
- return timers().isFakeTimers();
- },
- useRealTimers() {
- timers().useRealTimers();
- return utils;
- },
- runOnlyPendingTimers() {
- timers().runOnlyPendingTimers();
- return utils;
- },
- async runOnlyPendingTimersAsync() {
- await timers().runOnlyPendingTimersAsync();
- return utils;
- },
- runAllTimers() {
- timers().runAllTimers();
- return utils;
- },
- async runAllTimersAsync() {
- await timers().runAllTimersAsync();
- return utils;
- },
- runAllTicks() {
- timers().runAllTicks();
- return utils;
- },
- advanceTimersByTime(ms) {
- timers().advanceTimersByTime(ms);
- return utils;
- },
- async advanceTimersByTimeAsync(ms) {
- await timers().advanceTimersByTimeAsync(ms);
- return utils;
- },
- advanceTimersToNextTimer() {
- timers().advanceTimersToNextTimer();
- return utils;
- },
- async advanceTimersToNextTimerAsync() {
- await timers().advanceTimersToNextTimerAsync();
- return utils;
- },
- advanceTimersToNextFrame() {
- timers().advanceTimersToNextFrame();
- return utils;
- },
- getTimerCount() {
- return timers().getTimerCount();
- },
- setSystemTime(time) {
- timers().setSystemTime(time);
- return utils;
- },
- getMockedSystemTime() {
- return timers().getMockedSystemTime();
- },
- getRealSystemTime() {
- return timers().getRealSystemTime();
- },
- clearAllTimers() {
- timers().clearAllTimers();
- return utils;
- },
- spyOn,
- fn,
- waitFor,
- waitUntil,
- hoisted(factory) {
- assertTypes(factory, "\"vi.hoisted\" factory", ["function"]);
- return factory();
- },
- mock(path, factory) {
- if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`);
- const importer = getImporter("mock");
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
- },
- unmock(path) {
- if (typeof path !== "string") throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`);
- _mocker().queueUnmock(path, getImporter("unmock"));
- },
- doMock(path, factory) {
- if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`);
- const importer = getImporter("doMock");
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
- },
- doUnmock(path) {
- if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`);
- const importer = getImporter("doUnmock");
- _mocker().queueUnmock(path, importer);
- },
- async importActual(path) {
- const importer = getImporter("importActual");
- return _mocker().importActual(path, importer, _mocker().getMockContext().callstack);
- },
- async importMock(path) {
- const importer = getImporter("importMock");
- return _mocker().importMock(path, importer);
- },
- mockObject(value, options) {
- return _mocker().mockObject({ value }, void 0, options?.spy ? "autospy" : "automock").value;
- },
- mocked(item, _options = {}) {
- return item;
- },
- isMockFunction(fn) {
- return isMockFunction(fn);
- },
- clearAllMocks() {
- clearAllMocks();
- return utils;
- },
- resetAllMocks() {
- resetAllMocks();
- return utils;
- },
- restoreAllMocks() {
- restoreAllMocks();
- return utils;
- },
- stubGlobal(name, value) {
- if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
- Object.defineProperty(globalThis, name, {
- value,
- writable: true,
- configurable: true,
- enumerable: true
- });
- return utils;
- },
- stubEnv(name, value) {
- const env = state().metaEnv;
- if (!_stubsEnv.has(name)) _stubsEnv.set(name, env[name]);
- if (_envBooleans.includes(name)) env[name] = value ? "1" : "";
- else if (value === void 0) delete env[name];
- else env[name] = String(value);
- return utils;
- },
- unstubAllGlobals() {
- _stubsGlobal.forEach((original, name) => {
- if (!original) Reflect.deleteProperty(globalThis, name);
- else Object.defineProperty(globalThis, name, original);
- });
- _stubsGlobal.clear();
- return utils;
- },
- unstubAllEnvs() {
- const env = state().metaEnv;
- _stubsEnv.forEach((original, name) => {
- if (original === void 0) delete env[name];
- else env[name] = original;
- });
- _stubsEnv.clear();
- return utils;
- },
- resetModules() {
- resetModules(state().evaluatedModules);
- return utils;
- },
- async dynamicImportSettled() {
- return waitForImportsToResolve();
- },
- setConfig(config) {
- if (!_config) _config = { ...state().config };
- Object.assign(state().config, config);
- },
- resetConfig() {
- if (_config) Object.assign(state().config, _config);
- }
- };
- return utils;
-}
-const vitest = createVitest();
-const vi = vitest;
-function _mocker() {
- // @ts-expect-error injected by vite-nide
- return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, { get(_, name) {
- throw new Error(`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`);
- } });
-}
-function getImporter(name) {
- const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
- return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
- return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`) || stack.includes(` at ${name} (`);
- }) + 1])?.file || "";
-}
-
-export { getSnapshotClient as a, assert as b, createExpect as c, vitest as d, globalExpect as g, inject as i, should as s, vi as v };