vitest 4.0.6 → 4.0.8

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 (65) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/base.BgTO2qAg.js +156 -0
  5. package/dist/chunks/{benchmark.DHKMYAts.js → benchmark.B3N2zMcH.js} +9 -4
  6. package/dist/chunks/{browser.d.ScGeWTou.d.ts → browser.d.DTTM2PTh.d.ts} +1 -1
  7. package/dist/chunks/{cac.BBqWH4nd.js → cac.CfkWq8Qy.js} +117 -43
  8. package/dist/chunks/{cli-api.UL3SwFUb.js → cli-api.BQ-bjcRi.js} +1870 -847
  9. package/dist/chunks/console.Cf-YriPC.js +146 -0
  10. package/dist/chunks/{coverage.DuCn_Tmx.js → coverage.NVjCOln1.js} +281 -103
  11. package/dist/chunks/{creator.cqqifzG7.js → creator.fzVyoMf3.js} +74 -30
  12. package/dist/chunks/{date.-jtEtIeV.js → date.Bq6ZW5rf.js} +17 -6
  13. package/dist/chunks/{git.BFNcloKD.js → git.Bm2pzPAa.js} +3 -3
  14. package/dist/chunks/{global.d.DdOkMiVb.d.ts → global.d.DVdCfKp5.d.ts} +1 -1
  15. package/dist/chunks/{globals.BGT_RUsD.js → globals.DOh96BiR.js} +5 -5
  16. package/dist/chunks/{resolveSnapshotEnvironment.BZzLjzkh.js → index.BY4-tcno.js} +42 -25
  17. package/dist/chunks/{index.Bgo3tNWt.js → index.DAL392Ss.js} +40 -15
  18. package/dist/chunks/{index.RwjEGCQ0.js → index.DIFZf73e.js} +2 -2
  19. package/dist/chunks/{index.DV0mQLEO.js → index.DfKyPFVi.js} +195 -64
  20. package/dist/chunks/{index.BL8Hg4Uk.js → index.kotH7DY7.js} +837 -380
  21. package/dist/chunks/{index.CpdwpN7L.js → index.op2Re5rn.js} +22 -12
  22. package/dist/chunks/{init-forks.CSGFj9zN.js → init-forks.2hx7cf78.js} +16 -5
  23. package/dist/chunks/{init-threads.CIJLeFO8.js → init-threads.Cm4OCIWA.js} +3 -2
  24. package/dist/chunks/{init.DUeOfNO9.js → init.DMDG-idf.js} +124 -54
  25. package/dist/chunks/{inspector.DLZxSeU3.js → inspector.CvyFGlXm.js} +25 -10
  26. package/dist/chunks/{moduleRunner.d.TP-w6tIQ.d.ts → moduleRunner.d.CzOZ_4wC.d.ts} +1 -1
  27. package/dist/chunks/{node.BwAWWjHZ.js → node.Ce0vMQM7.js} +1 -1
  28. package/dist/chunks/{plugin.d.lctzD3Wk.d.ts → plugin.d.D4RrtywJ.d.ts} +1 -1
  29. package/dist/chunks/{reporters.d.PEs0tXod.d.ts → reporters.d.Da1D1VbQ.d.ts} +19 -9
  30. package/dist/chunks/rpc.BUV7uWKJ.js +76 -0
  31. package/dist/chunks/{setup-common.DR1sucx6.js → setup-common.LGjNSzXp.js} +20 -8
  32. package/dist/chunks/{startModuleRunner.Di-EZqh0.js → startModuleRunner.BOmUtLIO.js} +228 -105
  33. package/dist/chunks/{test.CnspO-X4.js → test.ClrAtjMv.js} +48 -22
  34. package/dist/chunks/{utils.CG9h5ccR.js → utils.DvEY5TfP.js} +14 -5
  35. package/dist/chunks/{vi.BZvkKVkM.js → vi.Bgcdy3bQ.js} +261 -111
  36. package/dist/chunks/{vm.Co_lR2NL.js → vm.BIkCDs68.js} +177 -70
  37. package/dist/chunks/{worker.d.B4Hthdvt.d.ts → worker.d.DadbA89M.d.ts} +52 -6
  38. package/dist/cli.js +2 -2
  39. package/dist/config.d.ts +5 -5
  40. package/dist/coverage.d.ts +3 -3
  41. package/dist/coverage.js +1 -1
  42. package/dist/environments.js +2 -1
  43. package/dist/index.d.ts +5 -5
  44. package/dist/index.js +5 -5
  45. package/dist/module-evaluator.d.ts +2 -2
  46. package/dist/module-evaluator.js +85 -35
  47. package/dist/module-runner.js +2 -2
  48. package/dist/node.d.ts +7 -7
  49. package/dist/node.js +16 -12
  50. package/dist/reporters.d.ts +3 -3
  51. package/dist/reporters.js +2 -2
  52. package/dist/runners.js +7 -7
  53. package/dist/snapshot.js +2 -2
  54. package/dist/suite.js +2 -2
  55. package/dist/worker.d.ts +2 -1
  56. package/dist/worker.js +27 -27
  57. package/dist/workers/forks.js +34 -31
  58. package/dist/workers/runVmTests.js +41 -22
  59. package/dist/workers/threads.js +34 -31
  60. package/dist/workers/vmForks.js +14 -14
  61. package/dist/workers/vmThreads.js +14 -14
  62. package/package.json +20 -20
  63. package/dist/chunks/base.BAf_bYeI.js +0 -128
  64. package/dist/chunks/console.CTJL2nuH.js +0 -115
  65. package/dist/chunks/rpc.Dv1Jt3i2.js +0 -66
package/LICENSE.md CHANGED
@@ -225,7 +225,7 @@ Repository: https://github.com/acornjs/acorn.git
225
225
  ## birpc
226
226
  License: MIT
227
227
  By: Anthony Fu
228
- Repository: git+https://github.com/antfu/birpc.git
228
+ Repository: git+https://github.com/antfu-collective/birpc.git
229
229
 
230
230
  > MIT License
231
231
  >
package/dist/browser.d.ts CHANGED
@@ -1,7 +1,7 @@
1
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.TP-w6tIQ.js';
4
+ import { V as VitestModuleRunner } from './chunks/moduleRunner.d.CzOZ_4wC.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.B4Hthdvt.js';
18
+ import './chunks/worker.d.DadbA89M.js';
19
19
  import './chunks/environment.d.CrsxCzP1.js';
20
20
  import '@vitest/mocker';
21
21
  import './chunks/mocker.d.BE_2ls6u.js';
package/dist/browser.js CHANGED
@@ -1,4 +1,4 @@
1
- export { l as loadDiffConfig, b as loadSnapshotSerializers, c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './chunks/setup-common.DR1sucx6.js';
1
+ export { l as loadDiffConfig, b as loadSnapshotSerializers, c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './chunks/setup-common.LGjNSzXp.js';
2
2
  export { collectTests, startTests } from '@vitest/runner';
3
3
  import * as spyModule from '@vitest/spy';
4
4
  export { spyModule as SpyModule };
@@ -9,7 +9,7 @@ export { DecodedMap, getOriginalPosition } from '@vitest/utils/source-map';
9
9
  export { getSafeTimers, setSafeTimers } from '@vitest/utils/timers';
10
10
  import './chunks/coverage.D_JHT54q.js';
11
11
  import '@vitest/snapshot';
12
- import './chunks/utils.CG9h5ccR.js';
12
+ import './chunks/utils.DvEY5TfP.js';
13
13
 
14
14
  /**
15
15
  * @internal
@@ -0,0 +1,156 @@
1
+ import { runInThisContext } from 'node:vm';
2
+ import * as spyModule from '@vitest/spy';
3
+ import { r as resolveTestRunner, a as resolveSnapshotEnvironment, s as setupChaiConfig } from './index.BY4-tcno.js';
4
+ import { l as loadEnvironment } from './init.DMDG-idf.js';
5
+ import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
6
+ import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.BOmUtLIO.js';
7
+ import { performance as performance$1 } from 'node:perf_hooks';
8
+ import { startTests, collectTests } from '@vitest/runner';
9
+ import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.LGjNSzXp.js';
10
+ import { g as globalExpect, v as vi } from './vi.Bgcdy3bQ.js';
11
+ import { c as closeInspector } from './inspector.CvyFGlXm.js';
12
+ import { createRequire } from 'node:module';
13
+ import timers from 'node:timers';
14
+ import timersPromises from 'node:timers/promises';
15
+ import util from 'node:util';
16
+ import { KNOWN_ASSET_TYPES } from '@vitest/utils/constants';
17
+ import { i as index } from './index.DIFZf73e.js';
18
+ import { g as getWorkerState, r as resetModules, p as provideWorkerState } from './utils.DvEY5TfP.js';
19
+
20
+ // this should only be used in Node
21
+ let globalSetup = false;
22
+ async function setupGlobalEnv(config, environment) {
23
+ await setupCommonEnv(config);
24
+ Object.defineProperty(globalThis, "__vitest_index__", {
25
+ value: index,
26
+ enumerable: false
27
+ });
28
+ globalExpect.setState({ environment: environment.name });
29
+ if (globalSetup) return;
30
+ globalSetup = true;
31
+ if ((environment.viteEnvironment || environment.name) === "client") {
32
+ const _require = createRequire(import.meta.url);
33
+ // always mock "required" `css` files, because we cannot process them
34
+ _require.extensions[".css"] = resolveCss;
35
+ _require.extensions[".scss"] = resolveCss;
36
+ _require.extensions[".sass"] = resolveCss;
37
+ _require.extensions[".less"] = resolveCss;
38
+ // since we are using Vite, we can assume how these will be resolved
39
+ KNOWN_ASSET_TYPES.forEach((type) => {
40
+ _require.extensions[`.${type}`] = resolveAsset;
41
+ });
42
+ process.env.SSR = "";
43
+ } else process.env.SSR = "1";
44
+ // @ts-expect-error not typed global for patched timers
45
+ globalThis.__vitest_required__ = {
46
+ util,
47
+ timers,
48
+ timersPromises
49
+ };
50
+ if (!config.disableConsoleIntercept) await setupConsoleLogSpy();
51
+ }
52
+ function resolveCss(mod) {
53
+ mod.exports = "";
54
+ }
55
+ function resolveAsset(mod, url) {
56
+ mod.exports = url;
57
+ }
58
+ async function setupConsoleLogSpy() {
59
+ const { createCustomConsole } = await import('./console.Cf-YriPC.js');
60
+ globalThis.console = createCustomConsole();
61
+ }
62
+
63
+ // browser shouldn't call this!
64
+ async function run(method, files, config, moduleRunner, environment) {
65
+ const workerState = getWorkerState();
66
+ const [testRunner] = await Promise.all([
67
+ resolveTestRunner(config, moduleRunner),
68
+ setupGlobalEnv(config, environment),
69
+ startCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate }),
70
+ (async () => {
71
+ if (!workerState.config.snapshotOptions.snapshotEnvironment) workerState.config.snapshotOptions.snapshotEnvironment = await resolveSnapshotEnvironment(config, moduleRunner);
72
+ })()
73
+ ]);
74
+ workerState.onCancel((reason) => {
75
+ closeInspector(config);
76
+ testRunner.cancel?.(reason);
77
+ });
78
+ workerState.durations.prepare = performance$1.now() - workerState.durations.prepare;
79
+ for (const file of files) {
80
+ if (config.isolate) {
81
+ moduleRunner.mocker.reset();
82
+ resetModules(workerState.evaluatedModules, true);
83
+ }
84
+ workerState.filepath = file.filepath;
85
+ if (method === "run") await startTests([file], testRunner);
86
+ else await collectTests([file], testRunner);
87
+ // reset after tests, because user might call `vi.setConfig` in setupFile
88
+ vi.resetConfig();
89
+ // mocks should not affect different files
90
+ vi.restoreAllMocks();
91
+ }
92
+ await stopCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.isolate });
93
+ }
94
+
95
+ let _moduleRunner;
96
+ const evaluatedModules = new VitestEvaluatedModules();
97
+ const moduleExecutionInfo = /* @__PURE__ */ new Map();
98
+ function startModuleRunner(options) {
99
+ if (_moduleRunner) return _moduleRunner;
100
+ _moduleRunner = startVitestModuleRunner(options);
101
+ return _moduleRunner;
102
+ }
103
+ let _currentEnvironment;
104
+ let _environmentTime;
105
+ async function setupEnvironment(context) {
106
+ const startTime = performance.now();
107
+ const { environment: { name: environmentName, options: environmentOptions }, rpc, config } = context;
108
+ const { environment, loader } = await loadEnvironment(environmentName, config.root, rpc);
109
+ _currentEnvironment = environment;
110
+ const env = await environment.setup(globalThis, environmentOptions || config.environmentOptions || {});
111
+ _environmentTime = performance.now() - startTime;
112
+ if (config.chaiConfig) setupChaiConfig(config.chaiConfig);
113
+ return async () => {
114
+ await env.teardown(globalThis);
115
+ await loader?.close();
116
+ };
117
+ }
118
+ /** @experimental */
119
+ async function runBaseTests(method, state) {
120
+ const { ctx } = state;
121
+ state.environment = _currentEnvironment;
122
+ state.durations.environment = _environmentTime;
123
+ // state has new context, but we want to reuse existing ones
124
+ state.evaluatedModules = evaluatedModules;
125
+ state.moduleExecutionInfo = moduleExecutionInfo;
126
+ provideWorkerState(globalThis, state);
127
+ if (ctx.invalidates) ctx.invalidates.forEach((filepath) => {
128
+ (state.evaluatedModules.fileToModulesMap.get(filepath) || []).forEach((module) => {
129
+ state.evaluatedModules.invalidateModule(module);
130
+ });
131
+ });
132
+ ctx.files.forEach((i) => {
133
+ const filepath = i.filepath;
134
+ (state.evaluatedModules.fileToModulesMap.get(filepath) || []).forEach((module) => {
135
+ state.evaluatedModules.invalidateModule(module);
136
+ });
137
+ });
138
+ const moduleRunner = startModuleRunner({
139
+ state,
140
+ evaluatedModules: state.evaluatedModules,
141
+ spyModule,
142
+ createImportMeta: createNodeImportMeta
143
+ });
144
+ // we could load @vite/env, but it would take ~8ms, while this takes ~0,02ms
145
+ if (ctx.config.serializedDefines) try {
146
+ runInThisContext(`(() =>{\n${ctx.config.serializedDefines}})()`, {
147
+ lineOffset: 1,
148
+ filename: "virtual:load-defines.js"
149
+ });
150
+ } catch (error) {
151
+ throw new Error(`Failed to load custom "defines": ${error.message}`);
152
+ }
153
+ await run(method, ctx.files, ctx.config, moduleRunner, _currentEnvironment);
154
+ }
155
+
156
+ export { runBaseTests as r, setupEnvironment as s };
@@ -1,9 +1,10 @@
1
1
  import { getCurrentSuite } from '@vitest/runner';
2
2
  import { createChainable } from '@vitest/runner/utils';
3
3
  import { noop } from '@vitest/utils/helpers';
4
- import { g as getWorkerState } from './utils.CG9h5ccR.js';
4
+ import { g as getWorkerState } from './utils.DvEY5TfP.js';
5
5
 
6
- const benchFns = /* @__PURE__ */ new WeakMap(), benchOptsMap = /* @__PURE__ */ new WeakMap();
6
+ const benchFns = /* @__PURE__ */ new WeakMap();
7
+ const benchOptsMap = /* @__PURE__ */ new WeakMap();
7
8
  function getBenchOptions(key) {
8
9
  return benchOptsMap.get(key);
9
10
  }
@@ -16,9 +17,11 @@ const bench = createBenchmark(function(name, fn = noop, options = {}) {
16
17
  ...this,
17
18
  meta: { benchmark: true }
18
19
  });
20
+ benchFns.set(task, fn);
21
+ benchOptsMap.set(task, options);
19
22
  // vitest runner sets mode to `todo` if handler is not passed down
20
23
  // but we store handler separetly
21
- if (benchFns.set(task, fn), benchOptsMap.set(task, options), !this.todo && task.mode === "todo") task.mode = "run";
24
+ if (!this.todo && task.mode === "todo") task.mode = "run";
22
25
  });
23
26
  function createBenchmark(fn) {
24
27
  const benchmark = createChainable([
@@ -26,7 +29,9 @@ function createBenchmark(fn) {
26
29
  "only",
27
30
  "todo"
28
31
  ], fn);
29
- return benchmark.skipIf = (condition) => condition ? benchmark.skip : benchmark, benchmark.runIf = (condition) => condition ? benchmark : benchmark.skip, benchmark;
32
+ benchmark.skipIf = (condition) => condition ? benchmark.skip : benchmark;
33
+ benchmark.runIf = (condition) => condition ? benchmark : benchmark.skip;
34
+ return benchmark;
30
35
  }
31
36
  function formatName(name) {
32
37
  return typeof name === "string" ? name : typeof name === "function" ? name.name || "<anonymous>" : String(name);
@@ -1,5 +1,5 @@
1
1
  import { FileSpecification } from '@vitest/runner';
2
- import { T as TestExecutionMethod } from './worker.d.B4Hthdvt.js';
2
+ import { T as TestExecutionMethod } from './worker.d.DadbA89M.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.BL8Hg4Uk.js';
6
+ import { R as ReportersMap } from './index.kotH7DY7.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.6";
622
+ var version = "4.0.8";
623
623
 
624
624
  const apiConfig = (port) => ({
625
625
  port: {
@@ -634,10 +634,12 @@ const apiConfig = (port) => ({
634
634
  middlewareMode: null
635
635
  });
636
636
  function watermarkTransform(value) {
637
- return typeof value === "string" ? value.split(",").map(Number) : value;
637
+ if (typeof value === "string") return value.split(",").map(Number);
638
+ return value;
638
639
  }
639
640
  function transformNestedBoolean(value) {
640
- return typeof value === "boolean" ? { enabled: value } : value;
641
+ if (typeof value === "boolean") return { enabled: value };
642
+ return value;
641
643
  }
642
644
  const cliOptionsConfig = {
643
645
  root: {
@@ -746,7 +748,9 @@ const cliOptionsConfig = {
746
748
  argument: "<boolean|function>",
747
749
  subcommands: null,
748
750
  transform(value) {
749
- return value === "true" || value === "yes" || value === true ? true : value === "false" || value === "no" || value === false ? false : value;
751
+ if (value === "true" || value === "yes" || value === true) return true;
752
+ if (value === "false" || value === "no" || value === false) return false;
753
+ return value;
750
754
  }
751
755
  },
752
756
  lines: {
@@ -821,12 +825,16 @@ const cliOptionsConfig = {
821
825
  description: "Run tests in the browser. Equivalent to `--browser.enabled` (default: `false`)",
822
826
  argument: "<name>",
823
827
  transform(browser) {
824
- return typeof browser === "boolean" ? { enabled: browser } : browser === "true" || browser === "false" ? { enabled: browser === "true" } : browser === "yes" || browser === "no" ? { enabled: browser === "yes" } : typeof browser === "string" ? { name: browser } : browser;
828
+ if (typeof browser === "boolean") return { enabled: browser };
829
+ if (browser === "true" || browser === "false") return { enabled: browser === "true" };
830
+ if (browser === "yes" || browser === "no") return { enabled: browser === "yes" };
831
+ if (typeof browser === "string") return { name: browser };
832
+ return browser;
825
833
  },
826
834
  subcommands: {
827
835
  enabled: { description: "Run tests in the browser. Equivalent to `--browser.enabled` (default: `false`)" },
828
836
  name: {
829
- description: "Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`). Visit [`browser.name`](https://vitest.dev/guide/browser/config/#browser-name) for more information",
837
+ description: "Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`).",
830
838
  argument: "<name>"
831
839
  },
832
840
  headless: { description: "Run the browser in headless mode (i.e. without opening the GUI (Graphical User Interface)). If you are running Vitest in CI, it will be enabled by default (default: `process.env.CI`)" },
@@ -836,7 +844,7 @@ const cliOptionsConfig = {
836
844
  subcommands: apiConfig(defaultBrowserPort)
837
845
  },
838
846
  provider: {
839
- description: "Provider used to run browser tests. Some browsers are only available for specific providers. Can be \"webdriverio\", \"playwright\", \"preview\", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/guide/browser/config.html#browser-provider) for more information (default: `\"preview\"`)",
847
+ description: "Provider used to run browser tests. Some browsers are only available for specific providers. Can be \"webdriverio\", \"playwright\", \"preview\", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/config/browser/provider) for more information",
840
848
  argument: "<name>",
841
849
  subcommands: null,
842
850
  transform(value) {
@@ -886,7 +894,8 @@ const cliOptionsConfig = {
886
894
  },
887
895
  execArgv: {
888
896
  description: "Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`.",
889
- argument: "<option>"
897
+ argument: "<option>",
898
+ array: true
890
899
  },
891
900
  vmMemoryLimit: {
892
901
  description: "Memory limit for VM pools. If you see memory leaks, try to tinker this value.",
@@ -946,14 +955,18 @@ const cliOptionsConfig = {
946
955
  description: "Enable Node.js inspector (default: `127.0.0.1:9229`)",
947
956
  argument: "[[host:]port]",
948
957
  transform(portOrEnabled) {
949
- return portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes" ? true : portOrEnabled === "false" || portOrEnabled === "no" ? false : portOrEnabled;
958
+ if (portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes") return true;
959
+ if (portOrEnabled === "false" || portOrEnabled === "no") return false;
960
+ return portOrEnabled;
950
961
  }
951
962
  },
952
963
  inspectBrk: {
953
964
  description: "Enable Node.js inspector and break before the test starts",
954
965
  argument: "[[host:]port]",
955
966
  transform(portOrEnabled) {
956
- return portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes" ? true : portOrEnabled === "false" || portOrEnabled === "no" ? false : portOrEnabled;
967
+ if (portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes") return true;
968
+ if (portOrEnabled === "false" || portOrEnabled === "no") return false;
969
+ return portOrEnabled;
957
970
  }
958
971
  },
959
972
  inspector: null,
@@ -1077,7 +1090,8 @@ const cliOptionsConfig = {
1077
1090
  default: true,
1078
1091
  transform(cache) {
1079
1092
  if (typeof cache !== "boolean" && cache) throw new Error("--cache.dir is deprecated");
1080
- return cache && {};
1093
+ if (cache) return {};
1094
+ return cache;
1081
1095
  }
1082
1096
  },
1083
1097
  maxConcurrency: {
@@ -1134,7 +1148,8 @@ const cliOptionsConfig = {
1134
1148
  description: "Path to a blob reports directory. If this options is used, Vitest won't run any tests, it will only report previously recorded tests",
1135
1149
  argument: "[path]",
1136
1150
  transform(value) {
1137
- return !value || typeof value === "boolean" ? ".vitest-reports" : value;
1151
+ if (!value || typeof value === "boolean") return ".vitest-reports";
1152
+ return value;
1138
1153
  }
1139
1154
  },
1140
1155
  cliExclude: null,
@@ -1204,7 +1219,11 @@ function addCommand(cli, name, option) {
1204
1219
  const received = value.map((s) => typeof s === "string" ? `"${s}"` : s).join(", ");
1205
1220
  throw new Error(`Expected a single value for option "${command}", received [${received}]`);
1206
1221
  }
1207
- return value = removeQuotes(value), option.transform ? option.transform(value) : option.array ? toArray(value) : option.normalize ? normalize(String(value)) : value;
1222
+ value = removeQuotes(value);
1223
+ if (option.transform) return option.transform(value);
1224
+ if (option.array) return toArray(value);
1225
+ if (option.normalize) return normalize(String(value));
1226
+ return value;
1208
1227
  }
1209
1228
  const hasSubcommands = "subcommands" in option && option.subcommands;
1210
1229
  if (option.description) {
@@ -1222,16 +1241,24 @@ function addCliOptions(cli, options) {
1222
1241
  }
1223
1242
  function createCLI(options = {}) {
1224
1243
  const cli = cac("vitest");
1225
- return cli.version(version), addCliOptions(cli, cliOptionsConfig), cli.help((info) => {
1244
+ cli.version(version);
1245
+ addCliOptions(cli, cliOptionsConfig);
1246
+ cli.help((info) => {
1226
1247
  const helpSection = info.find((current) => current.title?.startsWith("For more info, run any command"));
1227
1248
  if (helpSection) helpSection.body += "\n $ vitest --help --expand-help";
1228
1249
  const options = info.find((current) => current.title === "Options");
1229
1250
  if (typeof options !== "object") return info;
1230
- const helpIndex = process.argv.findIndex((arg) => arg === "--help"), subcommands = process.argv.slice(helpIndex + 1), defaultOutput = options.body.split("\n").filter((line) => /^\s+--\S+\./.test(line) === false).join("\n");
1251
+ const helpIndex = process.argv.findIndex((arg) => arg === "--help");
1252
+ const subcommands = process.argv.slice(helpIndex + 1);
1253
+ const defaultOutput = options.body.split("\n").filter((line) => /^\s+--\S+\./.test(line) === false).join("\n");
1231
1254
  // Filter out options with dot-notation if --help is not called with a subcommand (default behavior)
1232
- if (subcommands.length === 0) return options.body = defaultOutput, info;
1255
+ if (subcommands.length === 0) {
1256
+ options.body = defaultOutput;
1257
+ return info;
1258
+ }
1233
1259
  if (subcommands.length === 1 && (subcommands[0] === "--expand-help" || subcommands[0] === "--expandHelp")) return info;
1234
- const subcommandMarker = "$SUB_COMMAND_MARKER$", banner = info.find((current) => /^vitest\/\d+\.\d+\.\d+$/.test(current.body));
1260
+ const subcommandMarker = "$SUB_COMMAND_MARKER$";
1261
+ const banner = info.find((current) => /^vitest\/\d+\.\d+\.\d+$/.test(current.body));
1235
1262
  function addBannerWarning(warning) {
1236
1263
  if (typeof banner?.body === "string") {
1237
1264
  if (banner?.body.includes(warning)) return;
@@ -1249,67 +1276,111 @@ function createCLI(options = {}) {
1249
1276
  // Mark the help section for the subcommands
1250
1277
  if (subcommand.startsWith("--")) options.body = options.body.split("\n").map((line) => line.trim().startsWith(subcommand) ? `${subcommandMarker}${line}` : line).join("\n");
1251
1278
  }
1252
- if (options.body = options.body.split("\n").map((line) => line.startsWith(subcommandMarker) ? line.split(subcommandMarker)[1] : "").filter((line) => line.length !== 0).join("\n"), !options.body) addBannerWarning("no options were found for your subcommands so we printed the whole output"), options.body = defaultOutput;
1279
+ // Filter based on the marked options to preserve the original sort order
1280
+ options.body = options.body.split("\n").map((line) => line.startsWith(subcommandMarker) ? line.split(subcommandMarker)[1] : "").filter((line) => line.length !== 0).join("\n");
1281
+ if (!options.body) {
1282
+ addBannerWarning("no options were found for your subcommands so we printed the whole output");
1283
+ options.body = defaultOutput;
1284
+ }
1253
1285
  return info;
1254
- }), cli.command("run [...filters]", void 0, options).action(run), cli.command("related [...filters]", void 0, options).action(runRelated), cli.command("watch [...filters]", void 0, options).action(watch), cli.command("dev [...filters]", void 0, options).action(watch), addCliOptions(cli.command("bench [...filters]", void 0, options).action(benchmark), benchCliOptionsConfig), cli.command("init <project>", void 0, options).action(init), addCliOptions(cli.command("list [...filters]", void 0, options).action((filters, options) => collect("test", filters, options)), collectCliOptionsConfig), cli.command("[...filters]", void 0, options).action((filters, options) => start("test", filters, options)), cli;
1286
+ });
1287
+ cli.command("run [...filters]", void 0, options).action(run);
1288
+ cli.command("related [...filters]", void 0, options).action(runRelated);
1289
+ cli.command("watch [...filters]", void 0, options).action(watch);
1290
+ cli.command("dev [...filters]", void 0, options).action(watch);
1291
+ addCliOptions(cli.command("bench [...filters]", void 0, options).action(benchmark), benchCliOptionsConfig);
1292
+ cli.command("init <project>", void 0, options).action(init);
1293
+ addCliOptions(cli.command("list [...filters]", void 0, options).action((filters, options) => collect("test", filters, options)), collectCliOptionsConfig);
1294
+ cli.command("[...filters]", void 0, options).action((filters, options) => start("test", filters, options));
1295
+ return cli;
1255
1296
  }
1256
1297
  function removeQuotes(str) {
1257
- return typeof str === "string" ? str[0] === "\"" && str.endsWith("\"") || str.startsWith(`'`) && str.endsWith(`'`) ? str.slice(1, -1) : str : Array.isArray(str) ? str.map(removeQuotes) : str;
1298
+ if (typeof str !== "string") {
1299
+ if (Array.isArray(str)) return str.map(removeQuotes);
1300
+ return str;
1301
+ }
1302
+ if (str[0] === "\"" && str.endsWith("\"")) return str.slice(1, -1);
1303
+ if (str.startsWith(`'`) && str.endsWith(`'`)) return str.slice(1, -1);
1304
+ return str;
1258
1305
  }
1259
1306
  function splitArgv(argv) {
1260
- return argv = argv.replace(/(['"])(?:(?!\1).)+\1/g, (match) => match.replace(/\s/g, "\0")), argv.split(" ").map((arg) => {
1261
- return arg = arg.replace(/\0/g, " "), removeQuotes(arg);
1307
+ argv = argv.replace(/(['"])(?:(?!\1).)+\1/g, (match) => match.replace(/\s/g, "\0"));
1308
+ return argv.split(" ").map((arg) => {
1309
+ arg = arg.replace(/\0/g, " ");
1310
+ return removeQuotes(arg);
1262
1311
  });
1263
1312
  }
1264
1313
  function parseCLI(argv, config = {}) {
1265
1314
  const arrayArgs = typeof argv === "string" ? splitArgv(argv) : argv;
1266
1315
  if (arrayArgs[0] !== "vitest") throw new Error(`Expected "vitest" as the first argument, received "${arrayArgs[0]}"`);
1267
- arrayArgs[0] = "/index.js", arrayArgs.unshift("node");
1316
+ arrayArgs[0] = "/index.js";
1317
+ arrayArgs.unshift("node");
1268
1318
  let { args, options } = createCLI(config).parse(arrayArgs, { run: false });
1269
1319
  if (arrayArgs[2] === "watch" || arrayArgs[2] === "dev") options.watch = true;
1270
1320
  if (arrayArgs[2] === "run" && !options.watch) options.run = true;
1271
- if (arrayArgs[2] === "related") options.related = args, options.passWithNoTests ??= true, args = [];
1321
+ if (arrayArgs[2] === "related") {
1322
+ options.related = args;
1323
+ options.passWithNoTests ??= true;
1324
+ args = [];
1325
+ }
1272
1326
  return {
1273
1327
  filter: args,
1274
1328
  options
1275
1329
  };
1276
1330
  }
1277
1331
  async function runRelated(relatedFiles, argv) {
1278
- argv.related = relatedFiles, argv.passWithNoTests ??= true, await start("test", [], argv);
1332
+ argv.related = relatedFiles;
1333
+ argv.passWithNoTests ??= true;
1334
+ await start("test", [], argv);
1279
1335
  }
1280
1336
  async function watch(cliFilters, options) {
1281
- options.watch = true, await start("test", cliFilters, options);
1337
+ options.watch = true;
1338
+ await start("test", cliFilters, options);
1282
1339
  }
1283
1340
  async function run(cliFilters, options) {
1284
- options.run = !options.watch, await start("test", cliFilters, options);
1341
+ // "vitest run --watch" should still be watch mode
1342
+ options.run = !options.watch;
1343
+ await start("test", cliFilters, options);
1285
1344
  }
1286
1345
  async function benchmark(cliFilters, options) {
1287
- console.warn(c.yellow("Benchmarking is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest's version when using it.")), await start("benchmark", cliFilters, options);
1346
+ console.warn(c.yellow("Benchmarking is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest's version when using it."));
1347
+ await start("benchmark", cliFilters, options);
1288
1348
  }
1289
1349
  function normalizeCliOptions(cliFilters, argv) {
1290
- if (argv.exclude) argv.cliExclude = toArray(argv.exclude), delete argv.exclude;
1350
+ if (argv.exclude) {
1351
+ argv.cliExclude = toArray(argv.exclude);
1352
+ delete argv.exclude;
1353
+ }
1291
1354
  if (cliFilters.some((filter) => filter.includes(":"))) argv.includeTaskLocation ??= true;
1292
1355
  if (typeof argv.typecheck?.only === "boolean") argv.typecheck.enabled ??= true;
1293
1356
  return argv;
1294
1357
  }
1295
1358
  async function start(mode, cliFilters, options) {
1296
1359
  try {
1297
- const { startVitest } = await import('./cli-api.UL3SwFUb.js').then(function (n) { return n.p; }), ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1360
+ const { startVitest } = await import('./cli-api.BQ-bjcRi.js').then(function (n) { return n.p; });
1361
+ const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1298
1362
  if (!ctx.shouldKeepServer()) await ctx.exit();
1299
1363
  } catch (e) {
1300
- const { errorBanner } = await import('./index.BL8Hg4Uk.js').then(function (n) { return n.u; });
1301
- if (console.error(`\n${errorBanner("Startup Error")}`), console.error(e), console.error("\n\n"), process.exitCode == null) process.exitCode = 1;
1364
+ const { errorBanner } = await import('./index.kotH7DY7.js').then(function (n) { return n.u; });
1365
+ console.error(`\n${errorBanner("Startup Error")}`);
1366
+ console.error(e);
1367
+ console.error("\n\n");
1368
+ if (process.exitCode == null) process.exitCode = 1;
1302
1369
  process.exit();
1303
1370
  }
1304
1371
  }
1305
1372
  async function init(project) {
1306
- if (project !== "browser") console.error(/* @__PURE__ */ new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project.")), process.exit(1);
1307
- const { create } = await import('./creator.cqqifzG7.js');
1373
+ if (project !== "browser") {
1374
+ console.error(/* @__PURE__ */ new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project."));
1375
+ process.exit(1);
1376
+ }
1377
+ const { create } = await import('./creator.fzVyoMf3.js');
1308
1378
  await create();
1309
1379
  }
1310
1380
  async function collect(mode, cliFilters, options) {
1311
1381
  try {
1312
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.UL3SwFUb.js').then(function (n) { return n.p; }), ctx = await prepareVitest(mode, {
1382
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.BQ-bjcRi.js').then(function (n) { return n.p; });
1383
+ const ctx = await prepareVitest(mode, {
1313
1384
  ...normalizeCliOptions(cliFilters, options),
1314
1385
  watch: false,
1315
1386
  run: true
@@ -1317,18 +1388,21 @@ async function collect(mode, cliFilters, options) {
1317
1388
  if (!options.filesOnly) {
1318
1389
  const { testModules: tests, unhandledErrors: errors } = await ctx.collect(cliFilters.map(normalize));
1319
1390
  if (errors.length) {
1320
- console.error("\nThere were unhandled errors during test collection"), errors.forEach((e) => console.error(e)), console.error("\n\n"), await ctx.close();
1391
+ console.error("\nThere were unhandled errors during test collection");
1392
+ errors.forEach((e) => console.error(e));
1393
+ console.error("\n\n");
1394
+ await ctx.close();
1321
1395
  return;
1322
1396
  }
1323
1397
  processCollected(ctx, tests, options);
1324
- } else {
1325
- const files = await ctx.getRelevantTestSpecifications(cliFilters.map(normalize));
1326
- outputFileList(files, options);
1327
- }
1398
+ } else outputFileList(await ctx.getRelevantTestSpecifications(cliFilters.map(normalize)), options);
1328
1399
  await ctx.close();
1329
1400
  } catch (e) {
1330
- const { errorBanner } = await import('./index.BL8Hg4Uk.js').then(function (n) { return n.u; });
1331
- if (console.error(`\n${errorBanner("Collect Error")}`), console.error(e), console.error("\n\n"), process.exitCode == null) process.exitCode = 1;
1401
+ const { errorBanner } = await import('./index.kotH7DY7.js').then(function (n) { return n.u; });
1402
+ console.error(`\n${errorBanner("Collect Error")}`);
1403
+ console.error(e);
1404
+ console.error("\n\n");
1405
+ if (process.exitCode == null) process.exitCode = 1;
1332
1406
  process.exit();
1333
1407
  }
1334
1408
  }