aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
commit76cb9c2a39d477a64824a985ade40507e3bbade1 (patch)
tree41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
parent819a39a21ac992b1393244a4c283bbb125208c69 (diff)
downloadneko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
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, 3919 insertions, 0 deletions
diff --git a/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js b/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
new file mode 100644
index 0000000..1e3d35a
--- /dev/null
+++ b/vanilla/node_modules/vitest/dist/chunks/vi.2VT5v0um.js
@@ -0,0 +1,3919 @@
+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 };