vitest 4.0.5 → 4.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/browser.d.ts +3 -3
  2. package/dist/chunks/{base.RFExFinv.js → base.D3GxgUMI.js} +43 -50
  3. package/dist/chunks/{browser.d.B9iJzZyn.d.ts → browser.d.-LKfRopd.d.ts} +1 -1
  4. package/dist/chunks/{cac.Be29vze6.js → cac.G9DAn-c7.js} +8 -7
  5. package/dist/chunks/{cli-api.6GYRwzrM.js → cli-api.Csks4as1.js} +32 -28
  6. package/dist/chunks/{config.d.u2CUDWwS.d.ts → config.d.BTfZNUu9.d.ts} +0 -1
  7. package/dist/chunks/{coverage.DT47gDHj.js → coverage.C2LA1DSL.js} +17 -14
  8. package/dist/chunks/{global.d.BgJSTpgQ.d.ts → global.d.DxtanrNO.d.ts} +1 -1
  9. package/dist/chunks/{index.CcRZ6fUh.js → index.CVpyv-Zg.js} +9 -10
  10. package/dist/chunks/{index.DON9WL-E.js → index.CWIFvlX5.js} +57 -11
  11. package/dist/chunks/{resolveSnapshotEnvironment.BZzLjzkh.js → index.DEPqWSIZ.js} +12 -12
  12. package/dist/chunks/{index.BdSLhLDZ.js → index.jMQYiEWE.js} +1 -1
  13. package/dist/chunks/{init-forks.WSf5dRNP.js → init-forks.IU-xQ2_X.js} +3 -2
  14. package/dist/chunks/{init-threads.CgZguQvI.js → init-threads.C_NWvZkU.js} +3 -2
  15. package/dist/chunks/{init.CpZMjXJJ.js → init.fmH9J833.js} +85 -38
  16. package/dist/chunks/{moduleRunner.d.YtNsMIoJ.d.ts → moduleRunner.d.DEkTotCv.d.ts} +1 -1
  17. package/dist/chunks/{plugin.d.D8LgBgbU.d.ts → plugin.d.Cpes8Bt6.d.ts} +1 -1
  18. package/dist/chunks/{reporters.d.D-el0219.d.ts → reporters.d.CSNcMDxF.d.ts} +17 -9
  19. package/dist/chunks/{rpc.Dv1Jt3i2.js → rpc.D38ahn14.js} +8 -11
  20. package/dist/chunks/{startModuleRunner.BqQUfEjB.js → startModuleRunner.Cn7hCL7D.js} +36 -26
  21. package/dist/chunks/{test.CnspO-X4.js → test.B6aJd6T3.js} +1 -1
  22. package/dist/chunks/{vm.CqZQkf-M.js → vm.BL7_zzOr.js} +6 -5
  23. package/dist/chunks/{worker.d.BFk-vvBU.d.ts → worker.d.D25zYZ7N.d.ts} +23 -5
  24. package/dist/cli.js +2 -2
  25. package/dist/config.d.ts +6 -6
  26. package/dist/coverage.d.ts +4 -4
  27. package/dist/coverage.js +1 -1
  28. package/dist/environments.js +2 -1
  29. package/dist/index.d.ts +8 -8
  30. package/dist/module-evaluator.d.ts +3 -3
  31. package/dist/module-runner.js +1 -1
  32. package/dist/node.d.ts +8 -8
  33. package/dist/node.js +7 -7
  34. package/dist/reporters.d.ts +4 -4
  35. package/dist/reporters.js +2 -2
  36. package/dist/runners.d.ts +1 -1
  37. package/dist/runners.js +2 -2
  38. package/dist/worker.d.ts +3 -2
  39. package/dist/worker.js +21 -21
  40. package/dist/workers/forks.js +27 -24
  41. package/dist/workers/runVmTests.js +4 -4
  42. package/dist/workers/threads.js +27 -24
  43. package/dist/workers/vmForks.js +10 -10
  44. package/dist/workers/vmThreads.js +10 -10
  45. package/package.json +12 -12
package/dist/browser.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.d.u2CUDWwS.js';
1
+ import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.d.BTfZNUu9.js';
2
2
  import { R as RuntimeCoverageModuleLoader } from './chunks/coverage.d.BZtK59WP.js';
3
3
  import { SerializedDiffOptions } from '@vitest/utils/diff';
4
- import { V as VitestModuleRunner } from './chunks/moduleRunner.d.YtNsMIoJ.js';
4
+ import { V as VitestModuleRunner } from './chunks/moduleRunner.d.DEkTotCv.js';
5
5
  export { collectTests, startTests } from '@vitest/runner';
6
6
  import * as _vitest_spy from '@vitest/spy';
7
7
  export { _vitest_spy as SpyModule };
@@ -15,7 +15,7 @@ import '@vitest/pretty-format';
15
15
  import '@vitest/snapshot';
16
16
  import 'node:vm';
17
17
  import 'vite/module-runner';
18
- import './chunks/worker.d.BFk-vvBU.js';
18
+ import './chunks/worker.d.D25zYZ7N.js';
19
19
  import './chunks/environment.d.CrsxCzP1.js';
20
20
  import '@vitest/mocker';
21
21
  import './chunks/mocker.d.BE_2ls6u.js';
@@ -1,10 +1,11 @@
1
1
  import { runInThisContext } from 'node:vm';
2
2
  import * as spyModule from '@vitest/spy';
3
+ import { r as resolveTestRunner, a as resolveSnapshotEnvironment, s as setupChaiConfig } from './index.DEPqWSIZ.js';
4
+ import { l as loadEnvironment } from './init.fmH9J833.js';
3
5
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
4
- import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.BqQUfEjB.js';
5
- import { performance } from 'node:perf_hooks';
6
+ import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.Cn7hCL7D.js';
7
+ import { performance as performance$1 } from 'node:perf_hooks';
6
8
  import { startTests, collectTests } from '@vitest/runner';
7
- import { a as resolveSnapshotEnvironment, s as setupChaiConfig, r as resolveTestRunner } from './resolveSnapshotEnvironment.BZzLjzkh.js';
8
9
  import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.DR1sucx6.js';
9
10
  import { g as globalExpect, v as vi } from './vi.BZvkKVkM.js';
10
11
  import { c as closeInspector } from './inspector.DLZxSeU3.js';
@@ -13,20 +14,16 @@ import timers from 'node:timers';
13
14
  import timersPromises from 'node:timers/promises';
14
15
  import util from 'node:util';
15
16
  import { KNOWN_ASSET_TYPES } from '@vitest/utils/constants';
16
- import { getSafeTimers } from '@vitest/utils/timers';
17
17
  import { i as index } from './index.RwjEGCQ0.js';
18
18
  import { g as getWorkerState, r as resetModules, p as provideWorkerState } from './utils.CG9h5ccR.js';
19
19
 
20
20
  // this should only be used in Node
21
21
  let globalSetup = false;
22
- async function setupGlobalEnv(config, { environment }, moduleRunner) {
23
- await setupCommonEnv(config), Object.defineProperty(globalThis, "__vitest_index__", {
22
+ async function setupGlobalEnv(config, environment) {
23
+ if (await setupCommonEnv(config), Object.defineProperty(globalThis, "__vitest_index__", {
24
24
  value: index,
25
25
  enumerable: false
26
- });
27
- const state = getWorkerState();
28
- if (!state.config.snapshotOptions.snapshotEnvironment) state.config.snapshotOptions.snapshotEnvironment = await resolveSnapshotEnvironment(config, moduleRunner);
29
- if (!globalSetup) {
26
+ }), globalExpect.setState({ environment: environment.name }), !globalSetup) {
30
27
  if (globalSetup = true, (environment.viteEnvironment || environment.name) === "client") {
31
28
  const _require = createRequire(import.meta.url);
32
29
  _require.extensions[".css"] = resolveCss, _require.extensions[".scss"] = resolveCss, _require.extensions[".sass"] = resolveCss, _require.extensions[".less"] = resolveCss, KNOWN_ASSET_TYPES.forEach((type) => {
@@ -50,36 +47,28 @@ async function setupConsoleLogSpy() {
50
47
  const { createCustomConsole } = await import('./console.CTJL2nuH.js');
51
48
  globalThis.console = createCustomConsole();
52
49
  }
53
- async function withEnv({ environment }, options, fn) {
54
- globalThis.__vitest_environment__ = environment.name, globalExpect.setState({ environment: environment.name });
55
- const env = await environment.setup(globalThis, options);
56
- try {
57
- await fn();
58
- } finally {
59
- // Run possible setTimeouts, e.g. the onces used by ConsoleLogSpy
60
- const { setTimeout } = getSafeTimers();
61
- await new Promise((resolve) => setTimeout(resolve)), await env.teardown(globalThis);
62
- }
63
- }
64
50
 
65
51
  // browser shouldn't call this!
66
- async function run(method, files, config, environment, moduleRunner) {
67
- const workerState = getWorkerState();
68
- if (await setupGlobalEnv(config, environment, moduleRunner), await startCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate }), config.chaiConfig) setupChaiConfig(config.chaiConfig);
69
- const runner = await resolveTestRunner(config, moduleRunner);
70
- workerState.onCancel.then((reason) => {
71
- closeInspector(config), runner.cancel?.(reason);
72
- }), workerState.durations.prepare = performance.now() - workerState.durations.prepare, workerState.durations.environment = performance.now(), await withEnv(environment, environment.options || config.environmentOptions || {}, async () => {
73
- workerState.durations.environment = performance.now() - workerState.durations.environment;
74
- for (const file of files) {
75
- if (config.isolate) moduleRunner.mocker.reset(), resetModules(workerState.evaluatedModules, true);
76
- if (workerState.filepath = file.filepath, method === "run") await startTests([file], runner);
77
- else await collectTests([file], runner);
78
- // mocks should not affect different files
79
- vi.resetConfig(), vi.restoreAllMocks();
80
- }
81
- await stopCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate });
82
- }), workerState.environmentTeardownRun = true;
52
+ async function run(method, files, config, moduleRunner, environment) {
53
+ const workerState = getWorkerState(), [testRunner] = await Promise.all([
54
+ resolveTestRunner(config, moduleRunner),
55
+ setupGlobalEnv(config, environment),
56
+ startCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate }),
57
+ (async () => {
58
+ if (!workerState.config.snapshotOptions.snapshotEnvironment) workerState.config.snapshotOptions.snapshotEnvironment = await resolveSnapshotEnvironment(config, moduleRunner);
59
+ })()
60
+ ]);
61
+ workerState.onCancel((reason) => {
62
+ closeInspector(config), testRunner.cancel?.(reason);
63
+ }), workerState.durations.prepare = performance$1.now() - workerState.durations.prepare;
64
+ for (const file of files) {
65
+ if (config.isolate) moduleRunner.mocker.reset(), resetModules(workerState.evaluatedModules, true);
66
+ if (workerState.filepath = file.filepath, method === "run") await startTests([file], testRunner);
67
+ else await collectTests([file], testRunner);
68
+ // mocks should not affect different files
69
+ vi.resetConfig(), vi.restoreAllMocks();
70
+ }
71
+ await stopCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate });
83
72
  }
84
73
 
85
74
  let _moduleRunner;
@@ -87,29 +76,36 @@ const evaluatedModules = new VitestEvaluatedModules(), moduleExecutionInfo = /*
87
76
  function startModuleRunner(options) {
88
77
  return _moduleRunner || (_moduleRunner = startVitestModuleRunner(options), _moduleRunner);
89
78
  }
79
+ let _currentEnvironment, _environmentTime;
80
+ async function setupEnvironment(context) {
81
+ const startTime = performance.now(), { environment: { name: environmentName, options: environmentOptions }, rpc, config } = context, { environment, loader } = await loadEnvironment(environmentName, config.root, rpc);
82
+ _currentEnvironment = environment;
83
+ const env = await environment.setup(globalThis, environmentOptions || config.environmentOptions || {});
84
+ if (_environmentTime = performance.now() - startTime, config.chaiConfig) setupChaiConfig(config.chaiConfig);
85
+ return async () => {
86
+ await env.teardown(globalThis), await loader?.close();
87
+ };
88
+ }
90
89
  /** @experimental */
91
90
  async function runBaseTests(method, state) {
92
91
  const { ctx } = state;
93
- if (state.evaluatedModules = evaluatedModules, state.moduleExecutionInfo = moduleExecutionInfo, provideWorkerState(globalThis, state), ctx.invalidates) ctx.invalidates.forEach((filepath) => {
92
+ if (state.environment = _currentEnvironment, state.durations.environment = _environmentTime, state.evaluatedModules = evaluatedModules, state.moduleExecutionInfo = moduleExecutionInfo, provideWorkerState(globalThis, state), ctx.invalidates) ctx.invalidates.forEach((filepath) => {
94
93
  (state.evaluatedModules.fileToModulesMap.get(filepath) || []).forEach((module) => {
95
94
  state.evaluatedModules.invalidateModule(module);
96
95
  });
97
96
  });
98
97
  ctx.files.forEach((i) => {
99
- const filepath = typeof i === "string" ? i : i.filepath;
98
+ const filepath = i.filepath;
100
99
  (state.evaluatedModules.fileToModulesMap.get(filepath) || []).forEach((module) => {
101
100
  state.evaluatedModules.invalidateModule(module);
102
101
  });
103
102
  });
104
- const executor = startModuleRunner({
103
+ const moduleRunner = startModuleRunner({
105
104
  state,
106
105
  evaluatedModules: state.evaluatedModules,
107
106
  spyModule,
108
107
  createImportMeta: createNodeImportMeta
109
- }), fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
110
- filepath: f,
111
- testLocations: void 0
112
- } : f);
108
+ });
113
109
  // we could load @vite/env, but it would take ~8ms, while this takes ~0,02ms
114
110
  if (ctx.config.serializedDefines) try {
115
111
  runInThisContext(`(() =>{\n${ctx.config.serializedDefines}})()`, {
@@ -119,10 +115,7 @@ async function runBaseTests(method, state) {
119
115
  } catch (error) {
120
116
  throw new Error(`Failed to load custom "defines": ${error.message}`);
121
117
  }
122
- await run(method, fileSpecs, ctx.config, {
123
- environment: state.environment,
124
- options: ctx.environment.options
125
- }, executor);
118
+ await run(method, ctx.files, ctx.config, moduleRunner, _currentEnvironment);
126
119
  }
127
120
 
128
- export { runBaseTests as r };
121
+ export { runBaseTests as r, setupEnvironment as s };
@@ -1,5 +1,5 @@
1
1
  import { FileSpecification } from '@vitest/runner';
2
- import { T as TestExecutionMethod } from './worker.d.BFk-vvBU.js';
2
+ import { T as TestExecutionMethod } from './worker.d.D25zYZ7N.js';
3
3
 
4
4
  type SerializedTestSpecification = [project: {
5
5
  name: string | undefined;
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
3
3
  import { normalize } from 'pathe';
4
4
  import c from 'tinyrainbow';
5
5
  import { a as defaultPort, d as defaultBrowserPort } from './constants.D_Q9UYh-.js';
6
- import { R as ReportersMap } from './index.CcRZ6fUh.js';
6
+ import { R as ReportersMap } from './index.CVpyv-Zg.js';
7
7
 
8
8
  function toArr(any) {
9
9
  return any == null ? [] : Array.isArray(any) ? any : [any];
@@ -619,7 +619,7 @@ class CAC extends EventEmitter {
619
619
 
620
620
  const cac = (name = "") => new CAC(name);
621
621
 
622
- var version = "4.0.5";
622
+ var version = "4.0.7";
623
623
 
624
624
  const apiConfig = (port) => ({
625
625
  port: {
@@ -886,7 +886,8 @@ const cliOptionsConfig = {
886
886
  },
887
887
  execArgv: {
888
888
  description: "Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`.",
889
- argument: "<option>"
889
+ argument: "<option>",
890
+ array: true
890
891
  },
891
892
  vmMemoryLimit: {
892
893
  description: "Memory limit for VM pools. If you see memory leaks, try to tinker this value.",
@@ -1294,10 +1295,10 @@ function normalizeCliOptions(cliFilters, argv) {
1294
1295
  }
1295
1296
  async function start(mode, cliFilters, options) {
1296
1297
  try {
1297
- const { startVitest } = await import('./cli-api.6GYRwzrM.js').then(function (n) { return n.p; }), ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1298
+ const { startVitest } = await import('./cli-api.Csks4as1.js').then(function (n) { return n.p; }), ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1298
1299
  if (!ctx.shouldKeepServer()) await ctx.exit();
1299
1300
  } catch (e) {
1300
- const { errorBanner } = await import('./index.CcRZ6fUh.js').then(function (n) { return n.u; });
1301
+ const { errorBanner } = await import('./index.CVpyv-Zg.js').then(function (n) { return n.u; });
1301
1302
  if (console.error(`\n${errorBanner("Startup Error")}`), console.error(e), console.error("\n\n"), process.exitCode == null) process.exitCode = 1;
1302
1303
  process.exit();
1303
1304
  }
@@ -1309,7 +1310,7 @@ async function init(project) {
1309
1310
  }
1310
1311
  async function collect(mode, cliFilters, options) {
1311
1312
  try {
1312
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.6GYRwzrM.js').then(function (n) { return n.p; }), ctx = await prepareVitest(mode, {
1313
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.Csks4as1.js').then(function (n) { return n.p; }), ctx = await prepareVitest(mode, {
1313
1314
  ...normalizeCliOptions(cliFilters, options),
1314
1315
  watch: false,
1315
1316
  run: true
@@ -1327,7 +1328,7 @@ async function collect(mode, cliFilters, options) {
1327
1328
  }
1328
1329
  await ctx.close();
1329
1330
  } catch (e) {
1330
- const { errorBanner } = await import('./index.CcRZ6fUh.js').then(function (n) { return n.u; });
1331
+ const { errorBanner } = await import('./index.CVpyv-Zg.js').then(function (n) { return n.u; });
1331
1332
  if (console.error(`\n${errorBanner("Collect Error")}`), console.error(e), console.error("\n\n"), process.exitCode == null) process.exitCode = 1;
1332
1333
  process.exit();
1333
1334
  }
@@ -4,7 +4,7 @@ import { C as CoverageProviderMap } from './coverage.D_JHT54q.js';
4
4
  import path, { resolve as resolve$1 } from 'node:path';
5
5
  import { noop, createDefer, slash, isExternalUrl, unwrapId, nanoid, withTrailingSlash, cleanUrl, wrapId, toArray, deepMerge, deepClone, isPrimitive, notNullish } from '@vitest/utils/helpers';
6
6
  import { a as any, p as prompt } from './index.Dc3xnDvT.js';
7
- import { h as hash, R as RandomSequencer, i as isPackageExists, c as isBrowserEnabled, r as resolveConfig, g as getCoverageProvider, a as resolveApiServerConfig, d as resolveModule } from './coverage.DT47gDHj.js';
7
+ import { h as hash, R as RandomSequencer, i as isPackageExists, c as isBrowserEnabled, r as resolveConfig, g as getCoverageProvider, a as resolveApiServerConfig, d as resolveModule } from './coverage.C2LA1DSL.js';
8
8
  import * as vite from 'vite';
9
9
  import { parseAst, fetchModule, version, searchForWorkspaceRoot, mergeConfig, createServer } from 'vite';
10
10
  import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.D_Q9UYh-.js';
@@ -12,9 +12,9 @@ import * as nodeos from 'node:os';
12
12
  import nodeos__default, { tmpdir } from 'node:os';
13
13
  import { generateHash as generateHash$1, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, hasFailed, generateFileHash, limitConcurrency, createFileTask as createFileTask$1, getTasks, isTestCase } from '@vitest/runner/utils';
14
14
  import { SnapshotManager } from '@vitest/snapshot/manager';
15
- import { v as version$1 } from './cac.Be29vze6.js';
15
+ import { v as version$1 } from './cac.G9DAn-c7.js';
16
16
  import { c as createBirpc } from './index.Bgo3tNWt.js';
17
- import { p as parse, d as stringify, e as TraceMap, o as originalPositionFor, h as ancestor, i as printError, f as formatProjectName, w as withLabel, j as errorBanner, k as divider, l as Typechecker, m as generateCodeFrame, n as createDefinesScript, R as ReportersMap, B as BlobReporter, r as readBlobs, q as convertTasksToEvents, H as HangingProcessReporter } from './index.CcRZ6fUh.js';
17
+ import { p as parse, d as stringify, e as TraceMap, o as originalPositionFor, h as ancestor, i as printError, f as formatProjectName, w as withLabel, j as errorBanner, k as divider, l as Typechecker, m as generateCodeFrame, n as createDefinesScript, R as ReportersMap, B as BlobReporter, r as readBlobs, q as convertTasksToEvents, H as HangingProcessReporter } from './index.CVpyv-Zg.js';
18
18
  import require$$0$3 from 'events';
19
19
  import require$$1$1 from 'https';
20
20
  import require$$2 from 'http';
@@ -51,7 +51,7 @@ import { c as configDefaults } from './defaults.BOqNVLsY.js';
51
51
  import { KNOWN_ASSET_RE } from '@vitest/utils/constants';
52
52
  import { findNearestPackageData } from '@vitest/utils/resolver';
53
53
  import * as esModuleLexer from 'es-module-lexer';
54
- import { a as BenchmarkReportsMap } from './index.BdSLhLDZ.js';
54
+ import { a as BenchmarkReportsMap } from './index.jMQYiEWE.js';
55
55
  import assert$1 from 'node:assert';
56
56
  import { serializeValue } from '@vitest/utils/serialize';
57
57
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
@@ -6449,7 +6449,15 @@ class PoolRunner {
6449
6449
  this.postMessage({
6450
6450
  type: "start",
6451
6451
  __vitest_worker_request__: true,
6452
- options: { reportMemory: this.worker.reportMemory ?? false }
6452
+ options: { reportMemory: this.worker.reportMemory ?? false },
6453
+ context: {
6454
+ environment: {
6455
+ name: this.environment.name,
6456
+ options: this.environment.options
6457
+ },
6458
+ config: this.project.serializedConfig,
6459
+ pool: this.worker.name
6460
+ }
6453
6461
  }), await startPromise, this._state = RunnerState.STARTED;
6454
6462
  } catch (error) {
6455
6463
  throw this._state = RunnerState.IDLE, error;
@@ -6512,9 +6520,10 @@ class PoolRunner {
6512
6520
  this._eventEmitter.emit("error", error);
6513
6521
  };
6514
6522
  waitForStart() {
6515
- return new Promise((resolve) => {
6523
+ return new Promise((resolve, reject) => {
6516
6524
  const onStart = (message) => {
6517
- if (message.type === "started") this.off("message", onStart), resolve();
6525
+ if (message.type === "started") if (this.off("message", onStart), message.error) reject(message.error);
6526
+ else resolve();
6518
6527
  };
6519
6528
  this.on("message", onStart);
6520
6529
  });
@@ -6555,13 +6564,7 @@ class ForksPoolWorker {
6555
6564
  this.fork.off(event, callback);
6556
6565
  }
6557
6566
  send(message) {
6558
- if ("context" in message) message = {
6559
- ...message,
6560
- context: {
6561
- ...message.context,
6562
- config: wrapSerializableConfig(message.context.config)
6563
- }
6564
- };
6567
+ if ("context" in message && "config" in message.context) message.context.config = wrapSerializableConfig(message.context.config);
6565
6568
  this.fork.send(v8.serialize(message));
6566
6569
  }
6567
6570
  async start() {
@@ -6712,7 +6715,7 @@ async function onMessage(message, project) {
6712
6715
  error: await runPromise,
6713
6716
  __vitest_worker_response__
6714
6717
  };
6715
- case "stop": return await runPromise, await project.typechecker?.stop(), {
6718
+ case "stop": return await runPromise, {
6716
6719
  type: "stopped",
6717
6720
  __vitest_worker_response__
6718
6721
  };
@@ -6770,6 +6773,8 @@ function createRunner(vitest) {
6770
6773
  resolve(false), clearInterval(_i);
6771
6774
  }, 500).unref();
6772
6775
  });
6776
+ // Re-run but wasn't triggered by tsc
6777
+ if (promisesMap.has(project) && !triggered) return promisesMap.get(project);
6773
6778
  if (project.typechecker && !triggered) {
6774
6779
  const testFiles = project.typechecker.getTestFiles();
6775
6780
  for (const file of testFiles) await vitest._testRun.enqueued(project, file);
@@ -6917,7 +6922,7 @@ catch (error) {
6917
6922
  distPath: this.options.distPath,
6918
6923
  project: task.project,
6919
6924
  method,
6920
- environment: task.context.environment.name,
6925
+ environment: task.environment,
6921
6926
  env: task.env,
6922
6927
  execArgv: task.execArgv
6923
6928
  };
@@ -6958,7 +6963,7 @@ function formatFiles(task) {
6958
6963
  }
6959
6964
  function isEqualRunner(runner, task) {
6960
6965
  if (task.isolate) throw new Error("Isolated tasks should not share runners");
6961
- return runner.worker.name === task.worker && runner.project === task.project && runner.environment === task.context.environment.name && (!runner.worker.canReuse || runner.worker.canReuse(task));
6966
+ return runner.worker.name === task.worker && runner.project === task.project && runner.environment.name === task.environment.name && (!runner.worker.canReuse || runner.worker.canReuse(task));
6962
6967
  }
6963
6968
 
6964
6969
  const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
@@ -7011,18 +7016,15 @@ function createPool(ctx) {
7011
7016
  if (!execArgv) execArgv = [...options.execArgv, ...project.config.execArgv], projectExecArgvs.set(project, execArgv);
7012
7017
  taskGroup.push({
7013
7018
  context: {
7014
- pool,
7015
- config: project.serializedConfig,
7016
7019
  files: specs.map((spec) => ({
7017
7020
  filepath: spec.moduleId,
7018
7021
  testLocations: spec.testLines
7019
7022
  })),
7020
7023
  invalidates,
7021
- environment,
7022
- projectName: project.name,
7023
7024
  providedContext: project.getProvidedContext(),
7024
7025
  workerId: workerId++
7025
7026
  },
7027
+ environment,
7026
7028
  project,
7027
7029
  env,
7028
7030
  execArgv,
@@ -7058,7 +7060,11 @@ function createPool(ctx) {
7058
7060
  runTests: (files, invalidates) => executeTests("run", files, invalidates),
7059
7061
  collectTests: (files, invalidates) => executeTests("collect", files, invalidates),
7060
7062
  async close() {
7061
- await Promise.all([pool.close(), browserPool?.close?.()]);
7063
+ await Promise.all([
7064
+ pool.close(),
7065
+ browserPool?.close?.(),
7066
+ ...ctx.projects.map((project) => project.typechecker?.stop())
7067
+ ]);
7062
7068
  }
7063
7069
  };
7064
7070
  }
@@ -7079,8 +7085,7 @@ function resolveOptions(ctx) {
7079
7085
  ...process.execArgv.filter((execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")),
7080
7086
  ...conditions,
7081
7087
  "--experimental-import-meta-resolve",
7082
- "--require",
7083
- suppressWarningsPath
7088
+ ...globalThis.Deno ? [] : ["--require", suppressWarningsPath]
7084
7089
  ],
7085
7090
  env: {
7086
7091
  TEST: "true",
@@ -7123,10 +7128,10 @@ function groupSpecs(specs, environments) {
7123
7128
  typechecks[spec.project.name] ||= [], typechecks[spec.project.name].push(spec);
7124
7129
  return;
7125
7130
  }
7126
- const order = spec.project.config.sequence.groupOrder;
7131
+ const order = spec.project.config.sequence.groupOrder, isolate = spec.project.config.isolate;
7127
7132
  // Files that have disabled parallelism and default groupOrder are set into their own group
7128
- if (order === 0 && spec.project.config.fileParallelism === false) return sequential.specs.push([spec]);
7129
- const maxWorkers = resolveMaxWorkers(spec.project), isolate = spec.project.config.isolate;
7133
+ if (isolate === true && order === 0 && spec.project.config.maxWorkers === 1) return sequential.specs.push([spec]);
7134
+ const maxWorkers = resolveMaxWorkers(spec.project);
7130
7135
  // Multiple projects with different maxWorkers but same groupOrder
7131
7136
  if (groups[order] ||= {
7132
7137
  specs: [],
@@ -7162,7 +7167,6 @@ function serializeConfig(project) {
7162
7167
  environmentOptions: config.environmentOptions,
7163
7168
  mode: config.mode,
7164
7169
  isolate: config.isolate,
7165
- fileParallelism: config.fileParallelism,
7166
7170
  maxWorkers: config.maxWorkers,
7167
7171
  base: config.base,
7168
7172
  logHeapUsage: config.logHeapUsage,
@@ -78,7 +78,6 @@ interface SerializedConfig {
78
78
  disableConsoleIntercept: boolean | undefined;
79
79
  runner: string | undefined;
80
80
  isolate: boolean;
81
- fileParallelism: boolean;
82
81
  maxWorkers: number;
83
82
  mode: "test" | "benchmark";
84
83
  bail: number | undefined;
@@ -1,6 +1,6 @@
1
1
  import fs, { statSync, realpathSync, existsSync, promises, readdirSync, writeFileSync } from 'node:fs';
2
2
  import path, { win32, dirname, join } from 'node:path';
3
- import { slash, shuffle, toArray, cleanUrl } from '@vitest/utils/helpers';
3
+ import { slash, shuffle, toArray } from '@vitest/utils/helpers';
4
4
  import { isAbsolute, resolve, relative, normalize } from 'pathe';
5
5
  import pm from 'picomatch';
6
6
  import { glob } from 'tinyglobby';
@@ -2374,6 +2374,14 @@ class BaseSequencer {
2374
2374
  async sort(files) {
2375
2375
  const cache = this.ctx.cache;
2376
2376
  return [...files].sort((a, b) => {
2377
+ // "sequence.groupOrder" is higher priority
2378
+ const groupOrderDiff = a.project.config.sequence.groupOrder - b.project.config.sequence.groupOrder;
2379
+ if (groupOrderDiff !== 0) return groupOrderDiff;
2380
+ // Projects run sequential
2381
+ if (a.project.name !== b.project.name) return a.project.name < b.project.name ? -1 : 1;
2382
+ // Isolated run first
2383
+ if (a.project.config.isolate && !b.project.config.isolate) return -1;
2384
+ if (!a.project.config.isolate && b.project.config.isolate) return 1;
2377
2385
  const keyA = `${a.project.name}:${relative(this.ctx.config.root, a.moduleId)}`, keyB = `${b.project.name}:${relative(this.ctx.config.root, b.moduleId)}`, aState = cache.getFileTestResults(keyA), bState = cache.getFileTestResults(keyB);
2378
2386
  if (!aState || !bState) {
2379
2387
  const statsA = cache.getFileStats(keyA), statsB = cache.getFileStats(keyB);
@@ -2468,12 +2476,12 @@ function resolveConfig$1(vitest, options, viteConfig) {
2468
2476
  if (resolved.standalone && !resolved.watch) throw new Error(`Vitest standalone mode requires --watch`);
2469
2477
  if (resolved.mergeReports && resolved.watch) throw new Error(`Cannot merge reports with --watch enabled`);
2470
2478
  if (resolved.maxWorkers) resolved.maxWorkers = resolveInlineWorkerOption(resolved.maxWorkers);
2471
- if (resolved.fileParallelism ??= mode !== "benchmark", !resolved.fileParallelism)
2479
+ if (!(options.fileParallelism ?? mode !== "benchmark"))
2472
2480
  // ignore user config, parallelism cannot be implemented without limiting workers
2473
2481
  resolved.maxWorkers = 1;
2474
2482
  if (resolved.maxConcurrency === 0) logger.console.warn(c.yellow(`The option "maxConcurrency" cannot be set to 0. Using default value ${configDefaults.maxConcurrency} instead.`)), resolved.maxConcurrency = configDefaults.maxConcurrency;
2475
2483
  if (resolved.inspect || resolved.inspectBrk) {
2476
- if (resolved.fileParallelism) {
2484
+ if (resolved.maxWorkers !== 1) {
2477
2485
  const inspectOption = `--inspect${resolved.inspectBrk ? "-brk" : ""}`;
2478
2486
  throw new Error(`You cannot use ${inspectOption} without "--no-file-parallelism"`);
2479
2487
  }
@@ -2647,7 +2655,7 @@ function resolveConfig$1(vitest, options, viteConfig) {
2647
2655
  ...configDefaults.typecheck,
2648
2656
  ...resolved.typecheck
2649
2657
  }, resolved.typecheck ??= {}, resolved.typecheck.enabled ??= false, resolved.typecheck.enabled) logger.console.warn(c.yellow("Testing types with tsc and vue-tsc is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest's version when using it."));
2650
- if (resolved.browser.enabled ??= false, resolved.browser.headless ??= isCI, resolved.browser.isolate ??= true, resolved.browser.fileParallelism ??= options.fileParallelism ?? mode !== "benchmark", resolved.browser.ui ??= resolved.browser.headless === true ? false : !isCI, resolved.browser.commands ??= {}, resolved.browser.screenshotDirectory) resolved.browser.screenshotDirectory = resolve(resolved.root, resolved.browser.screenshotDirectory);
2658
+ if (resolved.browser.enabled ??= false, resolved.browser.headless ??= isCI, resolved.browser.isolate ??= resolved.isolate ?? true, resolved.browser.fileParallelism ??= options.fileParallelism ?? mode !== "benchmark", resolved.browser.ui ??= resolved.browser.headless === true ? false : !isCI, resolved.browser.commands ??= {}, resolved.browser.screenshotDirectory) resolved.browser.screenshotDirectory = resolve(resolved.root, resolved.browser.screenshotDirectory);
2651
2659
  if (resolved.inspector.enabled) resolved.browser.trackUnhandledErrors ??= false;
2652
2660
  if (resolved.browser.viewport ??= {}, resolved.browser.viewport.width ??= 414, resolved.browser.viewport.height ??= 896, resolved.browser.locators ??= {}, resolved.browser.locators.testIdAttribute ??= "data-testid", typeof resolved.browser.provider === "string") {
2653
2661
  const source = `@vitest/browser-${resolved.browser.provider}`;
@@ -2763,17 +2771,12 @@ Update your dependencies and make sure the versions match.`));
2763
2771
  // File outside project root with default allowExternal
2764
2772
  if (this.options.allowExternal === false && roots.every((root) => !filename.startsWith(root))) return this.globCache.set(filename, false), false;
2765
2773
  // By default `coverage.include` matches all files, except "coverage.exclude"
2766
- const glob = this.options.include || "**";
2767
- let included = roots.some((root) => {
2768
- const options = {
2769
- contains: true,
2770
- dot: true,
2771
- cwd: root,
2772
- ignore: this.options.exclude
2773
- };
2774
- return pm.isMatch(filename, glob, options);
2774
+ const glob = this.options.include || "**", included = pm.isMatch(filename, glob, {
2775
+ contains: true,
2776
+ dot: true,
2777
+ ignore: this.options.exclude
2775
2778
  });
2776
- return included &&= existsSync(cleanUrl(filename)), this.globCache.set(filename, included), included;
2779
+ return this.globCache.set(filename, included), included;
2777
2780
  }
2778
2781
  async getUntestedFilesByRoot(testedFiles, include, root) {
2779
2782
  let includedFiles = await glob(include, {
@@ -2,7 +2,7 @@ import { PromisifyAssertion, Tester, ExpectStatic } from '@vitest/expect';
2
2
  import { Plugin } from '@vitest/pretty-format';
3
3
  import { SnapshotState } from '@vitest/snapshot';
4
4
  import { B as BenchmarkResult } from './benchmark.d.DAaHLpsq.js';
5
- import { U as UserConsoleLog } from './worker.d.BFk-vvBU.js';
5
+ import { U as UserConsoleLog } from './worker.d.D25zYZ7N.js';
6
6
 
7
7
  interface SnapshotMatcher<T> {
8
8
  <U extends { [P in keyof T] : any }>(snapshot: Partial<U>, hint?: string): void;
@@ -387,12 +387,12 @@ function countTestErrors(tasks) {
387
387
  }
388
388
  function getStateString$1(tasks, name = "tests", showTotal = true) {
389
389
  if (tasks.length === 0) return c.dim(`no ${name}`);
390
- const passed = tasks.filter((i) => i.result?.state === "pass"), failed = tasks.filter((i) => i.result?.state === "fail"), skipped = tasks.filter((i) => i.mode === "skip"), todo = tasks.filter((i) => i.mode === "todo");
390
+ const passed = tasks.reduce((acc, i) => i.result?.state === "pass" ? acc + 1 : acc, 0), failed = tasks.reduce((acc, i) => i.result?.state === "fail" ? acc + 1 : acc, 0), skipped = tasks.reduce((acc, i) => i.mode === "skip" ? acc + 1 : acc, 0), todo = tasks.reduce((acc, i) => i.mode === "todo" ? acc + 1 : acc, 0);
391
391
  return [
392
- failed.length ? c.bold(c.red(`${failed.length} failed`)) : null,
393
- passed.length ? c.bold(c.green(`${passed.length} passed`)) : null,
394
- skipped.length ? c.yellow(`${skipped.length} skipped`) : null,
395
- todo.length ? c.gray(`${todo.length} todo`) : null
392
+ failed ? c.bold(c.red(`${failed} failed`)) : null,
393
+ passed ? c.bold(c.green(`${passed} passed`)) : null,
394
+ skipped ? c.yellow(`${skipped} skipped`) : null,
395
+ todo ? c.gray(`${todo} todo`) : null
396
396
  ].filter(Boolean).join(c.dim(" | ")) + (showTotal ? c.gray(` (${tasks.length})`) : "");
397
397
  }
398
398
  function getStateSymbol(task) {
@@ -704,6 +704,7 @@ class BaseReporter {
704
704
  }
705
705
  printErrorsSummary(files, errors) {
706
706
  const suites = getSuites(files), tests = getTests(files), failedSuites = suites.filter((i) => i.result?.errors), failedTests = tests.filter((i) => i.result?.state === "fail"), failedTotal = countTestErrors(failedSuites) + countTestErrors(failedTests);
707
+ // TODO: error divider should take into account merged errors for counting
707
708
  let current = 1;
708
709
  const errorDivider = () => this.error(`${c.red(c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1)))}\n`);
709
710
  if (failedSuites.length) this.error(`\n${errorBanner(`Failed Suites ${failedSuites.length}`)}\n`), this.printTaskErrors(failedSuites, errorDivider);
@@ -733,7 +734,7 @@ class BaseReporter {
733
734
  task.result?.errors?.forEach((error) => {
734
735
  let previous;
735
736
  if (error?.stack) previous = errorsQueue.find((i) => {
736
- if (i[0]?.stack !== error.stack) return false;
737
+ if (i[0]?.stack !== error.stack || i[0]?.diff !== error.diff) return false;
737
738
  const currentProjectName = task?.projectName || task.file?.projectName || "", projectName = i[1][0]?.projectName || i[1][0].file?.projectName || "", currentAnnotations = task.type === "test" && task.annotations, itemAnnotations = i[1][0].type === "test" && i[1][0].annotations;
738
739
  return projectName === currentProjectName && deepEqual(currentAnnotations, itemAnnotations);
739
740
  });
@@ -1015,7 +1016,7 @@ class SummaryReporter {
1015
1016
  name: testFile.projectName,
1016
1017
  color: testFile.projectColor
1017
1018
  }) + typecheck + testFile.filename + c.dim(!testFile.completed && !testFile.total ? " [queued]" : ` ${testFile.completed}/${testFile.total}`));
1018
- const slowTasks = [testFile.hook, ...Array.from(testFile.tests.values())].filter((t) => t != null && t.visible);
1019
+ const slowTasks = [testFile.hook, ...testFile.tests.values()].filter((t) => t != null && t.visible);
1019
1020
  for (const [index, task] of slowTasks.entries()) {
1020
1021
  const elapsed = this.currentTime - task.startTime, icon = index === slowTasks.length - 1 ? F_TREE_NODE_END : F_TREE_NODE_MIDDLE;
1021
1022
  if (summary.push(c.bold(c.yellow(` ${icon} `)) + task.name + c.bold(c.yellow(` ${formatTime(Math.max(0, elapsed))}`))), task.hook?.visible) summary.push(c.bold(c.yellow(` ${F_TREE_NODE_END} `)) + task.hook.name);
@@ -2597,13 +2598,12 @@ function printErrorInner(error, project, options) {
2597
2598
  }
2598
2599
  });
2599
2600
  }
2600
- const testPath = e.VITEST_TEST_PATH, testName = e.VITEST_TEST_NAME, afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN;
2601
+ const testPath = e.VITEST_TEST_PATH, testName = e.VITEST_TEST_NAME;
2601
2602
  // testName has testPath inside
2602
2603
  if (testPath) logger.error(c.red(`This error originated in "${c.bold(relative(project.config.root, testPath))}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`));
2603
2604
  if (testName) logger.error(c.red(`The latest test that might've caused the error is "${c.bold(testName)}". It might mean one of the following:
2604
2605
  - The error was thrown, while Vitest was running this test.
2605
2606
  - If the error occurred after the test had been completed, this was the last documented test before it was thrown.`));
2606
- if (afterEnvTeardown) logger.error(c.red("This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword"));
2607
2607
  if (typeof e.cause === "object" && e.cause && "name" in e.cause) e.cause.name = `Caused by: ${e.cause.name}`, printErrorInner(e.cause, project, {
2608
2608
  showCodeFrame: false,
2609
2609
  logger: options.logger,
@@ -2635,7 +2635,6 @@ const skipErrorProperties = new Set([
2635
2635
  "columnNumber",
2636
2636
  "VITEST_TEST_NAME",
2637
2637
  "VITEST_TEST_PATH",
2638
- "VITEST_AFTER_ENV_TEARDOWN",
2639
2638
  "__vitest_rollup_error__",
2640
2639
  ...Object.getOwnPropertyNames(Error.prototype),
2641
2640
  ...Object.getOwnPropertyNames(Object.prototype)