import { performance } from 'perf_hooks'; import { g as generateHash, c as calculateSuiteHash, s as someTasksAreOnly, i as interpretTaskModes, t as takeCoverageInsideWorker, p as pLimit } from './chunk-integrations-coverage.44413252.js'; import { f as clearCollectorContext, h as defaultSuite, j as setHooks, k as getHooks, l as collectorContext, m as getBenchOptions, n as getFn, o as setState, p as getSnapshotClient, G as GLOBAL_EXPECT, q as getState } from './chunk-runtime-chain.6df5a66b.js'; import { r as resetRunOnceCounter, i as index, v as vi, s as setCurrentTest } from './chunk-utils-import.2baa69a9.js'; import { g as getWorkerState, R as RealDate, t as toArray, k as relativePath, h as isRunningInBenchmark, p as partitionSuiteChildren, l as shuffle, q as hasTests, u as hasFailed, v as createDefer, e as getFullName } from './chunk-mock-date.a1c85759.js'; import { r as rpc } from './chunk-runtime-rpc.7f83c8a9.js'; import { p as processError } from './chunk-runtime-error.fad2c32b.js'; import { installSourcemapsSupport } from 'vite-node/source-map'; import { e as environments } from './chunk-env-node.b3664da2.js'; import { i as isNode, a as isBrowser } from './chunk-utils-env.b861e3a0.js'; import { b as safeClearTimeout, s as safeSetTimeout } from './chunk-utils-timers.52534f96.js'; let globalSetup = false; async function setupGlobalEnv(config) { resetRunOnceCounter(); Object.defineProperty(globalThis, "__vitest_index__", { value: index, enumerable: false }); setupDefines(config.defines); if (globalSetup) return; globalSetup = true; if (isNode) { const state = getWorkerState(); installSourcemapsSupport({ getSourceMap: (source) => state.moduleCache.getSourceMap(source) }); await setupConsoleLogSpy(); } if (config.globals) (await import('./chunk-integrations-globals.3dfaeb99.js')).registerApiGlobally(); } function setupDefines(defines) { for (const key in defines) globalThis[key] = defines[key]; } async function setupConsoleLogSpy() { const stdoutBuffer = /* @__PURE__ */ new Map(); const stderrBuffer = /* @__PURE__ */ new Map(); const timers = /* @__PURE__ */ new Map(); const unknownTestId = "__vitest__unknown_test__"; const { Writable } = await import('node:stream'); const { Console } = await import('node:console'); function schedule(taskId) { const timer = timers.get(taskId); const { stdoutTime, stderrTime } = timer; safeClearTimeout(timer.timer); timer.timer = safeSetTimeout(() => { if (stderrTime < stdoutTime) { sendStderr(taskId); sendStdout(taskId); } else { sendStdout(taskId); sendStderr(taskId); } }); } function sendStdout(taskId) { const buffer = stdoutBuffer.get(taskId); if (!buffer) return; const content = buffer.map((i) => String(i)).join(""); if (!content.trim()) return; const timer = timers.get(taskId); rpc().onUserConsoleLog({ type: "stdout", content, taskId, time: timer.stdoutTime || RealDate.now(), size: buffer.length }); stdoutBuffer.set(taskId, []); timer.stdoutTime = 0; } function sendStderr(taskId) { const buffer = stderrBuffer.get(taskId); if (!buffer) return; const content = buffer.map((i) => String(i)).join(""); if (!content.trim()) return; const timer = timers.get(taskId); rpc().onUserConsoleLog({ type: "stderr", content, taskId, time: timer.stderrTime || RealDate.now(), size: buffer.length }); stderrBuffer.set(taskId, []); timer.stderrTime = 0; } const stdout = new Writable({ write(data, encoding, callback) { var _a, _b; const id = ((_b = (_a = getWorkerState()) == null ? void 0 : _a.current) == null ? void 0 : _b.id) ?? unknownTestId; let timer = timers.get(id); if (timer) { timer.stdoutTime = timer.stdoutTime || RealDate.now(); } else { timer = { stdoutTime: RealDate.now(), stderrTime: RealDate.now(), timer: 0 }; timers.set(id, timer); } let buffer = stdoutBuffer.get(id); if (!buffer) { buffer = []; stdoutBuffer.set(id, buffer); } buffer.push(data); schedule(id); callback(); } }); const stderr = new Writable({ write(data, encoding, callback) { var _a, _b; const id = ((_b = (_a = getWorkerState()) == null ? void 0 : _a.current) == null ? void 0 : _b.id) ?? unknownTestId; let timer = timers.get(id); if (timer) { timer.stderrTime = timer.stderrTime || RealDate.now(); } else { timer = { stderrTime: RealDate.now(), stdoutTime: RealDate.now(), timer: 0 }; timers.set(id, timer); } let buffer = stderrBuffer.get(id); if (!buffer) { buffer = []; stderrBuffer.set(id, buffer); } buffer.push(data); schedule(id); callback(); } }); globalThis.console = new Console({ stdout, stderr, colorMode: true, groupIndentation: 2 }); } async function loadEnvironment(name) { const pkg = await import(`vitest-environment-${name}`); if (!pkg || !pkg.default || typeof pkg.default !== "object" || typeof pkg.default.setup !== "function") { throw new Error( `Environment "${name}" is not a valid environment. Package "vitest-environment-${name}" should have default export with "setup" method.` ); } return pkg.default; } async function withEnv(name, options, fn) { const config = environments[name] || await loadEnvironment(name); const env = await config.setup(globalThis, options); try { await fn(); } finally { await env.teardown(globalThis); } } async function runSetupFiles(config) { const files = toArray(config.setupFiles); await Promise.all( files.map(async (fsPath) => { getWorkerState().moduleCache.delete(fsPath); await import(fsPath); }) ); } const now$1 = Date.now; async function collectTests(paths, config) { const files = []; const browserHashMap = getWorkerState().browserHashMap; async function importFromBrowser(filepath) { const match = filepath.match(/^(\w:\/)/); const hash = browserHashMap.get(filepath); if (match) return await import(`/@fs/${filepath.slice(match[1].length)}?v=${hash}`); else return await import(`${filepath}?v=${hash}`); } for (const filepath of paths) { const path = relativePath(config.root, filepath); const file = { id: generateHash(path), name: path, type: "suite", mode: "run", filepath, tasks: [], projectName: config.name }; clearCollectorContext(); try { const setupStart = now$1(); await runSetupFiles(config); const collectStart = now$1(); file.setupDuration = collectStart - setupStart; if (config.browser && isBrowser) await importFromBrowser(filepath); else await import(filepath); const defaultTasks = await defaultSuite.collect(file); setHooks(file, getHooks(defaultTasks)); for (const c of [...defaultTasks.tasks, ...collectorContext.tasks]) { if (c.type === "test") { file.tasks.push(c); } else if (c.type === "benchmark") { file.tasks.push(c); } else if (c.type === "suite") { file.tasks.push(c); } else if (c.type === "collector") { const suite = await c.collect(file); if (suite.name || suite.tasks.length) file.tasks.push(suite); } } file.collectDuration = now$1() - collectStart; } catch (e) { const error = processError(e); file.result = { state: "fail", error, errors: [error] }; if (config.browser) console.error(e); } calculateSuiteHash(file); const hasOnlyTasks = someTasksAreOnly(file); interpretTaskModes(file, config.testNamePattern, hasOnlyTasks, false, config.allowOnly); files.push(file); } return files; } async function importTinybench() { if (!globalThis.EventTarget) await import('./vendor-index.534e612c.js').then(function (n) { return n.i; }); return await import('tinybench'); } const now = Date.now; function updateSuiteHookState(suite, name, state) { var _a; if (!suite.result) suite.result = { state: "run" }; if (!((_a = suite.result) == null ? void 0 : _a.hooks)) suite.result.hooks = {}; const suiteHooks = suite.result.hooks; if (suiteHooks) { suiteHooks[name] = state; updateTask(suite); } } function getSuiteHooks(suite, name, sequence) { const hooks = getHooks(suite)[name]; if (sequence === "stack" && (name === "afterAll" || name === "afterEach")) return hooks.slice().reverse(); return hooks; } async function callSuiteHook(suite, currentTask, name, args) { const callbacks = []; if (name === "beforeEach" && suite.suite) { callbacks.push( ...await callSuiteHook(suite.suite, currentTask, name, args) ); } updateSuiteHookState(currentTask, name, "run"); const state = getWorkerState(); const sequence = state.config.sequence.hooks; const hooks = getSuiteHooks(suite, name, sequence); if (sequence === "parallel") { callbacks.push(...await Promise.all(hooks.map((fn) => fn(...args)))); } else { for (const hook of hooks) callbacks.push(await hook(...args)); } updateSuiteHookState(currentTask, name, "pass"); if (name === "afterEach" && suite.suite) { callbacks.push( ...await callSuiteHook(suite.suite, currentTask, name, args) ); } return callbacks; } const packs = /* @__PURE__ */ new Map(); let updateTimer; let previousUpdate; function updateTask(task) { packs.set(task.id, task.result); safeClearTimeout(updateTimer); updateTimer = safeSetTimeout(() => { previousUpdate = sendTasksUpdate(); }, 10); } async function sendTasksUpdate() { safeClearTimeout(updateTimer); await previousUpdate; if (packs.size) { const p = rpc().onTaskUpdate(Array.from(packs)); packs.clear(); return p; } } const callCleanupHooks = async (cleanups) => { await Promise.all(cleanups.map(async (fn) => { if (typeof fn !== "function") return; await fn(); })); }; async function runTest(test) { var _a, _b, _c; if (test.mode !== "run") { const { getSnapshotClient: getSnapshotClient2 } = await import('./chunk-runtime-chain.6df5a66b.js').then(function (n) { return n.u; }); getSnapshotClient2().skipTestSnapshots(test); return; } if (((_a = test.result) == null ? void 0 : _a.state) === "fail") { updateTask(test); return; } const start = now(); test.result = { state: "run", startTime: start }; updateTask(test); clearModuleMocks(); setCurrentTest(test); if (isNode) { const { getSnapshotClient: getSnapshotClient2 } = await import('./chunk-runtime-chain.6df5a66b.js').then(function (n) { return n.u; }); await getSnapshotClient2().setTest(test); } const workerState = getWorkerState(); workerState.current = test; const retry = test.retry || 1; for (let retryCount = 0; retryCount < retry; retryCount++) { let beforeEachCleanups = []; try { setState({ assertionCalls: 0, isExpectingAssertions: false, isExpectingAssertionsError: null, expectedAssertionsNumber: null, expectedAssertionsNumberErrorGen: null, testPath: (_b = test.suite.file) == null ? void 0 : _b.filepath, currentTestName: getFullName(test), snapshotState: getSnapshotClient().snapshotState }, globalThis[GLOBAL_EXPECT]); beforeEachCleanups = await callSuiteHook(test.suite, test, "beforeEach", [test.context, test.suite]); test.result.retryCount = retryCount; await getFn(test)(); const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]); if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen(); if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError; test.result.state = "pass"; } catch (e) { const error = processError(e); test.result.state = "fail"; test.result.error = error; test.result.errors = [error]; } try { await callSuiteHook(test.suite, test, "afterEach", [test.context, test.suite]); await callCleanupHooks(beforeEachCleanups); } catch (e) { const error = processError(e); test.result.state = "fail"; test.result.error = error; test.result.errors = [error]; } if (test.result.state === "pass") break; updateTask(test); } if (test.result.state === "fail") await Promise.all(((_c = test.onFailed) == null ? void 0 : _c.map((fn) => fn(test.result))) || []); if (test.fails) { if (test.result.state === "pass") { const error = processError(new Error("Expect test to fail")); test.result.state = "fail"; test.result.error = error; test.result.errors = [error]; } else { test.result.state = "pass"; test.result.error = void 0; test.result.errors = void 0; } } if (isBrowser && test.result.error) console.error(test.result.error.message, test.result.error.stackStr); setCurrentTest(void 0); if (isNode) { const { getSnapshotClient: getSnapshotClient2 } = await import('./chunk-runtime-chain.6df5a66b.js').then(function (n) { return n.u; }); getSnapshotClient2().clearTest(); } test.result.duration = now() - start; if (workerState.config.logHeapUsage && isNode) test.result.heap = process.memoryUsage().heapUsed; workerState.current = void 0; updateTask(test); } function markTasksAsSkipped(suite) { suite.tasks.forEach((t) => { t.mode = "skip"; t.result = { ...t.result, state: "skip" }; updateTask(t); if (t.type === "suite") markTasksAsSkipped(t); }); } async function runSuite(suite) { var _a; if (((_a = suite.result) == null ? void 0 : _a.state) === "fail") { markTasksAsSkipped(suite); updateTask(suite); return; } const start = now(); suite.result = { state: "run", startTime: start }; updateTask(suite); const workerState = getWorkerState(); if (suite.mode === "skip") { suite.result.state = "skip"; } else if (suite.mode === "todo") { suite.result.state = "todo"; } else { try { const beforeAllCleanups = await callSuiteHook(suite, suite, "beforeAll", [suite]); if (isRunningInBenchmark()) { await runBenchmarkSuite(suite); } else { for (let tasksGroup of partitionSuiteChildren(suite)) { if (tasksGroup[0].concurrent === true) { const mutex = pLimit(workerState.config.maxConcurrency); await Promise.all(tasksGroup.map((c) => mutex(() => runSuiteChild(c)))); } else { const { sequence } = workerState.config; if (sequence.shuffle || suite.shuffle) { const suites = tasksGroup.filter((group) => group.type === "suite"); const tests = tasksGroup.filter((group) => group.type === "test"); const groups = shuffle([suites, tests], sequence.seed); tasksGroup = groups.flatMap((group) => shuffle(group, sequence.seed)); } for (const c of tasksGroup) await runSuiteChild(c); } } } await callSuiteHook(suite, suite, "afterAll", [suite]); await callCleanupHooks(beforeAllCleanups); } catch (e) { const error = processError(e); suite.result.state = "fail"; suite.result.error = error; suite.result.errors = [error]; } } suite.result.duration = now() - start; if (workerState.config.logHeapUsage && isNode) suite.result.heap = process.memoryUsage().heapUsed; if (suite.mode === "run") { if (!hasTests(suite)) { suite.result.state = "fail"; if (!suite.result.error) { const error = processError(new Error(`No test found in suite ${suite.name}`)); suite.result.error = error; suite.result.errors = [error]; } } else if (hasFailed(suite)) { suite.result.state = "fail"; } else { suite.result.state = "pass"; } } updateTask(suite); } function createBenchmarkResult(name) { return { name, rank: 0, rme: 0, samples: [] }; } async function runBenchmarkSuite(suite) { const { Task, Bench } = await importTinybench(); const start = performance.now(); const benchmarkGroup = []; const benchmarkSuiteGroup = []; for (const task of suite.tasks) { if (task.mode !== "run") continue; if (task.type === "benchmark") benchmarkGroup.push(task); else if (task.type === "suite") benchmarkSuiteGroup.push(task); } if (benchmarkSuiteGroup.length) await Promise.all(benchmarkSuiteGroup.map((subSuite) => runBenchmarkSuite(subSuite))); if (benchmarkGroup.length) { const defer = createDefer(); const benchmarkMap = {}; suite.result = { state: "run", startTime: start, benchmark: createBenchmarkResult(suite.name) }; updateTask(suite); benchmarkGroup.forEach((benchmark, idx) => { const options = getBenchOptions(benchmark); const benchmarkInstance = new Bench(options); const benchmarkFn = getFn(benchmark); benchmark.result = { state: "run", startTime: start, benchmark: createBenchmarkResult(benchmark.name) }; const id = idx.toString(); benchmarkMap[id] = benchmark; const task = new Task(benchmarkInstance, id, benchmarkFn); benchmark.task = task; updateTask(benchmark); }); benchmarkGroup.forEach((benchmark) => { benchmark.task.addEventListener("complete", (e) => { const task = e.task; const _benchmark = benchmarkMap[task.name || ""]; if (_benchmark) { const taskRes = task.result; const result = _benchmark.result.benchmark; Object.assign(result, taskRes); updateTask(_benchmark); } }); benchmark.task.addEventListener("error", (e) => { const task = e.task; const _benchmark = benchmarkMap[task.name || ""]; defer.reject(_benchmark ? task.result.error : e); }); }); Promise.all(benchmarkGroup.map(async (benchmark) => { await benchmark.task.warmup(); return await new Promise((resolve) => safeSetTimeout(async () => { resolve(await benchmark.task.run()); })); })).then((tasks) => { suite.result.duration = performance.now() - start; suite.result.state = "pass"; tasks.sort((a, b) => a.result.mean - b.result.mean).forEach((cycle, idx) => { const benchmark = benchmarkMap[cycle.name || ""]; benchmark.result.state = "pass"; if (benchmark) { const result = benchmark.result.benchmark; result.rank = Number(idx) + 1; updateTask(benchmark); } }); updateTask(suite); defer.resolve(null); }); await defer; } } async function runSuiteChild(c) { if (c.type === "test") return runTest(c); else if (c.type === "suite") return runSuite(c); } async function runSuites(suites) { for (const suite of suites) await runSuite(suite); } async function runFiles(files, config) { var _a, _b; for (const file of files) { if (!file.tasks.length && !config.passWithNoTests) { if (!((_b = (_a = file.result) == null ? void 0 : _a.errors) == null ? void 0 : _b.length)) { const error = processError(new Error(`No test suite found in file ${file.filepath}`)); file.result = { state: "fail", error, errors: [error] }; } } await runSuite(file); } } async function startTestsBrowser(paths, config) { if (isNode) { rpc().onPathsCollected(paths); } else { const files = await collectTests(paths, config); await rpc().onCollected(files); await runSuites(files); await sendTasksUpdate(); } } async function startTestsNode(paths, config) { const files = await collectTests(paths, config); rpc().onCollected(files); const { getSnapshotClient: getSnapshotClient2 } = await import('./chunk-runtime-chain.6df5a66b.js').then(function (n) { return n.u; }); getSnapshotClient2().clear(); await runFiles(files, config); const coverage = await takeCoverageInsideWorker(config.coverage); rpc().onAfterSuiteRun({ coverage }); await getSnapshotClient2().saveCurrent(); await sendTasksUpdate(); } async function startTests(paths, config) { if (config.browser) return startTestsBrowser(paths, config); else return startTestsNode(paths, config); } function clearModuleMocks() { const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = getWorkerState().config; if (restoreMocks) vi.restoreAllMocks(); else if (mockReset) vi.resetAllMocks(); else if (clearMocks) vi.clearAllMocks(); if (unstubEnvs) vi.unstubAllEnvs(); if (unstubGlobals) vi.unstubAllGlobals(); } export { setupGlobalEnv as a, startTests as s, withEnv as w };