vitest 4.0.0-beta.1 → 4.0.0-beta.3

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 (59) hide show
  1. package/dist/browser.d.ts +6 -6
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{base.Bj3pWTr1.js → base.D5_IXzht.js} +2 -2
  4. package/dist/chunks/{benchmark.d.BwvBVTda.d.ts → benchmark.d.DAaHLpsq.d.ts} +4 -4
  5. package/dist/chunks/{browser.d.q8Z0P0q1.d.ts → browser.d.BSPEQIuf.d.ts} +5 -5
  6. package/dist/chunks/{cac.D3EzDDZd.js → cac.C30xmylc.js} +11 -18
  7. package/dist/chunks/{cli-api.Dn5gKePv.js → cli-api.DE98RCgs.js} +53 -80
  8. package/dist/chunks/{config.d.HJdfX-8k.d.ts → config.d.DZo8c7fw.d.ts} +58 -58
  9. package/dist/chunks/{console.CtFJOzRO.js → console.DoJHFxmj.js} +3 -3
  10. package/dist/chunks/{constants.DnKduX2e.js → constants.CXzqaLmq.js} +1 -4
  11. package/dist/chunks/{coverage.Cwa-XhJt.js → coverage.OOpN1tMC.js} +54 -46
  12. package/dist/chunks/{coverage.d.S9RMNXIe.d.ts → coverage.d.CNYjU4GF.d.ts} +4 -4
  13. package/dist/chunks/{creator.GK6I-cL4.js → creator.CJNzQTzZ.js} +5 -5
  14. package/dist/chunks/{environment.d.CUq4cUgQ.d.ts → environment.d.Bhm9oc0v.d.ts} +1 -1
  15. package/dist/chunks/{execute.B7h3T_Hc.js → execute.Dt-pCVcL.js} +1 -1
  16. package/dist/chunks/{global.d.CVbXEflG.d.ts → global.d.DAhT2emn.d.ts} +2 -2
  17. package/dist/chunks/{globals.Cxal6MLI.js → globals.Dgo-vS5G.js} +3 -3
  18. package/dist/chunks/{index.CZI_8rVt.js → index.Bz6b0Ib7.js} +5 -5
  19. package/dist/chunks/{index.BWf_gE5n.js → index.D1_MsKEt.js} +1 -1
  20. package/dist/chunks/{index.TfbsX-3I.js → index.D3SKT3tv.js} +1 -1
  21. package/dist/chunks/{index.D-VkfKhf.js → index.Dppt57hu.js} +1 -1
  22. package/dist/chunks/{plugin.d.C2EcJUjo.d.ts → plugin.d.CKCmge5g.d.ts} +1 -1
  23. package/dist/chunks/{reporters.d.DxZg19fy.d.ts → reporters.d.BBuiUFDc.d.ts} +115 -145
  24. package/dist/chunks/{runBaseTests.BC7ZIH5L.js → runBaseTests.Bbi_gTJQ.js} +5 -5
  25. package/dist/chunks/{setup-common.D7ZqXFx-.js → setup-common.Ebx5x0eP.js} +1 -1
  26. package/dist/chunks/{suite.d.FvehnV49.d.ts → suite.d.BJWk38HB.d.ts} +1 -1
  27. package/dist/chunks/{typechecker.CVytUJuF.js → typechecker.CMNPqJOo.js} +3 -3
  28. package/dist/chunks/{utils.CAioKnHs.js → utils.CcGm2cd1.js} +1 -1
  29. package/dist/chunks/{vi.bdSIJ99Y.js → vi.CA0EPI9Y.js} +11 -11
  30. package/dist/chunks/{vm.BThCzidc.js → vm.BUnLJt_P.js} +11 -3
  31. package/dist/chunks/{worker.d.CmvJfRGs.d.ts → worker.d.DyXSTmRq.d.ts} +1 -1
  32. package/dist/chunks/{worker.d.DoNjFAiv.d.ts → worker.d.xTcinSQw.d.ts} +9 -15
  33. package/dist/cli.js +4 -4
  34. package/dist/config.d.ts +44 -44
  35. package/dist/config.js +1 -1
  36. package/dist/coverage.d.ts +20 -18
  37. package/dist/coverage.js +3 -3
  38. package/dist/environments.d.ts +9 -9
  39. package/dist/execute.d.ts +7 -7
  40. package/dist/execute.js +1 -1
  41. package/dist/index.d.ts +29 -27
  42. package/dist/index.js +2 -2
  43. package/dist/node.d.ts +23 -24
  44. package/dist/node.js +9 -9
  45. package/dist/reporters.d.ts +7 -7
  46. package/dist/reporters.js +3 -3
  47. package/dist/runners.d.ts +1 -1
  48. package/dist/runners.js +10 -3
  49. package/dist/suite.d.ts +2 -2
  50. package/dist/worker.js +1 -1
  51. package/dist/workers/forks.js +3 -3
  52. package/dist/workers/runVmTests.js +4 -4
  53. package/dist/workers/threads.js +3 -3
  54. package/dist/workers/vmForks.js +4 -4
  55. package/dist/workers/vmThreads.js +4 -4
  56. package/dist/workers.d.ts +4 -4
  57. package/dist/workers.js +5 -5
  58. package/globals.d.ts +17 -17
  59. package/package.json +17 -17
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as SerializedCoverageConfig, a as SerializedConfig } from './chunks/config.d.HJdfX-8k.js';
2
- import { R as RuntimeCoverageModuleLoader } from './chunks/coverage.d.S9RMNXIe.js';
1
+ import { S as SerializedCoverageConfig, a as SerializedConfig } from './chunks/config.d.DZo8c7fw.js';
2
+ import { R as RuntimeCoverageModuleLoader } from './chunks/coverage.d.CNYjU4GF.js';
3
3
  import { SerializedDiffOptions } from '@vitest/utils/diff';
4
4
  import { VitestExecutor } from './execute.js';
5
5
  export { collectTests, processError, startTests } from '@vitest/runner';
@@ -11,18 +11,18 @@ import '@vitest/pretty-format';
11
11
  import '@vitest/snapshot';
12
12
  import 'vite-node/client';
13
13
  import 'vite-node';
14
- import './chunks/worker.d.DoNjFAiv.js';
15
- import './chunks/environment.d.CUq4cUgQ.js';
14
+ import './chunks/worker.d.xTcinSQw.js';
15
+ import './chunks/environment.d.Bhm9oc0v.js';
16
16
  import 'node:vm';
17
17
  import '@vitest/mocker';
18
18
  import './chunks/mocker.d.BE_2ls6u.js';
19
19
 
20
20
  declare function startCoverageInsideWorker(options: SerializedCoverageConfig | undefined, loader: RuntimeCoverageModuleLoader, runtimeOptions: {
21
- isolate: boolean
21
+ isolate: boolean;
22
22
  }): Promise<unknown>;
23
23
  declare function takeCoverageInsideWorker(options: SerializedCoverageConfig | undefined, loader: RuntimeCoverageModuleLoader): Promise<unknown>;
24
24
  declare function stopCoverageInsideWorker(options: SerializedCoverageConfig | undefined, loader: RuntimeCoverageModuleLoader, runtimeOptions: {
25
- isolate: boolean
25
+ isolate: boolean;
26
26
  }): Promise<unknown>;
27
27
 
28
28
  declare function setupCommonEnv(config: SerializedConfig): Promise<void>;
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.D7ZqXFx-.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.Ebx5x0eP.js';
2
2
  export { collectTests, processError, startTests } from '@vitest/runner';
3
3
  import * as spy from '@vitest/spy';
4
4
  export { spy as SpyModule };
@@ -1,5 +1,5 @@
1
1
  import { ModuleCacheMap } from 'vite-node/client';
2
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.B7h3T_Hc.js';
2
+ import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.Dt-pCVcL.js';
3
3
  import { p as provideWorkerState } from './utils.XdZDrNZV.js';
4
4
 
5
5
  let _viteNode;
@@ -24,7 +24,7 @@ async function runBaseTests(method, state) {
24
24
  const [executor, { run }] = await Promise.all([startViteNode({
25
25
  state,
26
26
  requestStubs: getDefaultRequestStubs()
27
- }), import('./runBaseTests.BC7ZIH5L.js')]);
27
+ }), import('./runBaseTests.Bbi_gTJQ.js')]);
28
28
  const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
29
29
  filepath: f,
30
30
  testLocations: void 0
@@ -4,8 +4,8 @@ import { TaskResult, Bench, Options } from 'tinybench';
4
4
 
5
5
  interface Benchmark extends Test {
6
6
  meta: {
7
- benchmark: true
8
- result?: TaskResult
7
+ benchmark: true;
8
+ result?: TaskResult;
9
9
  };
10
10
  }
11
11
  interface BenchmarkResult extends TaskResult {
@@ -17,8 +17,8 @@ interface BenchmarkResult extends TaskResult {
17
17
  type BenchFunction = (this: Bench) => Promise<void> | void;
18
18
  type ChainableBenchmarkAPI = ChainableFunction<"skip" | "only" | "todo", (name: string | Function, fn?: BenchFunction, options?: Options) => void>;
19
19
  type BenchmarkAPI = ChainableBenchmarkAPI & {
20
- skipIf: (condition: any) => ChainableBenchmarkAPI
21
- runIf: (condition: any) => ChainableBenchmarkAPI
20
+ skipIf: (condition: any) => ChainableBenchmarkAPI;
21
+ runIf: (condition: any) => ChainableBenchmarkAPI;
22
22
  };
23
23
 
24
24
  export type { BenchmarkResult as B, BenchFunction as a, Benchmark as b, BenchmarkAPI as c };
@@ -1,11 +1,11 @@
1
- import { T as TestExecutionMethod } from './worker.d.DoNjFAiv.js';
1
+ import { T as TestExecutionMethod } from './worker.d.xTcinSQw.js';
2
2
 
3
3
  type SerializedTestSpecification = [project: {
4
- name: string | undefined
5
- root: string
4
+ name: string | undefined;
5
+ root: string;
6
6
  }, file: string, options: {
7
- pool: string
8
- testLines?: number[] | undefined
7
+ pool: string;
8
+ testLines?: number[] | undefined;
9
9
  }];
10
10
 
11
11
  interface BrowserTesterOptions {
@@ -2,8 +2,8 @@ import { toArray } from '@vitest/utils';
2
2
  import { EventEmitter } from 'events';
3
3
  import { normalize } from 'pathe';
4
4
  import c from 'tinyrainbow';
5
- import { a as defaultPort, d as defaultBrowserPort } from './constants.DnKduX2e.js';
6
- import { R as ReportersMap } from './index.CZI_8rVt.js';
5
+ import { a as defaultPort, d as defaultBrowserPort } from './constants.CXzqaLmq.js';
6
+ import { R as ReportersMap } from './index.Bz6b0Ib7.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.0-beta.1";
622
+ var version = "4.0.0-beta.3";
623
623
 
624
624
  const apiConfig = (port) => ({
625
625
  port: {
@@ -836,11 +836,6 @@ const cliOptionsConfig = {
836
836
  description: "Override Vite mode (default: `test` or `benchmark`)",
837
837
  argument: "<name>"
838
838
  },
839
- workspace: {
840
- description: "[deprecated] Path to a workspace configuration file",
841
- argument: "<path>",
842
- normalize: true
843
- },
844
839
  isolate: { description: "Run every test file in isolation. To disable isolation, use `--no-isolate` (default: `true`)" },
845
840
  globals: { description: "Inject apis globally" },
846
841
  dom: { description: "Mock browser API with happy-dom" },
@@ -1183,7 +1178,7 @@ const cliOptionsConfig = {
1183
1178
  description: "Use `bundle` to bundle the config with esbuild or `runner` (experimental) to process it on the fly. This is only available in vite version 6.1.0 and above. (default: `bundle`)",
1184
1179
  argument: "<loader>"
1185
1180
  },
1186
- standalone: { description: "Start Vitest without running tests. File filters will be ignored, tests will be running only on change (default: `false`)" },
1181
+ standalone: { description: "Start Vitest without running tests. Tests will be running only on change. This option is ignored when CLI file filters are passed. (default: `false`)" },
1187
1182
  mergeReports: {
1188
1183
  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",
1189
1184
  argument: "[path]",
@@ -1201,7 +1196,6 @@ const cliOptionsConfig = {
1201
1196
  includeSource: null,
1202
1197
  alias: null,
1203
1198
  env: null,
1204
- environmentMatchGlobs: null,
1205
1199
  environmentOptions: null,
1206
1200
  unstubEnvs: null,
1207
1201
  related: null,
@@ -1218,7 +1212,6 @@ const cliOptionsConfig = {
1218
1212
  chaiConfig: null,
1219
1213
  clearMocks: null,
1220
1214
  css: null,
1221
- poolMatchGlobs: null,
1222
1215
  deps: null,
1223
1216
  name: null,
1224
1217
  snapshotEnvironment: null,
@@ -1399,11 +1392,11 @@ async function start(mode, cliFilters, options) {
1399
1392
  process.title = "node (vitest)";
1400
1393
  } catch {}
1401
1394
  try {
1402
- const { startVitest } = await import('./cli-api.Dn5gKePv.js').then(function (n) { return n.f; });
1395
+ const { startVitest } = await import('./cli-api.DE98RCgs.js').then(function (n) { return n.f; });
1403
1396
  const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1404
1397
  if (!ctx.shouldKeepServer()) await ctx.exit();
1405
1398
  } catch (e) {
1406
- const { errorBanner } = await import('./index.CZI_8rVt.js').then(function (n) { return n.u; });
1399
+ const { errorBanner } = await import('./index.Bz6b0Ib7.js').then(function (n) { return n.u; });
1407
1400
  console.error(`\n${errorBanner("Startup Error")}`);
1408
1401
  console.error(e);
1409
1402
  console.error("\n\n");
@@ -1413,10 +1406,10 @@ async function start(mode, cliFilters, options) {
1413
1406
  }
1414
1407
  async function init(project) {
1415
1408
  if (project !== "browser") {
1416
- console.error(new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project."));
1409
+ console.error(/* @__PURE__ */ new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project."));
1417
1410
  process.exit(1);
1418
1411
  }
1419
- const { create } = await import('./creator.GK6I-cL4.js');
1412
+ const { create } = await import('./creator.CJNzQTzZ.js');
1420
1413
  await create();
1421
1414
  }
1422
1415
  async function collect(mode, cliFilters, options) {
@@ -1424,12 +1417,12 @@ async function collect(mode, cliFilters, options) {
1424
1417
  process.title = "node (vitest)";
1425
1418
  } catch {}
1426
1419
  try {
1427
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.Dn5gKePv.js').then(function (n) { return n.f; });
1420
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.DE98RCgs.js').then(function (n) { return n.f; });
1428
1421
  const ctx = await prepareVitest(mode, {
1429
1422
  ...normalizeCliOptions(cliFilters, options),
1430
1423
  watch: false,
1431
1424
  run: true
1432
- });
1425
+ }, void 0, void 0, cliFilters);
1433
1426
  if (!options.filesOnly) {
1434
1427
  const { testModules: tests, unhandledErrors: errors } = await ctx.collect(cliFilters.map(normalize));
1435
1428
  if (errors.length) {
@@ -1446,7 +1439,7 @@ async function collect(mode, cliFilters, options) {
1446
1439
  }
1447
1440
  await ctx.close();
1448
1441
  } catch (e) {
1449
- const { errorBanner } = await import('./index.CZI_8rVt.js').then(function (n) { return n.u; });
1442
+ const { errorBanner } = await import('./index.Bz6b0Ib7.js').then(function (n) { return n.u; });
1450
1443
  console.error(`\n${errorBanner("Collect Error")}`);
1451
1444
  console.error(e);
1452
1445
  console.error("\n\n");
@@ -6,14 +6,14 @@ import { noop, isPrimitive, createDefer, slash, highlight, toArray, deepMerge, n
6
6
  import { f as findUp, p as prompt } from './index.X0nbfr6-.js';
7
7
  import * as vite from 'vite';
8
8
  import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
9
- import { A as API_PATH, c as configFiles, d as defaultBrowserPort, w as workspacesFiles, a as defaultPort } from './constants.DnKduX2e.js';
9
+ import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.CXzqaLmq.js';
10
10
  import { generateFileHash, limitConcurrency, createFileTask, hasFailed, getTasks, getTests } from '@vitest/runner/utils';
11
11
  import { SnapshotManager } from '@vitest/snapshot/manager';
12
12
  import { ViteNodeRunner } from 'vite-node/client';
13
13
  import { ViteNodeServer } from 'vite-node/server';
14
- import { v as version$1 } from './cac.D3EzDDZd.js';
14
+ import { v as version$1 } from './cac.C30xmylc.js';
15
15
  import { c as createBirpc } from './index.B521nVV-.js';
16
- import { p as parse, s as stringify, d as printError, f as formatProjectName, w as withLabel, e as errorBanner, h as divider, i as generateCodeFrame, R as ReportersMap, B as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.CZI_8rVt.js';
16
+ import { p as parse, s as stringify, d as printError, f as formatProjectName, w as withLabel, e as errorBanner, h as divider, i as generateCodeFrame, R as ReportersMap, B as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.Bz6b0Ib7.js';
17
17
  import require$$0$3 from 'events';
18
18
  import require$$1$1 from 'https';
19
19
  import require$$2 from 'http';
@@ -28,8 +28,8 @@ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
28
28
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
29
29
  import crypto, { createHash } from 'node:crypto';
30
30
  import { distDir, rootDir } from '../path.js';
31
- import { h as hash, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, d as isBrowserEnabled, r as resolveConfig, e as groupBy, f as getCoverageProvider, j as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.Cwa-XhJt.js';
32
- import { c as convertTasksToEvents } from './typechecker.CVytUJuF.js';
31
+ import { h as hash, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, d as isBrowserEnabled, r as resolveConfig, e as groupBy, f as getCoverageProvider, j as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.OOpN1tMC.js';
32
+ import { c as convertTasksToEvents } from './typechecker.CMNPqJOo.js';
33
33
  import { Console } from 'node:console';
34
34
  import c from 'tinyrainbow';
35
35
  import { createRequire } from 'node:module';
@@ -43,7 +43,7 @@ import { normalizeRequestId, cleanUrl } from 'vite-node/utils';
43
43
  import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
44
44
  import { c as configDefaults } from './defaults.CXFFjsi8.js';
45
45
  import MagicString from 'magic-string';
46
- import { a as BenchmarkReportsMap } from './index.TfbsX-3I.js';
46
+ import { a as BenchmarkReportsMap } from './index.D3SKT3tv.js';
47
47
  import assert$1 from 'node:assert';
48
48
  import { serializeError } from '@vitest/utils/error';
49
49
  import readline from 'node:readline';
@@ -4717,9 +4717,11 @@ function requireWebsocketServer () {
4717
4717
  return;
4718
4718
  }
4719
4719
 
4720
- if (version !== 8 && version !== 13) {
4720
+ if (version !== 13 && version !== 8) {
4721
4721
  const message = 'Missing or invalid Sec-WebSocket-Version header';
4722
- abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
4722
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
4723
+ 'Sec-WebSocket-Version': '13, 8'
4724
+ });
4723
4725
  return;
4724
4726
  }
4725
4727
 
@@ -4987,16 +4989,24 @@ function requireWebsocketServer () {
4987
4989
  * @param {Duplex} socket The socket of the upgrade request
4988
4990
  * @param {Number} code The HTTP response status code
4989
4991
  * @param {String} message The HTTP response body
4992
+ * @param {Object} [headers] The HTTP response headers
4990
4993
  * @private
4991
4994
  */
4992
- function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {
4995
+ function abortHandshakeOrEmitwsClientError(
4996
+ server,
4997
+ req,
4998
+ socket,
4999
+ code,
5000
+ message,
5001
+ headers
5002
+ ) {
4993
5003
  if (server.listenerCount('wsClientError')) {
4994
5004
  const err = new Error(message);
4995
5005
  Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
4996
5006
 
4997
5007
  server.emit('wsClientError', err, socket, req);
4998
5008
  } else {
4999
- abortHandshake(socket, code, message);
5009
+ abortHandshake(socket, code, message, headers);
5000
5010
  }
5001
5011
  }
5002
5012
  return websocketServer;
@@ -5120,9 +5130,6 @@ function setup(ctx, _server) {
5120
5130
  getConfig() {
5121
5131
  return ctx.getRootProject().serializedConfig;
5122
5132
  },
5123
- getResolvedProjectNames() {
5124
- return ctx.projects.map((p) => p.name);
5125
- },
5126
5133
  getResolvedProjectLabels() {
5127
5134
  return ctx.projects.map((p) => ({
5128
5135
  name: p.name,
@@ -5260,7 +5267,7 @@ class BrowserSessions {
5260
5267
  // this promise only waits for the WS connection with the orhcestrator to be established
5261
5268
  const defer = createDefer();
5262
5269
  const timeout = setTimeout(() => {
5263
- defer.reject(new Error(`Failed to connect to the browser session "${sessionId}" [${project.name}] within the timeout.`));
5270
+ defer.reject(/* @__PURE__ */ new Error(`Failed to connect to the browser session "${sessionId}" [${project.name}] within the timeout.`));
5264
5271
  }, project.vitest.config.browser.connectTimeout ?? 6e4).unref();
5265
5272
  this.sessions.set(sessionId, {
5266
5273
  project,
@@ -5749,10 +5756,7 @@ function serializeConfig(config, coreConfig, viteConfig) {
5749
5756
  snapshotOptions: {
5750
5757
  snapshotEnvironment: void 0,
5751
5758
  updateSnapshot: coreConfig.snapshotOptions.updateSnapshot,
5752
- snapshotFormat: {
5753
- ...coreConfig.snapshotOptions.snapshotFormat,
5754
- compareKeys: void 0
5755
- },
5759
+ snapshotFormat: { ...coreConfig.snapshotOptions.snapshotFormat },
5756
5760
  expand: config.snapshotOptions.expand ?? coreConfig.snapshotOptions.expand
5757
5761
  },
5758
5762
  sequence: {
@@ -5952,7 +5956,7 @@ function silenceImportViteIgnoreWarning(logger) {
5952
5956
 
5953
5957
  const cssLangs = "\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)";
5954
5958
  const cssLangRE = new RegExp(cssLangs);
5955
- const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
5959
+ const cssModuleRE = /* @__PURE__ */ new RegExp(`\\.module${cssLangs}`);
5956
5960
  const cssInlineRE = /[?&]inline(?:&|$)/;
5957
5961
  function isCSS(id) {
5958
5962
  return cssLangRE.test(id);
@@ -6991,7 +6995,7 @@ class TestProject {
6991
6995
  * @param moduleId The file path
6992
6996
  */
6993
6997
  createSpecification(moduleId, locations, pool) {
6994
- return new TestSpecification(this, moduleId, pool || getFilePoolName(this, moduleId), locations);
6998
+ return new TestSpecification(this, moduleId, pool || getFilePoolName(this), locations);
6995
6999
  }
6996
7000
  toJSON() {
6997
7001
  return {
@@ -7437,7 +7441,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
7437
7441
  const fileProjects = [...configFiles, ...nonConfigDirectories];
7438
7442
  const concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
7439
7443
  projectConfigs.forEach((options, index) => {
7440
- const configRoot = workspaceConfigPath ? dirname(workspaceConfigPath) : vitest.config.root;
7444
+ const configRoot = vitest.config.root;
7441
7445
  // if extends a config file, resolve the file path
7442
7446
  const configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : options.extends === true ? vitest.vite.config.configFile || false : false;
7443
7447
  // if `root` is configured, resolve it relative to the workspace file or vite root (like other options)
@@ -7617,8 +7621,7 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
7617
7621
  if (!isDynamicPattern(stringOption)) {
7618
7622
  const file = resolve(vitest.config.root, stringOption);
7619
7623
  if (!existsSync(file)) {
7620
- const relativeWorkspaceConfigPath = workspaceConfigPath ? relative(vitest.config.root, workspaceConfigPath) : void 0;
7621
- const note = workspaceConfigPath ? `Workspace config file "${relativeWorkspaceConfigPath}"` : "Projects definition";
7624
+ const note = "Projects definition";
7622
7625
  throw new Error(`${note} references a non-existing file or a directory: ${file}`);
7623
7626
  }
7624
7627
  const stats = await promises.stat(file);
@@ -8244,25 +8247,29 @@ class StateManager {
8244
8247
  processTimeoutCauses = /* @__PURE__ */ new Set();
8245
8248
  reportedTasksMap = /* @__PURE__ */ new WeakMap();
8246
8249
  blobs;
8247
- catchError(err, type) {
8248
- if (isAggregateError(err)) return err.errors.forEach((error) => this.catchError(error, type));
8249
- if (err === Object(err)) err.type = type;
8250
- else err = {
8250
+ onUnhandledError;
8251
+ constructor(options) {
8252
+ this.onUnhandledError = options.onUnhandledError;
8253
+ }
8254
+ catchError(error, type) {
8255
+ if (isAggregateError(error)) return error.errors.forEach((error) => this.catchError(error, type));
8256
+ if (typeof error === "object" && error !== null) error.type = type;
8257
+ else error = {
8251
8258
  type,
8252
- message: err
8259
+ message: error
8253
8260
  };
8254
- const _err = err;
8255
- if (_err && typeof _err === "object" && _err.code === "VITEST_PENDING") {
8256
- const task = this.idMap.get(_err.taskId);
8261
+ const _error = error;
8262
+ if (_error && typeof _error === "object" && _error.code === "VITEST_PENDING") {
8263
+ const task = this.idMap.get(_error.taskId);
8257
8264
  if (task) {
8258
8265
  task.mode = "skip";
8259
8266
  task.result ??= { state: "skip" };
8260
8267
  task.result.state = "skip";
8261
- task.result.note = _err.note;
8268
+ task.result.note = _error.note;
8262
8269
  }
8263
8270
  return;
8264
8271
  }
8265
- this.errorsSet.add(err);
8272
+ if (!this.onUnhandledError || this.onUnhandledError(error) !== false) this.errorsSet.add(error);
8266
8273
  }
8267
8274
  clearErrors() {
8268
8275
  this.errorsSet.clear();
@@ -9165,11 +9172,6 @@ class Vitest {
9165
9172
  /** @internal */ closingPromise;
9166
9173
  /** @internal */ isCancelling = false;
9167
9174
  /** @internal */ coreWorkspaceProject;
9168
- /**
9169
- * @internal
9170
- * @deprecated
9171
- */
9172
- resolvedProjects = [];
9173
9175
  /** @internal */ _browserLastPort = defaultBrowserPort;
9174
9176
  /** @internal */ _browserSessions = new BrowserSessions();
9175
9177
  /** @internal */ _cliOptions = {};
@@ -9187,7 +9189,6 @@ class Vitest {
9187
9189
  _state;
9188
9190
  _cache;
9189
9191
  _snapshot;
9190
- _workspaceConfigPath;
9191
9192
  constructor(mode, cliOptions, options = {}) {
9192
9193
  this.mode = mode;
9193
9194
  this._cliOptions = cliOptions;
@@ -9264,8 +9265,6 @@ class Vitest {
9264
9265
  this.pool = void 0;
9265
9266
  this.closingPromise = void 0;
9266
9267
  this.projects = [];
9267
- this.resolvedProjects = [];
9268
- this._workspaceConfigPath = void 0;
9269
9268
  this.coverageProvider = void 0;
9270
9269
  this.runningPromise = void 0;
9271
9270
  this.coreWorkspaceProject = void 0;
@@ -9274,7 +9273,7 @@ class Vitest {
9274
9273
  this._vite = server;
9275
9274
  const resolved = resolveConfig(this, options, server.config);
9276
9275
  this._config = resolved;
9277
- this._state = new StateManager();
9276
+ this._state = new StateManager({ onUnhandledError: resolved.onUnhandledError });
9278
9277
  this._cache = new VitestCache(this.version);
9279
9278
  this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
9280
9279
  this._testRun = new TestRun(this);
@@ -9303,7 +9302,7 @@ class Vitest {
9303
9302
  // since we set `server.hmr: false`, Vite does not auto restart itself
9304
9303
  server.watcher.on("change", async (file) => {
9305
9304
  file = normalize(file);
9306
- const isConfig = file === server.config.configFile || this.projects.some((p) => p.vite.config.configFile === file) || file === this._workspaceConfigPath;
9305
+ const isConfig = file === server.config.configFile || this.projects.some((p) => p.vite.config.configFile === file);
9307
9306
  if (isConfig) {
9308
9307
  await Promise.all(this._onRestartListeners.map((fn) => fn("config")));
9309
9308
  this.report("onServerRestart", "config");
@@ -9317,7 +9316,6 @@ class Vitest {
9317
9316
  await this.cache.results.readFromCache();
9318
9317
  } catch {}
9319
9318
  const projects = await this.resolveProjects(this._cliOptions);
9320
- this.resolvedProjects = projects;
9321
9319
  this.projects = projects;
9322
9320
  await Promise.all(projects.flatMap((project) => {
9323
9321
  const hooks = project.vite.config.getSortedPluginHooks("configureVitest");
@@ -9401,41 +9399,15 @@ class Vitest {
9401
9399
  import(moduleId) {
9402
9400
  return this.runner.executeId(moduleId);
9403
9401
  }
9404
- async resolveWorkspaceConfigPath() {
9405
- if (typeof this.config.workspace === "string") return this.config.workspace;
9406
- const configDir = this.vite.config.configFile ? dirname(this.vite.config.configFile) : this.config.root;
9407
- const rootFiles = await promises.readdir(configDir);
9408
- const workspaceConfigName = workspacesFiles.find((configFile) => {
9409
- return rootFiles.includes(configFile);
9410
- });
9411
- if (!workspaceConfigName) return void 0;
9412
- return join(configDir, workspaceConfigName);
9413
- }
9414
9402
  async resolveProjects(cliOptions) {
9415
9403
  const names = /* @__PURE__ */ new Set();
9416
- if (this.config.projects) {
9417
- if (typeof this.config.workspace !== "undefined") this.logger.warn("Both `test.projects` and `test.workspace` are defined. Ignoring the `test.workspace` option.");
9418
- return resolveProjects(this, cliOptions, void 0, this.config.projects, names);
9419
- }
9420
- if (Array.isArray(this.config.workspace)) {
9421
- this.logger.deprecate("The `test.workspace` option is deprecated and will be removed in the next major. To hide this warning, rename `test.workspace` option to `test.projects`.");
9422
- return resolveProjects(this, cliOptions, void 0, this.config.workspace, names);
9423
- }
9424
- const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
9425
- this._workspaceConfigPath = workspaceConfigPath;
9426
- // user doesn't have a workspace config, return default project
9427
- if (!workspaceConfigPath) {
9428
- // user can filter projects with --project flag, `getDefaultTestProject`
9429
- // returns the project only if it matches the filter
9430
- const project = getDefaultTestProject(this);
9431
- if (!project) return [];
9432
- return resolveBrowserProjects(this, new Set([project.name]), [project]);
9433
- }
9434
- const configFile = this.vite.config.configFile ? resolve(this.vite.config.root, this.vite.config.configFile) : "the root config file";
9435
- this.logger.deprecate(`The workspace file is deprecated and will be removed in the next major. Please, use the \`test.projects\` field in ${configFile} instead.`);
9436
- const workspaceModule = await this.import(workspaceConfigPath);
9437
- if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) throw new TypeError(`Workspace config file "${workspaceConfigPath}" must export a default array of project paths.`);
9438
- return resolveProjects(this, cliOptions, workspaceConfigPath, workspaceModule.default, names);
9404
+ if (this.config.projects) return resolveProjects(this, cliOptions, void 0, this.config.projects, names);
9405
+ if ("workspace" in this.config) throw new Error("The `test.workspace` option was removed in Vitest 4. Please, migrate to `test.projects` instead. See https://vitest.dev/guide/projects for examples.");
9406
+ // user can filter projects with --project flag, `getDefaultTestProject`
9407
+ // returns the project only if it matches the filter
9408
+ const project = getDefaultTestProject(this);
9409
+ if (!project) return [];
9410
+ return resolveBrowserProjects(this, new Set([project.name]), [project]);
9439
9411
  }
9440
9412
  /**
9441
9413
  * Glob test files in every project and create a TestSpecification for each file and pool.
@@ -10447,7 +10419,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10447
10419
  const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout);
10448
10420
  const filter = await watchFilter.filter(async (str) => {
10449
10421
  const files = await ctx.globTestFiles([str]);
10450
- return files.map((file) => relative(ctx.config.root, file[1]));
10422
+ return files.map((file) => relative(ctx.config.root, file[1])).filter((file, index, all) => all.indexOf(file) === index);
10451
10423
  });
10452
10424
  on();
10453
10425
  if (typeof filter === "undefined") return;
@@ -10485,7 +10457,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10485
10457
  */
10486
10458
  async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
10487
10459
  const root = resolve(options.root || process.cwd());
10488
- const ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions);
10460
+ const ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
10489
10461
  if (mode === "test" && ctx.config.coverage.enabled) {
10490
10462
  const provider = ctx.config.coverage.provider || "v8";
10491
10463
  const requiredPackages = CoverageProviderMap[provider];
@@ -10531,11 +10503,12 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
10531
10503
  await ctx.close();
10532
10504
  return ctx;
10533
10505
  }
10534
- async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions) {
10506
+ async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions, cliFilters) {
10535
10507
  process.env.TEST = "true";
10536
10508
  process.env.VITEST = "true";
10537
10509
  process.env.NODE_ENV ??= "test";
10538
10510
  if (options.run) options.watch = false;
10511
+ if (options.standalone && (cliFilters?.length || 0) > 0) options.standalone = false;
10539
10512
  // this shouldn't affect _application root_ that can be changed inside config
10540
10513
  const root = resolve(options.root || process.cwd());
10541
10514
  const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);