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