vitest 4.0.0-beta.5 → 4.0.0-beta.6

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 (57) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/browser.d.ts +1 -1
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{base.DMfOuRWD.js → base.BXI97p6t.js} +7 -16
  5. package/dist/chunks/{benchmark.CtuRzf-i.js → benchmark.UW6Ezvxy.js} +4 -9
  6. package/dist/chunks/{cac.CKnbxhn2.js → cac.WE-urWw5.js} +37 -113
  7. package/dist/chunks/{cli-api.COn58yrl.js → cli-api.CZz3evYC.js} +505 -1211
  8. package/dist/chunks/{console.Duv2dVIC.js → console.B0quX7yH.js} +32 -68
  9. package/dist/chunks/{coverage.B6cReEn1.js → coverage.BPRS6xgn.js} +210 -579
  10. package/dist/chunks/{creator.DUVZ6rfm.js → creator.KEg6n5IC.js} +28 -74
  11. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  12. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  13. package/dist/chunks/{globals.CJQ63oO0.js → globals.lgsmH00r.js} +5 -5
  14. package/dist/chunks/{index.DgN0Zk9a.js → index.7w0eqmYM.js} +14 -24
  15. package/dist/chunks/{index.QZr3S3vQ.js → index.AR8aAkCC.js} +2 -2
  16. package/dist/chunks/{index.BRtIe7r8.js → index.BG0gqZH-.js} +39 -102
  17. package/dist/chunks/{index.oWRWx-nj.js → index.CsFXYRkW.js} +17 -36
  18. package/dist/chunks/{index.DQhAfQQU.js → index.VNI-1z5c.js} +270 -606
  19. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  20. package/dist/chunks/{moduleRunner.d.mmOmOGrW.d.ts → moduleRunner.d.8kKUsuDg.d.ts} +1 -1
  21. package/dist/chunks/{node.4JV5OXkt.js → node.BOqcT2jW.js} +1 -1
  22. package/dist/chunks/{plugin.d.CvOlgjxK.d.ts → plugin.d.DuiQJfUL.d.ts} +1 -1
  23. package/dist/chunks/{reporters.d.CYE9sT5z.d.ts → reporters.d.CqR9-CDJ.d.ts} +16 -33
  24. package/dist/chunks/{resolver.D5bG4zy5.js → resolver.Bx6lE0iq.js} +21 -64
  25. package/dist/chunks/{rpc.DGoW_Vl-.js → rpc.RpPylpp0.js} +7 -21
  26. package/dist/chunks/{runBaseTests.B3KcKqlF.js → runBaseTests.D6sfuWBM.js} +25 -54
  27. package/dist/chunks/{setup-common.lgPs-bYv.js → setup-common.hLGRxhC8.js} +9 -22
  28. package/dist/chunks/{startModuleRunner.C8FtT_BY.js → startModuleRunner.C8TW8zTN.js} +83 -205
  29. package/dist/chunks/{typechecker.BgoW4nTA.js → typechecker.Cd1wvxUM.js} +96 -208
  30. package/dist/chunks/{utils.CcGm2cd1.js → utils.C2YI6McM.js} +4 -13
  31. package/dist/chunks/{utils.B9FY3b73.js → utils.C7__0Iv5.js} +5 -14
  32. package/dist/chunks/{vi.DGAfBY4R.js → vi.BfdOiD4j.js} +110 -267
  33. package/dist/chunks/{vm.BKfKvaKl.js → vm.BHBje7cC.js} +73 -177
  34. package/dist/cli.js +3 -3
  35. package/dist/config.d.ts +4 -4
  36. package/dist/coverage.d.ts +1 -1
  37. package/dist/coverage.js +2 -2
  38. package/dist/environments.js +1 -1
  39. package/dist/index.js +5 -5
  40. package/dist/module-evaluator.d.ts +1 -1
  41. package/dist/module-evaluator.js +33 -84
  42. package/dist/module-runner.js +2 -2
  43. package/dist/node.d.ts +3 -3
  44. package/dist/node.js +13 -19
  45. package/dist/reporters.d.ts +2 -2
  46. package/dist/reporters.js +3 -3
  47. package/dist/runners.js +23 -51
  48. package/dist/snapshot.js +2 -2
  49. package/dist/suite.js +2 -2
  50. package/dist/worker.js +18 -34
  51. package/dist/workers/forks.js +4 -4
  52. package/dist/workers/runVmTests.js +19 -37
  53. package/dist/workers/threads.js +4 -4
  54. package/dist/workers/vmForks.js +7 -7
  55. package/dist/workers/vmThreads.js +7 -7
  56. package/dist/workers.js +11 -11
  57. package/package.json +11 -11
@@ -9,9 +9,9 @@ import { searchForWorkspaceRoot, version, mergeConfig, createServer } from 'vite
9
9
  import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.D_Q9UYh-.js';
10
10
  import { generateFileHash, limitConcurrency, createFileTask, hasFailed, getTasks, getTests } from '@vitest/runner/utils';
11
11
  import { SnapshotManager } from '@vitest/snapshot/manager';
12
- import { v as version$1 } from './cac.CKnbxhn2.js';
12
+ import { v as version$1 } from './cac.WE-urWw5.js';
13
13
  import { c as createBirpc } from './index.Bgo3tNWt.js';
14
- 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.DQhAfQQU.js';
14
+ 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.VNI-1z5c.js';
15
15
  import require$$0$3 from 'events';
16
16
  import require$$1$1 from 'https';
17
17
  import require$$2 from 'http';
@@ -26,8 +26,8 @@ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
26
26
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
27
27
  import crypto, { createHash } from 'node:crypto';
28
28
  import { distDir, rootDir } from '../path.js';
29
- import { h as hash, d as createFetchModuleFunction, n as normalizeResolvedIdToUrl, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, e as isBrowserEnabled, r as resolveConfig, f as groupBy, j as getCoverageProvider, k as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.B6cReEn1.js';
30
- import { c as convertTasksToEvents } from './typechecker.BgoW4nTA.js';
29
+ import { h as hash, d as createFetchModuleFunction, n as normalizeResolvedIdToUrl, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, e as isBrowserEnabled, r as resolveConfig, f as groupBy, j as getCoverageProvider, k as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.BPRS6xgn.js';
30
+ import { c as convertTasksToEvents } from './typechecker.Cd1wvxUM.js';
31
31
  import { VitestModuleEvaluator } from '#module-evaluator';
32
32
  import { ModuleRunner } from 'vite/module-runner';
33
33
  import { Console } from 'node:console';
@@ -42,9 +42,9 @@ import { glob, isDynamicPattern } from 'tinyglobby';
42
42
  import MagicString from 'magic-string';
43
43
  import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
44
44
  import { c as configDefaults } from './defaults.CXFFjsi8.js';
45
- import { f as findNearestPackageData } from './resolver.D5bG4zy5.js';
45
+ import { f as findNearestPackageData } from './resolver.Bx6lE0iq.js';
46
46
  import * as esModuleLexer from 'es-module-lexer';
47
- import { a as BenchmarkReportsMap } from './index.DgN0Zk9a.js';
47
+ import { a as BenchmarkReportsMap } from './index.7w0eqmYM.js';
48
48
  import assert$1 from 'node:assert';
49
49
  import { serializeError } from '@vitest/utils/error';
50
50
  import readline from 'node:readline';
@@ -5017,26 +5017,18 @@ var websocketServerExports = requireWebsocketServer();
5017
5017
  var WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServerExports);
5018
5018
 
5019
5019
  async function getModuleGraph(ctx, projectName, id, browser = false) {
5020
- const graph = {};
5021
- const externalized = /* @__PURE__ */ new Set();
5022
- const inlined = /* @__PURE__ */ new Set();
5023
- const project = ctx.getProjectByName(projectName);
5020
+ const graph = {}, externalized = /* @__PURE__ */ new Set(), inlined = /* @__PURE__ */ new Set(), project = ctx.getProjectByName(projectName);
5024
5021
  async function get(mod, seen = /* @__PURE__ */ new Map()) {
5025
- if (!mod || !mod.id) return;
5026
- if (mod.id === "\0@vitest/browser/context") return;
5022
+ if (!mod || !mod.id || mod.id === "\0@vitest/browser/context") return;
5027
5023
  if (seen.has(mod)) return seen.get(mod);
5028
5024
  let id = clearId(mod.id);
5029
5025
  seen.set(mod, id);
5030
5026
  // TODO: how to know if it was rewritten(?) - what is rewritten?
5031
5027
  const rewrote = browser ? mod.file?.includes(project.browser.vite.config.cacheDir) ? mod.id : false : false;
5032
- if (rewrote) {
5033
- id = rewrote;
5034
- externalized.add(id);
5035
- seen.set(mod, id);
5036
- } else inlined.add(id);
5028
+ if (rewrote) id = rewrote, externalized.add(id), seen.set(mod, id);
5029
+ else inlined.add(id);
5037
5030
  const mods = Array.from(mod.importedModules).filter((i) => i.id && !i.id.includes("/vitest/dist/"));
5038
- graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean);
5039
- return id;
5031
+ return graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean), id;
5040
5032
  }
5041
5033
  if (browser && project.browser) await get(project.browser.vite.moduleGraph.getModuleById(id));
5042
5034
  else await get(project.vite.moduleGraph.getModuleById(id));
@@ -5088,21 +5080,19 @@ catch {}
5088
5080
  }
5089
5081
 
5090
5082
  function setup(ctx, _server) {
5091
- const wss = new WebSocketServer({ noServer: true });
5092
- const clients = /* @__PURE__ */ new Map();
5093
- const server = _server || ctx.server;
5083
+ const wss = new WebSocketServer({ noServer: true }), clients = /* @__PURE__ */ new Map(), server = _server || ctx.server;
5094
5084
  server.httpServer?.on("upgrade", (request, socket, head) => {
5095
5085
  if (!request.url) return;
5096
5086
  const { pathname } = new URL(request.url, "http://localhost");
5097
- if (pathname !== API_PATH) return;
5098
- if (!isValidApiRequest(ctx.config, request)) {
5099
- socket.destroy();
5100
- return;
5087
+ if (pathname === API_PATH) {
5088
+ if (!isValidApiRequest(ctx.config, request)) {
5089
+ socket.destroy();
5090
+ return;
5091
+ }
5092
+ wss.handleUpgrade(request, socket, head, (ws) => {
5093
+ wss.emit("connection", ws, request), setupClient(ws);
5094
+ });
5101
5095
  }
5102
- wss.handleUpgrade(request, socket, head, (ws) => {
5103
- wss.emit("connection", ws, request);
5104
- setupClient(ws);
5105
- });
5106
5096
  });
5107
5097
  function setupClient(ws) {
5108
5098
  const rpc = createBirpc({
@@ -5116,8 +5106,7 @@ function setup(ctx, _server) {
5116
5106
  return ctx.state.getPaths();
5117
5107
  },
5118
5108
  async readTestFile(id) {
5119
- if (!ctx.state.filesMap.has(id) || !existsSync(id)) return null;
5120
- return promises.readFile(id, "utf-8");
5109
+ return !ctx.state.filesMap.has(id) || !existsSync(id) ? null : promises.readFile(id, "utf-8");
5121
5110
  },
5122
5111
  async saveTestFile(id, content) {
5123
5112
  if (!ctx.state.filesMap.has(id) || !existsSync(id)) throw new Error(`Test file "${id}" was not registered, so it cannot be updated using the API.`);
@@ -5139,8 +5128,7 @@ function setup(ctx, _server) {
5139
5128
  }));
5140
5129
  },
5141
5130
  async getTransformResult(projectName, id, browser = false) {
5142
- const project = ctx.getProjectByName(projectName);
5143
- const result = browser ? await project.browser.vite.transformRequest(id) : await project.vite.transformRequest(id);
5131
+ const project = ctx.getProjectByName(projectName), result = browser ? await project.browser.vite.transformRequest(id) : await project.vite.transformRequest(id);
5144
5132
  if (result) {
5145
5133
  try {
5146
5134
  result.source = result.source || await promises.readFile(id, "utf-8");
@@ -5183,56 +5171,49 @@ function setup(ctx, _server) {
5183
5171
  deserialize: parse,
5184
5172
  timeout: -1
5185
5173
  });
5186
- clients.set(ws, rpc);
5187
- ws.on("close", () => {
5188
- clients.delete(ws);
5189
- rpc.$close(/* @__PURE__ */ new Error("[vitest-api]: Pending methods while closing rpc"));
5174
+ clients.set(ws, rpc), ws.on("close", () => {
5175
+ clients.delete(ws), rpc.$close(/* @__PURE__ */ new Error("[vitest-api]: Pending methods while closing rpc"));
5190
5176
  });
5191
5177
  }
5192
5178
  ctx.reporters.push(new WebSocketReporter(ctx, wss, clients));
5193
5179
  }
5194
5180
  class WebSocketReporter {
5195
5181
  constructor(ctx, wss, clients) {
5196
- this.ctx = ctx;
5197
- this.wss = wss;
5198
- this.clients = clients;
5182
+ this.ctx = ctx, this.wss = wss, this.clients = clients;
5199
5183
  }
5200
- onCollected(files) {
5201
- if (this.clients.size === 0) return;
5202
- this.clients.forEach((client) => {
5203
- client.onCollected?.(files)?.catch?.(noop);
5184
+ onTestModuleCollected(testModule) {
5185
+ this.clients.size !== 0 && this.clients.forEach((client) => {
5186
+ client.onCollected?.([testModule.task])?.catch?.(noop);
5204
5187
  });
5205
5188
  }
5206
- onSpecsCollected(specs) {
5189
+ onTestRunStart(specifications) {
5207
5190
  if (this.clients.size === 0) return;
5191
+ const serializedSpecs = specifications.map((spec) => spec.toJSON());
5208
5192
  this.clients.forEach((client) => {
5209
- client.onSpecsCollected?.(specs)?.catch?.(noop);
5193
+ client.onSpecsCollected?.(serializedSpecs)?.catch?.(noop);
5210
5194
  });
5211
5195
  }
5212
5196
  async onTestCaseAnnotate(testCase, annotation) {
5213
- if (this.clients.size === 0) return;
5214
- this.clients.forEach((client) => {
5197
+ this.clients.size !== 0 && this.clients.forEach((client) => {
5215
5198
  client.onTestAnnotate?.(testCase.id, annotation)?.catch?.(noop);
5216
5199
  });
5217
5200
  }
5218
5201
  async onTaskUpdate(packs, events) {
5219
- if (this.clients.size === 0) return;
5220
- packs.forEach(([taskId, result]) => {
5221
- const task = this.ctx.state.idMap.get(taskId);
5222
- const isBrowser = task && task.file.pool === "browser";
5202
+ this.clients.size !== 0 && (packs.forEach(([taskId, result]) => {
5203
+ const task = this.ctx.state.idMap.get(taskId), isBrowser = task && task.file.pool === "browser";
5223
5204
  result?.errors?.forEach((error) => {
5224
- if (isPrimitive(error)) return;
5225
- if (isBrowser) {
5205
+ if (!isPrimitive(error)) if (isBrowser) {
5226
5206
  const project = this.ctx.getProjectByName(task.file.projectName || "");
5227
5207
  error.stacks = project.browser?.parseErrorStacktrace(error);
5228
5208
  } else error.stacks = parseErrorStacktrace(error);
5229
5209
  });
5230
- });
5231
- this.clients.forEach((client) => {
5210
+ }), this.clients.forEach((client) => {
5232
5211
  client.onTaskUpdate?.(packs, events)?.catch?.(noop);
5233
- });
5212
+ }));
5234
5213
  }
5235
- onFinished(files, errors) {
5214
+ onTestRunEnd(testModules, unhandledErrors) {
5215
+ if (!this.clients.size) return;
5216
+ const files = testModules.map((testModule) => testModule.task), errors = [...unhandledErrors];
5236
5217
  this.clients.forEach((client) => {
5237
5218
  client.onFinished?.(files, errors)?.catch?.(noop);
5238
5219
  });
@@ -5266,23 +5247,18 @@ class BrowserSessions {
5266
5247
  }
5267
5248
  createSession(sessionId, project, pool) {
5268
5249
  // this promise only waits for the WS connection with the orhcestrator to be established
5269
- const defer = createDefer();
5270
- const timeout = setTimeout(() => {
5250
+ const defer = createDefer(), timeout = setTimeout(() => {
5271
5251
  defer.reject(/* @__PURE__ */ new Error(`Failed to connect to the browser session "${sessionId}" [${project.name}] within the timeout.`));
5272
5252
  }, project.vitest.config.browser.connectTimeout ?? 6e4).unref();
5273
- this.sessions.set(sessionId, {
5253
+ return this.sessions.set(sessionId, {
5274
5254
  project,
5275
5255
  connected: () => {
5276
- defer.resolve();
5277
- clearTimeout(timeout);
5256
+ defer.resolve(), clearTimeout(timeout);
5278
5257
  },
5279
5258
  fail: (error) => {
5280
- defer.resolve();
5281
- clearTimeout(timeout);
5282
- pool.reject(error);
5259
+ defer.resolve(), clearTimeout(timeout), pool.reject(error);
5283
5260
  }
5284
- });
5285
- return defer;
5261
+ }), defer;
5286
5262
  }
5287
5263
  }
5288
5264
 
@@ -5323,37 +5299,25 @@ class ResultsCache {
5323
5299
  return this.cachePath;
5324
5300
  }
5325
5301
  setConfig(root, config) {
5326
- this.root = root;
5327
- if (config) this.cachePath = resolve(config.dir, "results.json");
5302
+ if (this.root = root, config) this.cachePath = resolve(config.dir, "results.json");
5328
5303
  }
5329
5304
  getResults(key) {
5330
5305
  return this.cache.get(key);
5331
5306
  }
5332
5307
  async readFromCache() {
5333
- if (!this.cachePath) return;
5334
- if (!fs.existsSync(this.cachePath)) return;
5335
- const resultsCache = await fs.promises.readFile(this.cachePath, "utf8");
5336
- const { results, version } = JSON.parse(resultsCache || "[]");
5337
- const [major, minor] = version.split(".");
5308
+ if (!this.cachePath || !fs.existsSync(this.cachePath)) return;
5309
+ const resultsCache = await fs.promises.readFile(this.cachePath, "utf8"), { results, version } = JSON.parse(resultsCache || "[]"), [major, minor] = version.split(".");
5338
5310
  // handling changed in 0.30.0
5339
- if (major > 0 || Number(minor) >= 30) {
5340
- this.cache = new Map(results);
5341
- this.version = version;
5342
- results.forEach(([spec]) => {
5343
- const [projectName, relativePath] = spec.split(":");
5344
- const keyMap = this.workspacesKeyMap.get(relativePath) || [];
5345
- keyMap.push(projectName);
5346
- this.workspacesKeyMap.set(relativePath, keyMap);
5347
- });
5348
- }
5311
+ if (major > 0 || Number(minor) >= 30) this.cache = new Map(results), this.version = version, results.forEach(([spec]) => {
5312
+ const [projectName, relativePath] = spec.split(":"), keyMap = this.workspacesKeyMap.get(relativePath) || [];
5313
+ keyMap.push(projectName), this.workspacesKeyMap.set(relativePath, keyMap);
5314
+ });
5349
5315
  }
5350
5316
  updateResults(files) {
5351
5317
  files.forEach((file) => {
5352
5318
  const result = file.result;
5353
5319
  if (!result) return;
5354
- const duration = result.duration || 0;
5355
- // store as relative, so cache would be the same in CI and locally
5356
- const relativePath = relative(this.root, file.filepath);
5320
+ const duration = result.duration || 0, relativePath = relative(this.root, file.filepath);
5357
5321
  this.cache.set(`${file.projectName || ""}:${relativePath}`, {
5358
5322
  duration: duration >= 0 ? duration : 0,
5359
5323
  failed: result.state === "fail"
@@ -5367,8 +5331,7 @@ class ResultsCache {
5367
5331
  }
5368
5332
  async writeToCache() {
5369
5333
  if (!this.cachePath) return;
5370
- const results = Array.from(this.cache.entries());
5371
- const cacheDirname = dirname(this.cachePath);
5334
+ const results = Array.from(this.cache.entries()), cacheDirname = dirname(this.cachePath);
5372
5335
  if (!fs.existsSync(cacheDirname)) await fs.promises.mkdir(cacheDirname, { recursive: true });
5373
5336
  const cache = JSON.stringify({
5374
5337
  version: this.version,
@@ -5412,9 +5375,7 @@ class ServerModuleRunner extends ModuleRunner {
5412
5375
  return { error };
5413
5376
  }
5414
5377
  } }
5415
- }, new VitestModuleEvaluator());
5416
- this.environment = environment;
5417
- this.config = config;
5378
+ }, new VitestModuleEvaluator()), this.environment = environment, this.config = config;
5418
5379
  }
5419
5380
  async import(rawId) {
5420
5381
  const resolved = await this.environment.pluginContainer.resolveId(rawId, this.config.root);
@@ -5481,43 +5442,26 @@ function highlightCode(id, source, colors) {
5481
5442
  });
5482
5443
  }
5483
5444
 
5484
- const PAD = " ";
5485
- const ESC$1 = "\x1B[";
5486
- const ERASE_DOWN = `${ESC$1}J`;
5487
- const ERASE_SCROLLBACK = `${ESC$1}3J`;
5488
- const CURSOR_TO_START = `${ESC$1}1;1H`;
5489
- const HIDE_CURSOR = `${ESC$1}?25l`;
5490
- const SHOW_CURSOR = `${ESC$1}?25h`;
5491
- const CLEAR_SCREEN = "\x1Bc";
5445
+ const PAD = " ", ESC$1 = "\x1B[", ERASE_DOWN = `${ESC$1}J`, ERASE_SCROLLBACK = `${ESC$1}3J`, CURSOR_TO_START = `${ESC$1}1;1H`, HIDE_CURSOR = `${ESC$1}?25l`, SHOW_CURSOR = `${ESC$1}?25h`, CLEAR_SCREEN = "\x1Bc";
5492
5446
  class Logger {
5493
5447
  _clearScreenPending;
5494
5448
  _highlights = /* @__PURE__ */ new Map();
5495
5449
  cleanupListeners = [];
5496
5450
  console;
5497
5451
  constructor(ctx, outputStream = process.stdout, errorStream = process.stderr) {
5498
- this.ctx = ctx;
5499
- this.outputStream = outputStream;
5500
- this.errorStream = errorStream;
5501
- this.console = new Console({
5452
+ if (this.ctx = ctx, this.outputStream = outputStream, this.errorStream = errorStream, this.console = new Console({
5502
5453
  stdout: outputStream,
5503
5454
  stderr: errorStream
5504
- });
5505
- this._highlights.clear();
5506
- this.addCleanupListeners();
5507
- this.registerUnhandledRejection();
5508
- if (this.outputStream.isTTY) this.outputStream.write(HIDE_CURSOR);
5455
+ }), this._highlights.clear(), this.addCleanupListeners(), this.registerUnhandledRejection(), this.outputStream.isTTY) this.outputStream.write(HIDE_CURSOR);
5509
5456
  }
5510
5457
  log(...args) {
5511
- this._clearScreen();
5512
- this.console.log(...args);
5458
+ this._clearScreen(), this.console.log(...args);
5513
5459
  }
5514
5460
  error(...args) {
5515
- this._clearScreen();
5516
- this.console.error(...args);
5461
+ this._clearScreen(), this.console.error(...args);
5517
5462
  }
5518
5463
  warn(...args) {
5519
- this._clearScreen();
5520
- this.console.warn(...args);
5464
+ this._clearScreen(), this.console.warn(...args);
5521
5465
  }
5522
5466
  clearFullScreen(message = "") {
5523
5467
  if (!this.ctx.config.clearScreen) {
@@ -5532,14 +5476,12 @@ class Logger {
5532
5476
  this.console.log(message);
5533
5477
  return;
5534
5478
  }
5535
- this._clearScreenPending = message;
5536
- if (force) this._clearScreen();
5479
+ if (this._clearScreenPending = message, force) this._clearScreen();
5537
5480
  }
5538
5481
  _clearScreen() {
5539
5482
  if (this._clearScreenPending == null) return;
5540
5483
  const log = this._clearScreenPending;
5541
- this._clearScreenPending = void 0;
5542
- this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
5484
+ this._clearScreenPending = void 0, this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
5543
5485
  }
5544
5486
  printError(err, options = {}) {
5545
5487
  printError(err, this.ctx, this, options);
@@ -5554,8 +5496,7 @@ class Logger {
5554
5496
  highlight(filename, source) {
5555
5497
  if (this._highlights.has(filename)) return this._highlights.get(filename);
5556
5498
  const code = highlightCode(filename, source);
5557
- this._highlights.set(filename, code);
5558
- return code;
5499
+ return this._highlights.set(filename, code), code;
5559
5500
  }
5560
5501
  printNoTestFound(filters) {
5561
5502
  const config = this.ctx.config;
@@ -5568,34 +5509,22 @@ class Logger {
5568
5509
  const projectsFilter = toArray(config.project);
5569
5510
  if (projectsFilter.length) this.console.error(c.dim("projects: ") + c.yellow(projectsFilter.join(comma)));
5570
5511
  this.ctx.projects.forEach((project) => {
5571
- const config = project.config;
5572
- const printConfig = !project.isRootProject() && project.name;
5512
+ const config = project.config, printConfig = !project.isRootProject() && project.name;
5573
5513
  if (printConfig) this.console.error(`\n${formatProjectName(project)}\n`);
5574
5514
  if (config.include) this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
5575
5515
  if (config.exclude) this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
5576
- if (config.typecheck.enabled) {
5577
- this.console.error(c.dim("typecheck include: ") + c.yellow(config.typecheck.include.join(comma)));
5578
- this.console.error(c.dim("typecheck exclude: ") + c.yellow(config.typecheck.exclude.join(comma)));
5579
- }
5580
- });
5581
- this.console.error();
5516
+ if (config.typecheck.enabled) this.console.error(c.dim("typecheck include: ") + c.yellow(config.typecheck.include.join(comma))), this.console.error(c.dim("typecheck exclude: ") + c.yellow(config.typecheck.exclude.join(comma)));
5517
+ }), this.console.error();
5582
5518
  }
5583
5519
  printBanner() {
5584
5520
  this.log();
5585
- const color = this.ctx.config.watch ? "blue" : "cyan";
5586
- const mode = this.ctx.config.watch ? "DEV" : "RUN";
5587
- this.log(withLabel(color, mode, `v${this.ctx.version} `) + c.gray(this.ctx.config.root));
5588
- if (this.ctx.config.sequence.sequencer === RandomSequencer) this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
5521
+ const color = this.ctx.config.watch ? "blue" : "cyan", mode = this.ctx.config.watch ? "DEV" : "RUN";
5522
+ if (this.log(withLabel(color, mode, `v${this.ctx.version} `) + c.gray(this.ctx.config.root)), this.ctx.config.sequence.sequencer === RandomSequencer) this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
5589
5523
  if (this.ctx.config.ui) {
5590
- const host = this.ctx.config.api?.host || "localhost";
5591
- const port = this.ctx.server.config.server.port;
5592
- const base = this.ctx.config.uiBase;
5524
+ const host = this.ctx.config.api?.host || "localhost", port = this.ctx.server.config.server.port, base = this.ctx.config.uiBase;
5593
5525
  this.log(PAD + c.dim(c.green(`UI started at http://${host}:${c.bold(port)}${base}`)));
5594
5526
  } else if (this.ctx.config.api?.port) {
5595
- const resolvedUrls = this.ctx.server.resolvedUrls;
5596
- // workaround for https://github.com/vitejs/vite/issues/15438, it was fixed in vite 5.1
5597
- const fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`;
5598
- const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
5527
+ const resolvedUrls = this.ctx.server.resolvedUrls, fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`, origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
5599
5528
  this.log(PAD + c.dim(c.green(`API started at ${new URL("/", origin)}`)));
5600
5529
  }
5601
5530
  if (this.ctx.coverageProvider) this.log(PAD + c.dim("Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
@@ -5604,35 +5533,26 @@ class Logger {
5604
5533
  }
5605
5534
  printBrowserBanner(project) {
5606
5535
  if (!project.browser) return;
5607
- const resolvedUrls = project.browser.vite.resolvedUrls;
5608
- const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
5536
+ const resolvedUrls = project.browser.vite.resolvedUrls, origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
5609
5537
  if (!origin) return;
5610
- const output = project.isRootProject() ? "" : formatProjectName(project);
5611
- const provider = project.browser.provider.name;
5612
- const providerString = provider === "preview" ? "" : ` by ${c.reset(c.bold(provider))}`;
5538
+ const output = project.isRootProject() ? "" : formatProjectName(project), provider = project.browser.provider.name, providerString = provider === "preview" ? "" : ` by ${c.reset(c.bold(provider))}`;
5613
5539
  this.log(c.dim(`${output}Browser runner started${providerString} ${c.dim("at")} ${c.blue(new URL("/__vitest_test__/", origin))}\n`));
5614
5540
  }
5615
5541
  printUnhandledErrors(errors) {
5616
5542
  const errorMessage = c.red(c.bold(`\nVitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
5617
5543
  This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`));
5618
- this.error(errorBanner("Unhandled Errors"));
5619
- this.error(errorMessage);
5620
- errors.forEach((err) => {
5544
+ this.error(errorBanner("Unhandled Errors")), this.error(errorMessage), errors.forEach((err) => {
5621
5545
  this.printError(err, {
5622
5546
  fullStack: true,
5623
5547
  type: err.type || "Unhandled Error"
5624
5548
  });
5625
- });
5626
- this.error(c.red(divider()));
5549
+ }), this.error(c.red(divider()));
5627
5550
  }
5628
5551
  printSourceTypeErrors(errors) {
5629
5552
  const errorMessage = c.red(c.bold(`\nVitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`));
5630
- this.log(errorBanner("Source Errors"));
5631
- this.log(errorMessage);
5632
- errors.forEach((err) => {
5553
+ this.log(errorBanner("Source Errors")), this.log(errorMessage), errors.forEach((err) => {
5633
5554
  this.printError(err, { fullStack: true });
5634
- });
5635
- this.log(c.red(divider()));
5555
+ }), this.log(c.red(divider()));
5636
5556
  }
5637
5557
  getColumns() {
5638
5558
  return "columns" in this.outputStream ? this.outputStream.columns : 80;
@@ -5642,38 +5562,25 @@ This might cause false positive tests. Resolve unhandled errors to make sure you
5642
5562
  }
5643
5563
  addCleanupListeners() {
5644
5564
  const cleanup = () => {
5645
- this.cleanupListeners.forEach((fn) => fn());
5646
- if (this.outputStream.isTTY) this.outputStream.write(SHOW_CURSOR);
5647
- };
5648
- const onExit = (signal, exitCode) => {
5649
- cleanup();
5565
+ if (this.cleanupListeners.forEach((fn) => fn()), this.outputStream.isTTY) this.outputStream.write(SHOW_CURSOR);
5566
+ }, onExit = (signal, exitCode) => {
5650
5567
  // Interrupted signals don't set exit code automatically.
5651
5568
  // Use same exit code as node: https://nodejs.org/api/process.html#signal-events
5652
- if (process.exitCode === void 0) process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal);
5569
+ if (cleanup(), process.exitCode === void 0) process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal);
5653
5570
  process.exit();
5654
5571
  };
5655
- process.once("SIGINT", onExit);
5656
- process.once("SIGTERM", onExit);
5657
- process.once("exit", onExit);
5658
- this.ctx.onClose(() => {
5659
- process.off("SIGINT", onExit);
5660
- process.off("SIGTERM", onExit);
5661
- process.off("exit", onExit);
5662
- cleanup();
5572
+ process.once("SIGINT", onExit), process.once("SIGTERM", onExit), process.once("exit", onExit), this.ctx.onClose(() => {
5573
+ process.off("SIGINT", onExit), process.off("SIGTERM", onExit), process.off("exit", onExit), cleanup();
5663
5574
  });
5664
5575
  }
5665
5576
  registerUnhandledRejection() {
5666
5577
  const onUnhandledRejection = (err) => {
5667
- process.exitCode = 1;
5668
- this.printError(err, {
5578
+ process.exitCode = 1, this.printError(err, {
5669
5579
  fullStack: true,
5670
5580
  type: "Unhandled Rejection"
5671
- });
5672
- this.error("\n\n");
5673
- process.exit();
5581
+ }), this.error("\n\n"), process.exit();
5674
5582
  };
5675
- process.on("unhandledRejection", onUnhandledRejection);
5676
- this.ctx.onClose(() => {
5583
+ process.on("unhandledRejection", onUnhandledRejection), this.ctx.onClose(() => {
5677
5584
  process.off("unhandledRejection", onUnhandledRejection);
5678
5585
  });
5679
5586
  }
@@ -5689,36 +5596,26 @@ class VitestPackageInstaller {
5689
5596
  if (process.versions.pnp) {
5690
5597
  const targetRequire = createRequire(__dirname);
5691
5598
  try {
5692
- targetRequire.resolve(dependency, { paths: [root, __dirname] });
5693
- return true;
5599
+ return targetRequire.resolve(dependency, { paths: [root, __dirname] }), true;
5694
5600
  } catch {}
5695
5601
  }
5696
5602
  if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname] })) return true;
5697
- process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`));
5698
- if (!isTTY) return false;
5699
- const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; });
5700
- const { install } = await prompts.default({
5603
+ if (process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`)), !isTTY) return false;
5604
+ const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; }), { install } = await prompts.default({
5701
5605
  type: "confirm",
5702
5606
  name: "install",
5703
5607
  message: c.reset(`Do you want to install ${c.green(dependency)}?`)
5704
5608
  });
5705
5609
  if (install) {
5706
5610
  const packageName = version ? `${dependency}@${version}` : dependency;
5707
- await (await import('./index.D3XRDfWc.js')).installPackage(packageName, { dev: true });
5708
- // TODO: somehow it fails to load the package after installation, remove this when it's fixed
5709
- process.stderr.write(c.yellow(`\nPackage ${packageName} installed, re-run the command to start.\n`));
5710
- process.exit();
5711
- return true;
5611
+ return await (await import('./index.D3XRDfWc.js')).installPackage(packageName, { dev: true }), process.stderr.write(c.yellow(`\nPackage ${packageName} installed, re-run the command to start.\n`)), process.exit(), true;
5712
5612
  }
5713
5613
  return false;
5714
5614
  }
5715
5615
  }
5716
5616
 
5717
5617
  function serializeConfig(config, coreConfig, viteConfig) {
5718
- const optimizer = config.deps?.optimizer || {};
5719
- const poolOptions = config.poolOptions;
5720
- // Resolve from server.config to avoid comparing against default value
5721
- const isolate = viteConfig?.test?.isolate;
5618
+ const optimizer = config.deps?.optimizer || {}, poolOptions = config.poolOptions, isolate = viteConfig?.test?.isolate;
5722
5619
  return {
5723
5620
  environmentOptions: config.environmentOptions,
5724
5621
  mode: config.mode,
@@ -5752,8 +5649,7 @@ function serializeConfig(config, coreConfig, viteConfig) {
5752
5649
  snapshotEnvironment: config.snapshotEnvironment,
5753
5650
  passWithNoTests: config.passWithNoTests,
5754
5651
  coverage: ((coverage) => {
5755
- const htmlReporter = coverage.reporter.find(([reporterName]) => reporterName === "html");
5756
- const subdir = htmlReporter && htmlReporter[1]?.subdir;
5652
+ const htmlReporter = coverage.reporter.find(([reporterName]) => reporterName === "html"), subdir = htmlReporter && htmlReporter[1]?.subdir;
5757
5653
  return {
5758
5654
  reportsDirectory: coverage.reportsDirectory,
5759
5655
  provider: coverage.provider,
@@ -5778,8 +5674,7 @@ function serializeConfig(config, coreConfig, viteConfig) {
5778
5674
  deps: {
5779
5675
  web: config.deps.web || {},
5780
5676
  optimizer: Object.entries(optimizer).reduce((acc, [name, option]) => {
5781
- acc[name] = { enabled: option?.enabled ?? false };
5782
- return acc;
5677
+ return acc[name] = { enabled: option?.enabled ?? false }, acc;
5783
5678
  }, {}),
5784
5679
  interopDefault: config.deps.interopDefault,
5785
5680
  moduleDirectories: config.deps.moduleDirectories
@@ -5840,12 +5735,12 @@ async function loadGlobalSetupFile(file, runner) {
5840
5735
  file,
5841
5736
  setup: m.default
5842
5737
  };
5843
- else if (m.setup || m.teardown) return {
5738
+ if (m.setup || m.teardown) return {
5844
5739
  file,
5845
5740
  setup: m.setup,
5846
5741
  teardown: m.teardown
5847
5742
  };
5848
- else throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
5743
+ throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
5849
5744
  }
5850
5745
 
5851
5746
  function CoverageTransform(ctx) {
@@ -6350,12 +6245,10 @@ function MetaEnvReplacerPlugin() {
6350
6245
  transform(code, id) {
6351
6246
  if (!/\bimport\.meta\.env\b/.test(code)) return null;
6352
6247
  let s = null;
6353
- const cleanCode = stripLiteral(code);
6354
- const envs = cleanCode.matchAll(/\bimport\.meta\.env\b/g);
6248
+ const cleanCode = stripLiteral(code), envs = cleanCode.matchAll(/\bimport\.meta\.env\b/g);
6355
6249
  for (const env of envs) {
6356
6250
  s ||= new MagicString(code);
6357
- const startIndex = env.index;
6358
- const endIndex = startIndex + env[0].length;
6251
+ const startIndex = env.index, endIndex = startIndex + env[0].length;
6359
6252
  s.overwrite(startIndex, endIndex, `Object.assign(/* istanbul ignore next */ globalThis.__vitest_worker__?.metaEnv ?? import.meta.env)`);
6360
6253
  }
6361
6254
  if (s) return {
@@ -6373,9 +6266,7 @@ function MocksPlugins(options = {}) {
6373
6266
  const normalizedDistDir = normalize(distDir);
6374
6267
  return [hoistMocksPlugin({
6375
6268
  filter(id) {
6376
- if (id.includes(normalizedDistDir)) return false;
6377
- if (options.filter) return options.filter(id);
6378
- return true;
6269
+ return id.includes(normalizedDistDir) ? false : options.filter ? options.filter(id) : true;
6379
6270
  },
6380
6271
  codeFrameGenerator(node, id, code) {
6381
6272
  return generateCodeFrame(code, 4, node.start + 1);
@@ -6401,34 +6292,23 @@ const LogLevels = {
6401
6292
  info: 3
6402
6293
  };
6403
6294
  function clearScreen(logger) {
6404
- const repeatCount = process.stdout.rows - 2;
6405
- const blank = repeatCount > 0 ? "\n".repeat(repeatCount) : "";
6295
+ const repeatCount = process.stdout.rows - 2, blank = repeatCount > 0 ? "\n".repeat(repeatCount) : "";
6406
6296
  logger.clearScreen(blank);
6407
6297
  }
6408
- let lastType;
6409
- let lastMsg;
6410
- let sameCount = 0;
6411
- // Only initialize the timeFormatter when the timestamp option is used, and
6412
- // reuse it across all loggers
6413
- let timeFormatter;
6298
+ let lastType, lastMsg, sameCount = 0, timeFormatter;
6414
6299
  function getTimeFormatter() {
6415
- timeFormatter ??= new Intl.DateTimeFormat(void 0, {
6300
+ return timeFormatter ??= new Intl.DateTimeFormat(void 0, {
6416
6301
  hour: "numeric",
6417
6302
  minute: "numeric",
6418
6303
  second: "numeric"
6419
- });
6420
- return timeFormatter;
6304
+ }), timeFormatter;
6421
6305
  }
6422
6306
  // This is copy-pasted and needs to be synced from time to time. Ideally, Vite's `createLogger` should accept a custom `console`
6423
6307
  // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/logger.ts?rgh-link-date=2024-10-16T23%3A29%3A19Z
6424
6308
  // When Vitest supports only Vite 6 and above, we can use Vite's `createLogger({ console })`
6425
6309
  // https://github.com/vitejs/vite/pull/18379
6426
6310
  function createViteLogger(console, level = "info", options = {}) {
6427
- const loggedErrors = /* @__PURE__ */ new WeakSet();
6428
- const { prefix = "[vite]", allowClearScreen = true } = options;
6429
- const thresh = LogLevels[level];
6430
- const canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI;
6431
- const clear = canClearScreen ? clearScreen : () => {};
6311
+ const loggedErrors = /* @__PURE__ */ new WeakSet(), { prefix = "[vite]", allowClearScreen = true } = options, thresh = LogLevels[level], canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI, clear = canClearScreen ? clearScreen : () => {};
6432
6312
  function format(type, msg, options = {}) {
6433
6313
  if (options.timestamp) {
6434
6314
  let tag = "";
@@ -6443,39 +6323,27 @@ function createViteLogger(console, level = "info", options = {}) {
6443
6323
  if (thresh >= LogLevels[type]) {
6444
6324
  const method = type === "info" ? "log" : type;
6445
6325
  if (options.error) loggedErrors.add(options.error);
6446
- if (canClearScreen) if (type === lastType && msg === lastMsg) {
6447
- sameCount++;
6448
- clear(console);
6449
- console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
6450
- } else {
6451
- sameCount = 0;
6452
- lastMsg = msg;
6453
- lastType = type;
6454
- if (options.clear) clear(console);
6326
+ if (canClearScreen) if (type === lastType && msg === lastMsg) sameCount++, clear(console), console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
6327
+ else {
6328
+ if (sameCount = 0, lastMsg = msg, lastType = type, options.clear) clear(console);
6455
6329
  console[method](format(type, msg, options));
6456
6330
  }
6457
6331
  else console[method](format(type, msg, options));
6458
6332
  }
6459
6333
  }
6460
- const warnedMessages = /* @__PURE__ */ new Set();
6461
- const logger = {
6334
+ const warnedMessages = /* @__PURE__ */ new Set(), logger = {
6462
6335
  hasWarned: false,
6463
6336
  info(msg, opts) {
6464
6337
  output("info", msg, opts);
6465
6338
  },
6466
6339
  warn(msg, opts) {
6467
- logger.hasWarned = true;
6468
- output("warn", msg, opts);
6340
+ logger.hasWarned = true, output("warn", msg, opts);
6469
6341
  },
6470
6342
  warnOnce(msg, opts) {
6471
- if (warnedMessages.has(msg)) return;
6472
- logger.hasWarned = true;
6473
- output("warn", msg, opts);
6474
- warnedMessages.add(msg);
6343
+ warnedMessages.has(msg) || (logger.hasWarned = true, output("warn", msg, opts), warnedMessages.add(msg));
6475
6344
  },
6476
6345
  error(msg, opts) {
6477
- logger.hasWarned = true;
6478
- output("error", msg, opts);
6346
+ logger.hasWarned = true, output("error", msg, opts);
6479
6347
  },
6480
6348
  clearScreen(type) {
6481
6349
  if (thresh >= LogLevels[type]) clear(console);
@@ -6491,16 +6359,12 @@ function silenceImportViteIgnoreWarning(logger) {
6491
6359
  return {
6492
6360
  ...logger,
6493
6361
  warn(msg, options) {
6494
- if (msg.includes("The above dynamic import cannot be analyzed by Vite")) return;
6495
- logger.warn(msg, options);
6362
+ msg.includes("The above dynamic import cannot be analyzed by Vite") || logger.warn(msg, options);
6496
6363
  }
6497
6364
  };
6498
6365
  }
6499
6366
 
6500
- const cssLangs = "\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)";
6501
- const cssLangRE = new RegExp(cssLangs);
6502
- const cssModuleRE = /* @__PURE__ */ new RegExp(`\\.module${cssLangs}`);
6503
- const cssInlineRE = /[?&]inline(?:&|$)/;
6367
+ const cssLangs = "\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)", cssLangRE = new RegExp(cssLangs), cssModuleRE = /* @__PURE__ */ new RegExp(`\\.module${cssLangs}`), cssInlineRE = /[?&]inline(?:&|$)/;
6504
6368
  function isCSS(id) {
6505
6369
  return cssLangRE.test(id);
6506
6370
  }
@@ -6520,45 +6384,37 @@ function getCSSModuleProxyReturn(strategy, filename) {
6520
6384
  function CSSEnablerPlugin(ctx) {
6521
6385
  const shouldProcessCSS = (id) => {
6522
6386
  const { css } = ctx.config;
6523
- if (typeof css === "boolean") return css;
6524
- if (toArray(css.exclude).some((re) => re.test(id))) return false;
6525
- if (toArray(css.include).some((re) => re.test(id))) return true;
6526
- return false;
6387
+ return typeof css === "boolean" ? css : toArray(css.exclude).some((re) => re.test(id)) ? false : !!toArray(css.include).some((re) => re.test(id));
6527
6388
  };
6528
6389
  return [{
6529
6390
  name: "vitest:css-disable",
6530
6391
  enforce: "pre",
6531
6392
  transform(code, id) {
6532
- if (!isCSS(id)) return;
6533
- // css plugin inside Vite won't do anything if the code is empty
6534
- // but it will put __vite__updateStyle anyway
6535
- if (!shouldProcessCSS(id)) return { code: "" };
6393
+ if (isCSS(id) && !shouldProcessCSS(id)) return { code: "" };
6536
6394
  }
6537
6395
  }, {
6538
6396
  name: "vitest:css-empty-post",
6539
6397
  enforce: "post",
6540
6398
  transform(_, id) {
6541
- if (!isCSS(id) || shouldProcessCSS(id)) return;
6542
- if (isCSSModule(id) && !isInline(id)) {
6543
- // return proxy for css modules, so that imported module has names:
6544
- // styles.foo returns a "foo" instead of "undefined"
6545
- // we don't use code content to generate hash for "scoped", because it's empty
6546
- const scopeStrategy = typeof ctx.config.css !== "boolean" && ctx.config.css.modules?.classNameStrategy || "stable";
6547
- const proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id));
6548
- const code = `export default new Proxy(Object.create(null), {
6399
+ if (!(!isCSS(id) || shouldProcessCSS(id))) {
6400
+ if (isCSSModule(id) && !isInline(id)) {
6401
+ // return proxy for css modules, so that imported module has names:
6402
+ // styles.foo returns a "foo" instead of "undefined"
6403
+ // we don't use code content to generate hash for "scoped", because it's empty
6404
+ const scopeStrategy = typeof ctx.config.css !== "boolean" && ctx.config.css.modules?.classNameStrategy || "stable", proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id)), code = `export default new Proxy(Object.create(null), {
6549
6405
  get(_, style) {
6550
6406
  return ${proxyReturn};
6551
6407
  },
6552
6408
  })`;
6553
- return { code };
6409
+ return { code };
6410
+ }
6411
+ return { code: "export default \"\"" };
6554
6412
  }
6555
- return { code: "export default \"\"" };
6556
6413
  }
6557
6414
  }];
6558
6415
  }
6559
6416
 
6560
- const metaUrlLength = 15;
6561
- const locationString = "self.location".padEnd(metaUrlLength, " ");
6417
+ const metaUrlLength = 15, locationString = "self.location".padEnd(metaUrlLength, " ");
6562
6418
  // Vite transforms new URL('./path', import.meta.url) to new URL('/path.js', import.meta.url)
6563
6419
  // This makes "href" equal to "http://localhost:3000/path.js" in the browser, but if we keep it like this,
6564
6420
  // then in tests the URL will become "file:///path.js".
@@ -6569,14 +6425,11 @@ function NormalizeURLPlugin() {
6569
6425
  enforce: "post",
6570
6426
  transform(code) {
6571
6427
  if (this.environment.name !== "client" || !code.includes("new URL") || !code.includes("import.meta.url")) return;
6572
- const cleanString = stripLiteral(code);
6573
- const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*(?:'' \+ )?import\.meta\.url\s*(?:,\s*)?\)/g;
6574
- let updatedCode = code;
6575
- let match;
6428
+ const cleanString = stripLiteral(code), assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*(?:'' \+ )?import\.meta\.url\s*(?:,\s*)?\)/g;
6429
+ let updatedCode = code, match;
6576
6430
  // eslint-disable-next-line no-cond-assign
6577
6431
  while (match = assetImportMetaUrlRE.exec(cleanString)) {
6578
- const { 0: exp, index } = match;
6579
- const metaUrlIndex = index + exp.indexOf("import.meta.url");
6432
+ const { 0: exp, index } = match, metaUrlIndex = index + exp.indexOf("import.meta.url");
6580
6433
  updatedCode = updatedCode.slice(0, metaUrlIndex) + locationString + updatedCode.slice(metaUrlIndex + metaUrlLength);
6581
6434
  }
6582
6435
  return {
@@ -6593,10 +6446,7 @@ function VitestOptimizer() {
6593
6446
  config: {
6594
6447
  order: "post",
6595
6448
  handler(viteConfig) {
6596
- const testConfig = viteConfig.test || {};
6597
- const root = resolve(viteConfig.root || process.cwd());
6598
- const name = viteConfig.test?.name;
6599
- const label = typeof name === "string" ? name : name?.label || "";
6449
+ const testConfig = viteConfig.test || {}, root = resolve(viteConfig.root || process.cwd()), name = viteConfig.test?.name, label = typeof name === "string" ? name : name?.label || "";
6600
6450
  viteConfig.cacheDir = VitestCache.resolveCacheDir(resolve(root || process.cwd()), testConfig.cache != null && testConfig.cache !== false ? testConfig.cache.dir : viteConfig.cacheDir, label);
6601
6451
  }
6602
6452
  }
@@ -6606,21 +6456,17 @@ function VitestOptimizer() {
6606
6456
  function resolveOptimizerConfig(_testOptions, viteOptions) {
6607
6457
  const testOptions = _testOptions || {};
6608
6458
  let optimizeDeps;
6609
- if (testOptions.enabled !== true) {
6610
- testOptions.enabled ??= false;
6611
- optimizeDeps = {
6612
- disabled: true,
6613
- entries: []
6614
- };
6615
- } else {
6616
- const currentInclude = testOptions.include || viteOptions?.include || [];
6617
- const exclude = [
6459
+ if (testOptions.enabled !== true) testOptions.enabled ??= false, optimizeDeps = {
6460
+ disabled: true,
6461
+ entries: []
6462
+ };
6463
+ else {
6464
+ const currentInclude = testOptions.include || viteOptions?.include || [], exclude = [
6618
6465
  "vitest",
6619
6466
  "react",
6620
6467
  "vue",
6621
6468
  ...testOptions.exclude || viteOptions?.exclude || []
6622
- ];
6623
- const runtime = currentInclude.filter((n) => n.endsWith("jsx-dev-runtime") || n.endsWith("jsx-runtime"));
6469
+ ], runtime = currentInclude.filter((n) => n.endsWith("jsx-dev-runtime") || n.endsWith("jsx-runtime"));
6624
6470
  exclude.push(...runtime);
6625
6471
  const include = (testOptions.include || viteOptions?.include || []).filter((n) => !exclude.includes(n));
6626
6472
  optimizeDeps = {
@@ -6635,21 +6481,12 @@ function resolveOptimizerConfig(_testOptions, viteOptions) {
6635
6481
  }
6636
6482
  // `optimizeDeps.disabled` is deprecated since v5.1.0-beta.1
6637
6483
  // https://github.com/vitejs/vite/pull/15184
6638
- if (optimizeDeps.disabled) {
6639
- optimizeDeps.noDiscovery = true;
6640
- optimizeDeps.include = [];
6641
- }
6642
- delete optimizeDeps.disabled;
6643
- return optimizeDeps;
6484
+ if (optimizeDeps.disabled) optimizeDeps.noDiscovery = true, optimizeDeps.include = [];
6485
+ return delete optimizeDeps.disabled, optimizeDeps;
6644
6486
  }
6645
6487
  function deleteDefineConfig(viteConfig) {
6646
6488
  const defines = {};
6647
- if (viteConfig.define) {
6648
- delete viteConfig.define["import.meta.vitest"];
6649
- delete viteConfig.define["process.env"];
6650
- delete viteConfig.define.process;
6651
- delete viteConfig.define.global;
6652
- }
6489
+ if (viteConfig.define) delete viteConfig.define["import.meta.vitest"], delete viteConfig.define["process.env"], delete viteConfig.define.process, delete viteConfig.define.global;
6653
6490
  for (const key in viteConfig.define) {
6654
6491
  const val = viteConfig.define[key];
6655
6492
  let replacement;
@@ -6662,26 +6499,20 @@ function deleteDefineConfig(viteConfig) {
6662
6499
  }
6663
6500
  if (key.startsWith("import.meta.env.")) {
6664
6501
  const envKey = key.slice(16);
6665
- process.env[envKey] = replacement;
6666
- delete viteConfig.define[key];
6502
+ process.env[envKey] = replacement, delete viteConfig.define[key];
6667
6503
  } else if (key.startsWith("process.env.")) {
6668
6504
  const envKey = key.slice(12);
6669
- process.env[envKey] = replacement;
6670
- delete viteConfig.define[key];
6671
- } else if (!key.includes(".")) {
6672
- defines[key] = replacement;
6673
- delete viteConfig.define[key];
6674
- }
6505
+ process.env[envKey] = replacement, delete viteConfig.define[key];
6506
+ } else if (!key.includes(".")) defines[key] = replacement, delete viteConfig.define[key];
6675
6507
  }
6676
6508
  return defines;
6677
6509
  }
6678
6510
  function resolveFsAllow(projectRoot, rootConfigFile) {
6679
- if (!rootConfigFile) return [searchForWorkspaceRoot(projectRoot), rootDir];
6680
- return [
6511
+ return rootConfigFile ? [
6681
6512
  dirname(rootConfigFile),
6682
6513
  searchForWorkspaceRoot(projectRoot),
6683
6514
  rootDir
6684
- ];
6515
+ ] : [searchForWorkspaceRoot(projectRoot), rootDir];
6685
6516
  }
6686
6517
  function getDefaultResolveOptions() {
6687
6518
  return {
@@ -6708,78 +6539,44 @@ function ModuleRunnerTransform() {
6708
6539
  const testConfig = config.test || {};
6709
6540
  config.environments ??= {};
6710
6541
  const names = new Set(Object.keys(config.environments));
6711
- names.add("client");
6712
- names.add("ssr");
6542
+ names.add("client"), names.add("ssr");
6713
6543
  const pool = config.test?.pool;
6714
6544
  if (pool === "vmForks" || pool === "vmThreads") names.add("__vitest_vm__");
6715
- const external = [];
6716
- const noExternal = [];
6545
+ const external = [], noExternal = [];
6717
6546
  let noExternalAll;
6718
6547
  for (const name of names) {
6719
6548
  config.environments[name] ??= {};
6720
6549
  const environment = config.environments[name];
6721
- environment.dev ??= {};
6722
6550
  // vm tests run using the native import mechanism
6723
- if (name === "__vitest_vm__") {
6724
- environment.dev.moduleRunnerTransform = false;
6725
- environment.consumer = "client";
6726
- } else environment.dev.moduleRunnerTransform = true;
6727
- environment.dev.preTransformRequests = false;
6728
- environment.keepProcessEnv = true;
6729
- const resolveExternal = name === "client" ? config.resolve?.external : [];
6730
- const resolveNoExternal = name === "client" ? config.resolve?.noExternal : [];
6731
- const topLevelResolveOptions = {};
6551
+ if (environment.dev ??= {}, name === "__vitest_vm__") environment.dev.moduleRunnerTransform = false, environment.consumer = "client";
6552
+ else environment.dev.moduleRunnerTransform = true;
6553
+ environment.dev.preTransformRequests = false, environment.keepProcessEnv = true;
6554
+ const resolveExternal = name === "client" ? config.resolve?.external : [], resolveNoExternal = name === "client" ? config.resolve?.noExternal : [], topLevelResolveOptions = {};
6732
6555
  if (resolveExternal != null) topLevelResolveOptions.external = resolveExternal;
6733
6556
  if (resolveNoExternal != null) topLevelResolveOptions.noExternal = resolveNoExternal;
6734
- const currentResolveOptions = mergeConfig(topLevelResolveOptions, environment.resolve || {});
6735
- const envNoExternal = resolveViteResolveOptions("noExternal", currentResolveOptions);
6557
+ const currentResolveOptions = mergeConfig(topLevelResolveOptions, environment.resolve || {}), envNoExternal = resolveViteResolveOptions("noExternal", currentResolveOptions);
6736
6558
  if (envNoExternal === true) noExternalAll = true;
6737
6559
  else noExternal.push(...envNoExternal);
6738
6560
  const envExternal = resolveViteResolveOptions("external", currentResolveOptions);
6739
6561
  if (envExternal !== true) external.push(...envExternal);
6740
- // remove Vite's externalization logic because we have our own (unfortunetly)
6741
- environment.resolve ??= {};
6742
- environment.resolve.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
6743
- // by setting `noExternal` to `true`, we make sure that
6744
- // Vite will never use its own externalization mechanism
6745
- // to externalize modules and always resolve static imports
6746
- // in both SSR and Client environments
6747
- environment.resolve.noExternal = true;
6748
- if (name === "__vitest_vm__" || name === "__vitest__") continue;
6749
- const currentOptimizeDeps = environment.optimizeDeps || (name === "client" ? config.optimizeDeps : name === "ssr" ? config.ssr?.optimizeDeps : void 0);
6750
- const optimizeDeps = resolveOptimizerConfig(testConfig.deps?.optimizer?.[name], currentOptimizeDeps);
6562
+ if (environment.resolve ??= {}, environment.resolve.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)], environment.resolve.noExternal = true, name === "__vitest_vm__" || name === "__vitest__") continue;
6563
+ const currentOptimizeDeps = environment.optimizeDeps || (name === "client" ? config.optimizeDeps : name === "ssr" ? config.ssr?.optimizeDeps : void 0), optimizeDeps = resolveOptimizerConfig(testConfig.deps?.optimizer?.[name], currentOptimizeDeps);
6751
6564
  // Vite respects the root level optimize deps, so we override it instead
6752
- if (name === "client") {
6753
- config.optimizeDeps = optimizeDeps;
6754
- environment.optimizeDeps = void 0;
6755
- } else if (name === "ssr") {
6756
- config.ssr ??= {};
6757
- config.ssr.optimizeDeps = optimizeDeps;
6758
- environment.optimizeDeps = void 0;
6759
- } else environment.optimizeDeps = optimizeDeps;
6565
+ if (name === "client") config.optimizeDeps = optimizeDeps, environment.optimizeDeps = void 0;
6566
+ else if (name === "ssr") config.ssr ??= {}, config.ssr.optimizeDeps = optimizeDeps, environment.optimizeDeps = void 0;
6567
+ else environment.optimizeDeps = optimizeDeps;
6760
6568
  }
6761
- testConfig.server ??= {};
6762
- testConfig.server.deps ??= {};
6763
- if (testConfig.server.deps.inline !== true) {
6569
+ if (testConfig.server ??= {}, testConfig.server.deps ??= {}, testConfig.server.deps.inline !== true) {
6764
6570
  if (noExternalAll) testConfig.server.deps.inline = true;
6765
- else if (noExternal.length) {
6766
- testConfig.server.deps.inline ??= [];
6767
- testConfig.server.deps.inline.push(...noExternal);
6768
- }
6769
- }
6770
- if (external.length) {
6771
- testConfig.server.deps.external ??= [];
6772
- testConfig.server.deps.external.push(...external);
6571
+ else if (noExternal.length) testConfig.server.deps.inline ??= [], testConfig.server.deps.inline.push(...noExternal);
6773
6572
  }
6573
+ if (external.length) testConfig.server.deps.external ??= [], testConfig.server.deps.external.push(...external);
6774
6574
  }
6775
6575
  }
6776
6576
  };
6777
6577
  }
6778
6578
  function resolveViteResolveOptions(key, options) {
6779
- if (Array.isArray(options[key])) return options[key];
6780
- else if (typeof options[key] === "string" || options[key] instanceof RegExp) return [options[key]];
6781
- else if (typeof options[key] === "boolean") return true;
6782
- return [];
6579
+ return Array.isArray(options[key]) ? options[key] : typeof options[key] === "string" || options[key] instanceof RegExp ? [options[key]] : typeof options[key] === "boolean" ? true : [];
6783
6580
  }
6784
6581
 
6785
6582
  function VitestProjectResolver(ctx) {
@@ -6826,23 +6623,16 @@ function WorkspaceVitestPlugin(project, options) {
6826
6623
  };
6827
6624
  if (!name) if (typeof options.workspacePath === "string") {
6828
6625
  // if there is a package.json, read the name from it
6829
- const dir = options.workspacePath.endsWith("/") ? options.workspacePath.slice(0, -1) : dirname(options.workspacePath);
6830
- const pkgJsonPath = resolve(dir, "package.json");
6626
+ const dir = options.workspacePath.endsWith("/") ? options.workspacePath.slice(0, -1) : dirname(options.workspacePath), pkgJsonPath = resolve(dir, "package.json");
6831
6627
  if (existsSync(pkgJsonPath)) name = JSON.parse(readFileSync(pkgJsonPath, "utf-8")).name;
6832
6628
  if (typeof name !== "string" || !name) name = basename(dir);
6833
6629
  } else name = options.workspacePath.toString();
6834
- const isUserBrowserEnabled = viteConfig.test?.browser?.enabled;
6835
- const isBrowserEnabled = isUserBrowserEnabled ?? (viteConfig.test?.browser && project.vitest._cliOptions.browser?.enabled);
6836
- // keep project names to potentially filter it out
6837
- const workspaceNames = [name];
6838
- const browser = viteConfig.test.browser || {};
6630
+ const isUserBrowserEnabled = viteConfig.test?.browser?.enabled, isBrowserEnabled = isUserBrowserEnabled ?? (viteConfig.test?.browser && project.vitest._cliOptions.browser?.enabled), workspaceNames = [name], browser = viteConfig.test.browser || {};
6839
6631
  if (isBrowserEnabled && browser.name && !browser.instances?.length)
6840
6632
  // vitest injects `instances` in this case later on
6841
6633
  workspaceNames.push(name ? `${name} (${browser.name})` : browser.name);
6842
6634
  viteConfig.test?.browser?.instances?.forEach((instance) => {
6843
- // every instance is a potential project
6844
- instance.name ??= name ? `${name} (${instance.browser})` : instance.browser;
6845
- if (isBrowserEnabled) workspaceNames.push(instance.name);
6635
+ if (instance.name ??= name ? `${name} (${instance.browser})` : instance.browser, isBrowserEnabled) workspaceNames.push(instance.name);
6846
6636
  });
6847
6637
  const filters = project.vitest.config.project;
6848
6638
  // if there is `--project=...` filter, check if any of the potential projects match
@@ -6870,22 +6660,14 @@ function WorkspaceVitestPlugin(project, options) {
6870
6660
  this.meta.watchMode = false;
6871
6661
  },
6872
6662
  config(viteConfig) {
6873
- const defines = deleteDefineConfig(viteConfig);
6874
- const testConfig = viteConfig.test || {};
6875
- const root = testConfig.root || viteConfig.root || options.root;
6876
- const resolveOptions = getDefaultResolveOptions();
6877
- const config = {
6663
+ const defines = deleteDefineConfig(viteConfig), testConfig = viteConfig.test || {}, root = testConfig.root || viteConfig.root || options.root, resolveOptions = getDefaultResolveOptions();
6664
+ let config = {
6878
6665
  root,
6879
6666
  define: { "process.env.NODE_ENV": "process.env.NODE_ENV" },
6880
6667
  resolve: {
6881
6668
  ...resolveOptions,
6882
6669
  alias: testConfig.alias
6883
6670
  },
6884
- esbuild: viteConfig.esbuild === false ? false : {
6885
- target: viteConfig.esbuild?.target || "node18",
6886
- sourcemap: "external",
6887
- legalComments: "inline"
6888
- },
6889
6671
  server: {
6890
6672
  watch: null,
6891
6673
  open: false,
@@ -6898,19 +6680,27 @@ function WorkspaceVitestPlugin(project, options) {
6898
6680
  environments: { ssr: { resolve: resolveOptions } },
6899
6681
  test: {}
6900
6682
  };
6683
+ if ("rolldownVersion" in vite) config = {
6684
+ ...config,
6685
+ oxc: viteConfig.oxc === false ? false : { target: viteConfig.oxc?.target || "node18" }
6686
+ };
6687
+ else config = {
6688
+ ...config,
6689
+ esbuild: viteConfig.esbuild === false ? false : {
6690
+ target: viteConfig.esbuild?.target || "node18",
6691
+ sourcemap: "external",
6692
+ legalComments: "inline"
6693
+ }
6694
+ };
6901
6695
  config.test.defines = defines;
6902
6696
  const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
6903
6697
  if (classNameStrategy !== "scoped") {
6904
- config.css ??= {};
6905
- config.css.modules ??= {};
6906
- if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
6698
+ if (config.css ??= {}, config.css.modules ??= {}, config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
6907
6699
  const root = project.config.root;
6908
6700
  return generateScopedClassName(classNameStrategy, name, relative(root, filename));
6909
6701
  };
6910
6702
  }
6911
- config.customLogger = createViteLogger(project.vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
6912
- config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
6913
- return config;
6703
+ return config.customLogger = createViteLogger(project.vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false }), config.customLogger = silenceImportViteIgnoreWarning(config.customLogger), config;
6914
6704
  }
6915
6705
  },
6916
6706
  {
@@ -6918,8 +6708,7 @@ function WorkspaceVitestPlugin(project, options) {
6918
6708
  enforce: "post",
6919
6709
  async configureServer(server) {
6920
6710
  const options = deepMerge({}, configDefaults, server.config.test || {});
6921
- await project._configureServer(options, server);
6922
- await server.watcher.close();
6711
+ await project._configureServer(options, server), await server.watcher.close();
6923
6712
  }
6924
6713
  },
6925
6714
  MetaEnvReplacerPlugin(),
@@ -6962,10 +6751,7 @@ const BUILTIN_EXTENSIONS = new Set([
6962
6751
  ".cjs",
6963
6752
  ".node",
6964
6753
  ".wasm"
6965
- ]);
6966
- const ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/;
6967
- const ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/;
6968
- const defaultInline = [
6754
+ ]), ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/, ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/, defaultInline = [
6969
6755
  /virtual:/,
6970
6756
  /\.[mc]?ts$/,
6971
6757
  /[?&](init|raw|url|inline)\b/,
@@ -6973,8 +6759,7 @@ const defaultInline = [
6973
6759
  /^(?!.*node_modules).*\.mjs$/,
6974
6760
  /^(?!.*node_modules).*\.cjs\.js$/,
6975
6761
  /vite\w*\/dist\/client\/env.mjs/
6976
- ];
6977
- const depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
6762
+ ], depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
6978
6763
  function guessCJSversion(id) {
6979
6764
  if (id.match(ESM_EXT_RE)) {
6980
6765
  for (const i of [
@@ -7004,8 +6789,7 @@ async function isValidNodeImport(id) {
7004
6789
  if (/\.(?:\w+-)?esm?(?:-\w+)?\.js$|\/esm?\//.test(id)) return false;
7005
6790
  try {
7006
6791
  await esModuleLexer.init;
7007
- const code = await promises.readFile(id, "utf8");
7008
- const [, , , hasModuleSyntax] = esModuleLexer.parse(code);
6792
+ const code = await promises.readFile(id, "utf8"), [, , , hasModuleSyntax] = esModuleLexer.parse(code);
7009
6793
  return !hasModuleSyntax;
7010
6794
  } catch {
7011
6795
  return false;
@@ -7016,25 +6800,17 @@ async function shouldExternalize(id, options, cache) {
7016
6800
  return cache.get(id);
7017
6801
  }
7018
6802
  async function _shouldExternalize(id, options) {
7019
- if (isBuiltin(id)) return id;
7020
6803
  // data: should be processed by native import,
7021
6804
  // since it is a feature of ESM.
7022
6805
  // also externalize network imports since nodejs allows it when --experimental-network-imports
7023
- if (id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
6806
+ if (isBuiltin(id) || id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
7024
6807
  const moduleDirectories = options?.moduleDirectories || ["/node_modules/"];
7025
- if (matchExternalizePattern(id, moduleDirectories, options?.inline)) return false;
7026
- if (options?.inlineFiles && options?.inlineFiles.includes(id)) return false;
7027
- if (matchExternalizePattern(id, moduleDirectories, options?.external)) return id;
6808
+ if (matchExternalizePattern(id, moduleDirectories, options?.inline) || options?.inlineFiles && options?.inlineFiles.includes(id)) return false;
7028
6809
  // Unless the user explicitly opted to inline them, externalize Vite deps.
7029
6810
  // They are too big to inline by default.
7030
- if (options?.cacheDir && id.includes(options.cacheDir)) return id;
7031
- const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir));
7032
- const guessCJS = isLibraryModule && options?.fallbackCJS;
7033
- id = guessCJS ? guessCJSversion(id) || id : id;
7034
- if (matchExternalizePattern(id, moduleDirectories, defaultInline)) return false;
7035
- if (matchExternalizePattern(id, moduleDirectories, depsExternal)) return id;
7036
- if (isLibraryModule && await isValidNodeImport(id)) return id;
7037
- return false;
6811
+ if (matchExternalizePattern(id, moduleDirectories, options?.external) || options?.cacheDir && id.includes(options.cacheDir)) return id;
6812
+ const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir)), guessCJS = isLibraryModule && options?.fallbackCJS;
6813
+ return id = guessCJS ? guessCJSversion(id) || id : id, matchExternalizePattern(id, moduleDirectories, defaultInline) ? false : matchExternalizePattern(id, moduleDirectories, depsExternal) || isLibraryModule && await isValidNodeImport(id) ? id : false;
7038
6814
  }
7039
6815
  function matchExternalizePattern(id, moduleDirectories, patterns) {
7040
6816
  if (patterns == null) return false;
@@ -7080,24 +6856,16 @@ class TestSpecification {
7080
6856
  */
7081
6857
  testLines;
7082
6858
  constructor(project, moduleId, pool, testLines) {
7083
- this[0] = project;
7084
- this[1] = moduleId;
7085
- this[2] = { pool };
7086
- const name = project.config.name;
7087
- const hashName = pool !== "typescript" ? name : name ? `${name}:__typecheck__` : "__typecheck__";
7088
- this.taskId = generateFileHash(relative(project.config.root, moduleId), hashName);
7089
- this.project = project;
7090
- this.moduleId = moduleId;
7091
- this.pool = pool;
7092
- this.testLines = testLines;
6859
+ this[0] = project, this[1] = moduleId, this[2] = { pool };
6860
+ const name = project.config.name, hashName = pool !== "typescript" ? name : name ? `${name}:__typecheck__` : "__typecheck__";
6861
+ this.taskId = generateFileHash(relative(project.config.root, moduleId), hashName), this.project = project, this.moduleId = moduleId, this.pool = pool, this.testLines = testLines;
7093
6862
  }
7094
6863
  /**
7095
6864
  * Test module associated with the specification.
7096
6865
  */
7097
6866
  get testModule() {
7098
6867
  const task = this.project.vitest.state.idMap.get(this.taskId);
7099
- if (!task) return void 0;
7100
- return this.project.vitest.state.getReportedEntity(task);
6868
+ return task ? this.project.vitest.state.getReportedEntity(task) : void 0;
7101
6869
  }
7102
6870
  toJSON() {
7103
6871
  return [
@@ -7117,9 +6885,7 @@ class TestSpecification {
7117
6885
  * @deprecated
7118
6886
  */
7119
6887
  *[Symbol.iterator]() {
7120
- yield this.project;
7121
- yield this.moduleId;
7122
- yield this.pool;
6888
+ yield this.project, yield this.moduleId, yield this.pool;
7123
6889
  }
7124
6890
  }
7125
6891
 
@@ -7128,12 +6894,10 @@ async function createViteServer(inlineConfig) {
7128
6894
  // But Vitest works correctly either way
7129
6895
  const error = console.error;
7130
6896
  console.error = (...args) => {
7131
- if (typeof args[0] === "string" && args[0].includes("WebSocket server error:")) return;
7132
- error(...args);
6897
+ typeof args[0] === "string" && args[0].includes("WebSocket server error:") || error(...args);
7133
6898
  };
7134
6899
  const server = await createServer(inlineConfig);
7135
- console.error = error;
7136
- return server;
6900
+ return console.error = error, server;
7137
6901
  }
7138
6902
 
7139
6903
  class TestProject {
@@ -7168,11 +6932,7 @@ class TestProject {
7168
6932
  _globalSetups;
7169
6933
  _provided = {};
7170
6934
  constructor(path, vitest, options) {
7171
- this.path = path;
7172
- this.options = options;
7173
- this.vitest = vitest;
7174
- this.ctx = vitest;
7175
- this.globalConfig = vitest.config;
6935
+ this.path = path, this.options = options, this.vitest = vitest, this.ctx = vitest, this.globalConfig = vitest.config;
7176
6936
  }
7177
6937
  /**
7178
6938
  * The unique hash of this project. This value is consistent between the reruns.
@@ -7201,10 +6961,9 @@ class TestProject {
7201
6961
  * Get the provided context. The project context is merged with the global context.
7202
6962
  */
7203
6963
  getProvidedContext() {
7204
- if (this.isRootProject()) return this._provided;
7205
6964
  // globalSetup can run even if core workspace is not part of the test run
7206
6965
  // so we need to inherit its provided context
7207
- return {
6966
+ return this.isRootProject() ? this._provided : {
7208
6967
  ...this.vitest.getRootProject().getProvidedContext(),
7209
6968
  ...this._provided
7210
6969
  };
@@ -7228,13 +6987,11 @@ class TestProject {
7228
6987
  */
7229
6988
  get vite() {
7230
6989
  if (!this._vite) throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
7231
- // checking it once should be enough
7232
- Object.defineProperty(this, "vite", {
6990
+ return Object.defineProperty(this, "vite", {
7233
6991
  configurable: true,
7234
6992
  writable: true,
7235
6993
  value: this._vite
7236
- });
7237
- return this._vite;
6994
+ }), this._vite;
7238
6995
  }
7239
6996
  /**
7240
6997
  * Resolved project configuration.
@@ -7291,13 +7048,14 @@ class TestProject {
7291
7048
  }
7292
7049
  /** @internal */
7293
7050
  async _initializeGlobalSetup() {
7294
- if (this._globalSetups) return;
7295
- this._globalSetups = await loadGlobalSetupFiles(this.runner, this.config.globalSetup);
7296
- for (const globalSetupFile of this._globalSetups) {
7297
- const teardown = await globalSetupFile.setup?.(this);
7298
- if (teardown == null || !!globalSetupFile.teardown) continue;
7299
- if (typeof teardown !== "function") throw new TypeError(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
7300
- globalSetupFile.teardown = teardown;
7051
+ if (!this._globalSetups) {
7052
+ this._globalSetups = await loadGlobalSetupFiles(this.runner, this.config.globalSetup);
7053
+ for (const globalSetupFile of this._globalSetups) {
7054
+ const teardown = await globalSetupFile.setup?.(this);
7055
+ if (teardown == null || !!globalSetupFile.teardown) continue;
7056
+ if (typeof teardown !== "function") throw new TypeError(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
7057
+ globalSetupFile.teardown = teardown;
7058
+ }
7301
7059
  }
7302
7060
  }
7303
7061
  onTestsRerun(cb) {
@@ -7309,8 +7067,7 @@ class TestProject {
7309
7067
  }
7310
7068
  /** @internal */
7311
7069
  async _teardownGlobalSetup() {
7312
- if (!this._globalSetups) return;
7313
- for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
7070
+ if (this._globalSetups) for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
7314
7071
  }
7315
7072
  /** @deprecated use `vitest.logger` instead */
7316
7073
  get logger() {
@@ -7340,12 +7097,8 @@ class TestProject {
7340
7097
  * @param filters String filters to match the test files.
7341
7098
  */
7342
7099
  async globTestFiles(filters = []) {
7343
- const dir = this.config.dir || this.config.root;
7344
- const { include, exclude, includeSource } = this.config;
7345
- const typecheck = this.config.typecheck;
7346
- const [testFiles, typecheckTestFiles] = await Promise.all([typecheck.enabled && typecheck.only ? [] : this.globAllTestFiles(include, exclude, includeSource, dir), typecheck.enabled ? this.typecheckFilesList || this.globFiles(typecheck.include, typecheck.exclude, dir) : []]);
7347
- this.typecheckFilesList = typecheckTestFiles;
7348
- return {
7100
+ const dir = this.config.dir || this.config.root, { include, exclude, includeSource } = this.config, typecheck = this.config.typecheck, [testFiles, typecheckTestFiles] = await Promise.all([typecheck.enabled && typecheck.only ? [] : this.globAllTestFiles(include, exclude, includeSource, dir), typecheck.enabled ? this.typecheckFilesList || this.globFiles(typecheck.include, typecheck.exclude, dir) : []]);
7101
+ return this.typecheckFilesList = typecheckTestFiles, {
7349
7102
  testFiles: this.filterFiles(testFiles, filters, dir),
7350
7103
  typecheckTestFiles: this.filterFiles(typecheckTestFiles, filters, dir)
7351
7104
  };
@@ -7364,8 +7117,7 @@ class TestProject {
7364
7117
  }
7365
7118
  }));
7366
7119
  }
7367
- this.testFilesList = testFiles;
7368
- return testFiles;
7120
+ return this.testFilesList = testFiles, testFiles;
7369
7121
  }
7370
7122
  isBrowserEnabled() {
7371
7123
  return isBrowserEnabled(this.config);
@@ -7402,8 +7154,7 @@ class TestProject {
7402
7154
  cwd,
7403
7155
  ignore: exclude,
7404
7156
  expandDirectories: false
7405
- };
7406
- const files = await glob(include, globOptions);
7157
+ }, files = await glob(include, globOptions);
7407
7158
  // keep the slashes consistent with Vite
7408
7159
  // we are not using the pathe here because it normalizes the drive letter on Windows
7409
7160
  // and we want to keep it the same as working dir
@@ -7416,16 +7167,10 @@ class TestProject {
7416
7167
  if (this._isCachedTestFile(moduleId)) return true;
7417
7168
  const relativeId = relative(this.config.dir || this.config.root, moduleId);
7418
7169
  if (pm.isMatch(relativeId, this.config.exclude)) return false;
7419
- if (pm.isMatch(relativeId, this.config.include)) {
7420
- this.markTestFile(moduleId);
7421
- return true;
7422
- }
7170
+ if (pm.isMatch(relativeId, this.config.include)) return this.markTestFile(moduleId), true;
7423
7171
  if (this.config.includeSource?.length && pm.isMatch(relativeId, this.config.includeSource)) {
7424
7172
  const code = source?.() || readFileSync(moduleId, "utf-8");
7425
- if (this.isInSourceTestCode(code)) {
7426
- this.markTestFile(moduleId);
7427
- return true;
7428
- }
7173
+ if (this.isInSourceTestCode(code)) return this.markTestFile(moduleId), true;
7429
7174
  }
7430
7175
  return false;
7431
7176
  }
@@ -7438,7 +7183,7 @@ class TestProject {
7438
7183
  }
7439
7184
  filterFiles(testFiles, filters, dir) {
7440
7185
  if (filters.length && process.platform === "win32") filters = filters.map((f) => slash(f));
7441
- if (filters.length) return testFiles.filter((t) => {
7186
+ return filters.length ? testFiles.filter((t) => {
7442
7187
  const testFile = relative(dir, t).toLocaleLowerCase();
7443
7188
  return filters.some((f) => {
7444
7189
  // if filter is a full file path, we should include it if it's in the same folder
@@ -7446,8 +7191,7 @@ class TestProject {
7446
7191
  const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
7447
7192
  return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
7448
7193
  });
7449
- });
7450
- return testFiles;
7194
+ }) : testFiles;
7451
7195
  }
7452
7196
  _parentBrowser;
7453
7197
  /** @internal */
@@ -7466,21 +7210,15 @@ class TestProject {
7466
7210
  }
7467
7211
  },
7468
7212
  ...MocksPlugins({ filter(id) {
7469
- if (id.includes(distRoot) || id.includes(cacheDir)) return false;
7470
- return true;
7213
+ return !(id.includes(distRoot) || id.includes(cacheDir));
7471
7214
  } }),
7472
7215
  MetaEnvReplacerPlugin()
7473
7216
  ], [CoverageTransform(this.vitest)]);
7474
- this._parentBrowser = browser;
7475
- if (this.config.browser.ui) setup(this.vitest, browser.vite);
7217
+ if (this._parentBrowser = browser, this.config.browser.ui) setup(this.vitest, browser.vite);
7476
7218
  });
7477
7219
  /** @internal */
7478
7220
  _initBrowserServer = deduped(async () => {
7479
- await this._parent?._initParentBrowser();
7480
- if (!this.browser && this._parent?._parentBrowser) {
7481
- this.browser = this._parent._parentBrowser.spawn(this);
7482
- await this.vitest.report("onBrowserInit", this);
7483
- }
7221
+ if (await this._parent?._initParentBrowser(), !this.browser && this._parent?._parentBrowser) this.browser = this._parent._parentBrowser.spawn(this), await this.vitest.report("onBrowserInit", this);
7484
7222
  });
7485
7223
  /**
7486
7224
  * Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts.
@@ -7493,8 +7231,7 @@ class TestProject {
7493
7231
  this.browser?.close(),
7494
7232
  this.clearTmpDir()
7495
7233
  ].filter(Boolean)).then(() => {
7496
- this._provided = {};
7497
- this._vite = void 0;
7234
+ this._provided = {}, this._vite = void 0;
7498
7235
  });
7499
7236
  return this.closingPromise;
7500
7237
  }
@@ -7518,27 +7255,22 @@ class TestProject {
7518
7255
  }
7519
7256
  /** @internal */
7520
7257
  async _configureServer(options, server) {
7521
- this._config = resolveConfig(this.vitest, {
7258
+ for (const _providedKey in this._config = resolveConfig(this.vitest, {
7522
7259
  ...options,
7523
7260
  coverage: this.vitest.config.coverage
7524
- }, server.config);
7525
- this._setHash();
7526
- for (const _providedKey in this.config.provide) {
7261
+ }, server.config), this._setHash(), this.config.provide) {
7527
7262
  const providedKey = _providedKey;
7528
7263
  // type is very strict here, so we cast it to any
7529
7264
  this.provide(providedKey, this.config.provide[providedKey]);
7530
7265
  }
7531
- this.closingPromise = void 0;
7532
- this._resolver = new VitestResolver(server.config.cacheDir, this._config);
7533
- this._vite = server;
7266
+ this.closingPromise = void 0, this._resolver = new VitestResolver(server.config.cacheDir, this._config), this._vite = server;
7534
7267
  const environment = server.environments.__vitest__;
7535
7268
  this.runner = new ServerModuleRunner(environment, this._resolver, this._config);
7536
7269
  }
7537
7270
  _serializeOverriddenConfig() {
7538
7271
  // TODO: serialize the config _once_ or when needed
7539
7272
  const config = serializeConfig(this.config, this.vitest.config, this.vite.config);
7540
- if (!this.vitest.configOverride) return config;
7541
- return deepMerge(config, this.vitest.configOverride);
7273
+ return this.vitest.configOverride ? deepMerge(config, this.vitest.configOverride) : config;
7542
7274
  }
7543
7275
  async clearTmpDir() {
7544
7276
  try {
@@ -7551,9 +7283,10 @@ class TestProject {
7551
7283
  }
7552
7284
  /** @internal */
7553
7285
  _initBrowserProvider = deduped(async () => {
7554
- if (!this.isBrowserEnabled() || this.browser?.provider) return;
7555
- if (!this.browser) await this._initBrowserServer();
7556
- await this.browser?.initBrowserProvider(this);
7286
+ if (!(!this.isBrowserEnabled() || this.browser?.provider)) {
7287
+ if (!this.browser) await this._initBrowserServer();
7288
+ await this.browser?.initBrowserProvider(this);
7289
+ }
7557
7290
  });
7558
7291
  /** @internal */
7559
7292
  _provideObject(context) {
@@ -7566,40 +7299,25 @@ class TestProject {
7566
7299
  /** @internal */
7567
7300
  static _createBasicProject(vitest) {
7568
7301
  const project = new TestProject(vitest.config.name || vitest.config.root, vitest);
7569
- project.runner = vitest.runner;
7570
- project._vite = vitest.server;
7571
- project._config = vitest.config;
7572
- project._resolver = vitest._resolver;
7573
- project._setHash();
7574
- project._provideObject(vitest.config.provide);
7575
- return project;
7302
+ return project.runner = vitest.runner, project._vite = vitest.server, project._config = vitest.config, project._resolver = vitest._resolver, project._setHash(), project._provideObject(vitest.config.provide), project;
7576
7303
  }
7577
7304
  /** @internal */
7578
7305
  static _cloneBrowserProject(parent, config) {
7579
7306
  const clone = new TestProject(parent.path, parent.vitest);
7580
- clone.runner = parent.runner;
7581
- clone._vite = parent._vite;
7582
- clone._resolver = parent._resolver;
7583
- clone._config = config;
7584
- clone._setHash();
7585
- clone._parent = parent;
7586
- clone._provideObject(config.provide);
7587
- return clone;
7307
+ return clone.runner = parent.runner, clone._vite = parent._vite, clone._resolver = parent._resolver, clone._config = config, clone._setHash(), clone._parent = parent, clone._provideObject(config.provide), clone;
7588
7308
  }
7589
7309
  }
7590
7310
  function deduped(cb) {
7591
7311
  let _promise;
7592
- return (...args) => {
7312
+ return ((...args) => {
7593
7313
  if (!_promise) _promise = cb(...args).finally(() => {
7594
7314
  _promise = void 0;
7595
7315
  });
7596
7316
  return _promise;
7597
- };
7317
+ });
7598
7318
  }
7599
7319
  async function initializeProject(workspacePath, ctx, options) {
7600
- const project = new TestProject(workspacePath, ctx, options);
7601
- const { configFile,...restOptions } = options;
7602
- const config = {
7320
+ const project = new TestProject(workspacePath, ctx, options), { configFile,...restOptions } = options, config = {
7603
7321
  ...restOptions,
7604
7322
  configFile,
7605
7323
  configLoader: ctx.vite.config.inlineConfig.configLoader,
@@ -7609,25 +7327,20 @@ async function initializeProject(workspacePath, ctx, options) {
7609
7327
  workspacePath
7610
7328
  })]
7611
7329
  };
7612
- await createViteServer(config);
7613
- return project;
7330
+ return await createViteServer(config), project;
7614
7331
  }
7615
7332
  function generateHash(str) {
7616
7333
  let hash = 0;
7617
7334
  if (str.length === 0) return `${hash}`;
7618
7335
  for (let i = 0; i < str.length; i++) {
7619
7336
  const char = str.charCodeAt(i);
7620
- hash = (hash << 5) - hash + char;
7621
- hash = hash & hash;
7337
+ hash = (hash << 5) - hash + char, hash = hash & hash;
7622
7338
  }
7623
7339
  return `${hash}`;
7624
7340
  }
7625
7341
 
7626
7342
  async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projectsDefinition, names) {
7627
- const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition);
7628
- // cli options that affect the project config,
7629
- // not all options are allowed to be overridden
7630
- const overridesOptions = [
7343
+ const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition), overridesOptions = [
7631
7344
  "logHeapUsage",
7632
7345
  "allowOnly",
7633
7346
  "sequence",
@@ -7646,21 +7359,12 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
7646
7359
  "inspect",
7647
7360
  "inspectBrk",
7648
7361
  "fileParallelism"
7649
- ];
7650
- const cliOverrides = overridesOptions.reduce((acc, name) => {
7362
+ ], cliOverrides = overridesOptions.reduce((acc, name) => {
7651
7363
  if (name in cliOptions) acc[name] = cliOptions[name];
7652
7364
  return acc;
7653
- }, {});
7654
- const projectPromises = [];
7655
- const fileProjects = [...configFiles, ...nonConfigDirectories];
7656
- const concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
7365
+ }, {}), projectPromises = [], fileProjects = [...configFiles, ...nonConfigDirectories], concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
7657
7366
  projectConfigs.forEach((options, index) => {
7658
- const configRoot = vitest.config.root;
7659
- // if extends a config file, resolve the file path
7660
- const configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : options.extends === true ? vitest.vite.config.configFile || false : false;
7661
- // if `root` is configured, resolve it relative to the workspace file or vite root (like other options)
7662
- // if `root` is not specified, inline configs use the same root as the root project
7663
- const root = options.root ? resolve(configRoot, options.root) : vitest.config.root;
7367
+ const configRoot = vitest.config.root, configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : options.extends === true ? vitest.vite.config.configFile || false : false, root = options.root ? resolve(configRoot, options.root) : vitest.config.root;
7664
7368
  projectPromises.push(concurrent(() => initializeProject(index, vitest, {
7665
7369
  ...options,
7666
7370
  root,
@@ -7678,8 +7382,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
7678
7382
  if (project) projectPromises.push(Promise.resolve(project));
7679
7383
  continue;
7680
7384
  }
7681
- const configFile = path.endsWith("/") ? false : path;
7682
- const root = path.endsWith("/") ? path : dirname(path);
7385
+ const configFile = path.endsWith("/") ? false : path, root = path.endsWith("/") ? path : dirname(path);
7683
7386
  projectPromises.push(concurrent(() => initializeProject(path, vitest, {
7684
7387
  root,
7685
7388
  configFile,
@@ -7692,9 +7395,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
7692
7395
  vitest.config.project.length ? `The filter matched no projects: ${vitest.config.project.join(", ")}. ` : "",
7693
7396
  `The projects definition: ${JSON.stringify(projectsDefinition, null, 4)}.`
7694
7397
  ].join(""));
7695
- const resolvedProjectsPromises = await Promise.allSettled(projectPromises);
7696
- const errors = [];
7697
- const resolvedProjects = [];
7398
+ const resolvedProjectsPromises = await Promise.allSettled(projectPromises), errors = [], resolvedProjects = [];
7698
7399
  for (const result of resolvedProjectsPromises) if (result.status === "rejected") {
7699
7400
  if (result.reason instanceof VitestFilteredOutProjectError)
7700
7401
  // filter out filtered out projects
@@ -7706,8 +7407,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
7706
7407
  for (const project of resolvedProjects) {
7707
7408
  const name = project.name;
7708
7409
  if (names.has(name)) {
7709
- const duplicate = resolvedProjects.find((p) => p.name === name && p !== project);
7710
- const filesError = fileProjects.length ? [
7410
+ const duplicate = resolvedProjects.find((p) => p.name === name && p !== project), filesError = fileProjects.length ? [
7711
7411
  "\n\nYour config matched these files:\n",
7712
7412
  fileProjects.map((p) => ` - ${relative(vitest.config.root, p)}`).join("\n"),
7713
7413
  "\n\n"
@@ -7729,24 +7429,18 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
7729
7429
  const removeProjects = /* @__PURE__ */ new Set();
7730
7430
  resolvedProjects.forEach((project) => {
7731
7431
  if (!project.config.browser.enabled) return;
7732
- const instances = project.config.browser.instances || [];
7733
- const browser = project.config.browser.name;
7734
- if (instances.length === 0 && browser) {
7735
- instances.push({
7736
- browser,
7737
- name: project.name ? `${project.name} (${browser})` : browser
7738
- });
7739
- vitest.logger.warn(withLabel("yellow", "Vitest", [
7740
- `No browser "instances" were defined`,
7741
- project.name ? ` for the "${project.name}" project. ` : ". ",
7742
- `Running tests in "${project.config.browser.name}" browser. `,
7743
- "The \"browser.name\" field is deprecated since Vitest 3. ",
7744
- "Read more: https://vitest.dev/guide/browser/config#browser-instances"
7745
- ].filter(Boolean).join("")));
7746
- }
7747
- const originalName = project.config.name;
7748
- // if original name is in the --project=name filter, keep all instances
7749
- const filteredInstances = vitest.matchesProjectFilter(originalName) ? instances : instances.filter((instance) => {
7432
+ const instances = project.config.browser.instances || [], browser = project.config.browser.name;
7433
+ if (instances.length === 0 && browser) instances.push({
7434
+ browser,
7435
+ name: project.name ? `${project.name} (${browser})` : browser
7436
+ }), vitest.logger.warn(withLabel("yellow", "Vitest", [
7437
+ `No browser "instances" were defined`,
7438
+ project.name ? ` for the "${project.name}" project. ` : ". ",
7439
+ `Running tests in "${project.config.browser.name}" browser. `,
7440
+ "The \"browser.name\" field is deprecated since Vitest 3. ",
7441
+ "Read more: https://vitest.dev/guide/browser/config#browser-instances"
7442
+ ].filter(Boolean).join("")));
7443
+ const originalName = project.config.name, filteredInstances = vitest.matchesProjectFilter(originalName) ? instances : instances.filter((instance) => {
7750
7444
  const newName = instance.name;
7751
7445
  return vitest.matchesProjectFilter(newName);
7752
7446
  });
@@ -7759,8 +7453,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
7759
7453
  filteredInstances.forEach((config, index) => {
7760
7454
  const browser = config.browser;
7761
7455
  if (!browser) {
7762
- const nth = index + 1;
7763
- const ending = nth === 2 ? "nd" : nth === 3 ? "rd" : "th";
7456
+ const nth = index + 1, ending = nth === 2 ? "nd" : nth === 3 ? "rd" : "th";
7764
7457
  throw new Error(`The browser configuration must have a "browser" property. The ${nth}${ending} item in "browser.instances" doesn't have it. Make sure your${originalName ? ` "${originalName}"` : ""} configuration is correct.`);
7765
7458
  }
7766
7459
  const name = config.name;
@@ -7775,18 +7468,15 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
7775
7468
  clonedConfig.name = name;
7776
7469
  const clone = TestProject._cloneBrowserProject(project, clonedConfig);
7777
7470
  resolvedProjects.push(clone);
7778
- });
7779
- removeProjects.add(project);
7780
- });
7781
- resolvedProjects = resolvedProjects.filter((project) => !removeProjects.has(project));
7471
+ }), removeProjects.add(project);
7472
+ }), resolvedProjects = resolvedProjects.filter((project) => !removeProjects.has(project));
7782
7473
  const headedBrowserProjects = resolvedProjects.filter((project) => {
7783
7474
  return project.config.browser.enabled && !project.config.browser.headless;
7784
7475
  });
7785
7476
  if (headedBrowserProjects.length > 1) {
7786
7477
  const message = [`Found multiple projects that run browser tests in headed mode: "${headedBrowserProjects.map((p) => p.name).join("\", \"")}".`, ` Vitest cannot run multiple headed browsers at the same time.`].join("");
7787
7478
  if (!isTTY) throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
7788
- const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; });
7789
- const { projectName } = await prompts.default({
7479
+ const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; }), { projectName } = await prompts.default({
7790
7480
  type: "select",
7791
7481
  name: "projectName",
7792
7482
  choices: headedBrowserProjects.map((project) => ({
@@ -7801,10 +7491,9 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
7801
7491
  return resolvedProjects;
7802
7492
  }
7803
7493
  function cloneConfig(project, { browser,...config }) {
7804
- const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name,...overrideConfig } = config;
7805
- const currentConfig = project.config.browser;
7494
+ const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name,...overrideConfig } = config, currentConfig = project.config.browser, clonedConfig = deepClone(project.config);
7806
7495
  return mergeConfig({
7807
- ...deepClone(project.config),
7496
+ ...clonedConfig,
7808
7497
  browser: {
7809
7498
  ...project.config.browser,
7810
7499
  locators: locators ? { testIdAttribute: locators.testIdAttribute ?? currentConfig.locators.testIdAttribute } : project.config.browser.locators,
@@ -7816,18 +7505,15 @@ function cloneConfig(project, { browser,...config }) {
7816
7505
  name: browser,
7817
7506
  providerOptions: config,
7818
7507
  instances: void 0
7819
- }
7508
+ },
7509
+ include: overrideConfig.include && overrideConfig.include.length > 0 ? [] : clonedConfig.include,
7510
+ exclude: overrideConfig.exclude && overrideConfig.exclude.length > 0 ? [] : clonedConfig.exclude,
7511
+ includeSource: overrideConfig.includeSource && overrideConfig.includeSource.length > 0 ? [] : clonedConfig.includeSource
7820
7512
  }, overrideConfig);
7821
7513
  }
7822
7514
  async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition) {
7823
7515
  // project configurations that were specified directly
7824
- const projectsOptions = [];
7825
- // custom config files that were specified directly or resolved from a directory
7826
- const projectsConfigFiles = [];
7827
- // custom glob matches that should be resolved as directories or config files
7828
- const projectsGlobMatches = [];
7829
- // directories that don't have a config file inside, but should be treated as projects
7830
- const nonConfigProjectDirectories = [];
7516
+ const projectsOptions = [], projectsConfigFiles = [], projectsGlobMatches = [], nonConfigProjectDirectories = [];
7831
7517
  for (const definition of projectsDefinition) if (typeof definition === "string") {
7832
7518
  const stringOption = definition.replace("<rootDir>", vitest.config.root);
7833
7519
  // if the string doesn't contain a glob, we can resolve it directly
@@ -7871,8 +7557,7 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
7871
7557
  "**/*.timestamp-*",
7872
7558
  "**/.DS_Store"
7873
7559
  ]
7874
- };
7875
- const projectsFs = await glob(projectsGlobMatches, globOptions);
7560
+ }, projectsFs = await glob(projectsGlobMatches, globOptions);
7876
7561
  await Promise.all(projectsFs.map(async (path) => {
7877
7562
  // directories are allowed with a glob like `packages/*`
7878
7563
  // in this case every directory is treated as a project
@@ -7891,21 +7576,15 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
7891
7576
  };
7892
7577
  }
7893
7578
  async function resolveDirectoryConfig(directory) {
7894
- const files = new Set(await promises.readdir(directory));
7895
- // default resolution looks for vitest.config.* or vite.config.* files
7896
- // this simulates how `findUp` works in packages/vitest/src/node/create.ts:29
7897
- const configFile = configFiles.find((file) => files.has(file));
7898
- if (configFile) return resolve(directory, configFile);
7899
- return null;
7579
+ const files = new Set(await promises.readdir(directory)), configFile = configFiles.find((file) => files.has(file));
7580
+ return configFile ? resolve(directory, configFile) : null;
7900
7581
  }
7901
7582
  function getDefaultTestProject(vitest) {
7902
- const filter = vitest.config.project;
7903
- const project = vitest._ensureRootProject();
7583
+ const filter = vitest.config.project, project = vitest._ensureRootProject();
7904
7584
  if (!filter.length) return project;
7905
7585
  // check for the project name and browser names
7906
7586
  const hasProjects = getPotentialProjectNames(project).some((p) => vitest.matchesProjectFilter(p));
7907
- if (hasProjects) return project;
7908
- return null;
7587
+ return hasProjects ? project : null;
7909
7588
  }
7910
7589
  function getPotentialProjectNames(project) {
7911
7590
  const names = [project.name];
@@ -7925,8 +7604,7 @@ async function loadCustomReporterModule(path, runner) {
7925
7604
  return customReporterModule.default;
7926
7605
  }
7927
7606
  function createReporters(reporterReferences, ctx) {
7928
- const runner = ctx.runner;
7929
- const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
7607
+ const runner = ctx.runner, promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
7930
7608
  if (Array.isArray(referenceOrInstance)) {
7931
7609
  const [reporterName, reporterOptions] = referenceOrInstance;
7932
7610
  if (reporterName === "html") {
@@ -7967,14 +7645,12 @@ function parseFilter(filter) {
7967
7645
  filename: parsedFilename,
7968
7646
  lineNumber: Number.parseInt(lineNumber)
7969
7647
  };
7970
- else if (lineNumber.match(/^\d+-\d+$/)) throw new RangeLocationFilterProvidedError(filter);
7971
- else return { filename: filter };
7648
+ if (lineNumber.match(/^\d+-\d+$/)) throw new RangeLocationFilterProvidedError(filter);
7649
+ return { filename: filter };
7972
7650
  }
7973
7651
  function groupFilters(filters) {
7974
- const groupedFilters_ = groupBy(filters, (f) => f.filename);
7975
- const groupedFilters = Object.fromEntries(Object.entries(groupedFilters_).map((entry) => {
7976
- const [filename, filters] = entry;
7977
- const testLocations = filters.map((f) => f.lineNumber);
7652
+ const groupedFilters_ = groupBy(filters, (f) => f.filename), groupedFilters = Object.fromEntries(Object.entries(groupedFilters_).map((entry) => {
7653
+ const [filename, filters] = entry, testLocations = filters.map((f) => f.lineNumber);
7978
7654
  return [filename, testLocations.filter((l) => l !== void 0)];
7979
7655
  }));
7980
7656
  return groupedFilters;
@@ -7993,45 +7669,35 @@ class VitestSpecifications {
7993
7669
  if (project._isCachedTestFile(moduleId)) specs.push(project.createSpecification(moduleId));
7994
7670
  if (project._isCachedTypecheckFile(moduleId)) specs.push(project.createSpecification(moduleId, [], "typescript"));
7995
7671
  }
7996
- specs.forEach((spec) => this.ensureSpecificationCached(spec));
7997
- return specs;
7672
+ return specs.forEach((spec) => this.ensureSpecificationCached(spec)), specs;
7998
7673
  }
7999
7674
  async getRelevantTestSpecifications(filters = []) {
8000
7675
  return this.filterTestsBySource(await this.globTestSpecifications(filters));
8001
7676
  }
8002
7677
  async globTestSpecifications(filters = []) {
8003
- const files = [];
8004
- const dir = process.cwd();
8005
- const parsedFilters = filters.map((f) => parseFilter(f));
7678
+ const files = [], dir = process.cwd(), parsedFilters = filters.map((f) => parseFilter(f));
8006
7679
  // Require includeTaskLocation when a location filter is passed
8007
7680
  if (!this.vitest.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) throw new IncludeTaskLocationDisabledError();
8008
7681
  const testLines = groupFilters(parsedFilters.map((f) => ({
8009
7682
  ...f,
8010
7683
  filename: resolve(dir, f.filename)
8011
- })));
8012
- // Key is file and val specifies whether we have matched this file with testLocation
8013
- const testLocHasMatch = {};
8014
- await Promise.all(this.vitest.projects.map(async (project) => {
7684
+ }))), testLocHasMatch = {};
7685
+ return await Promise.all(this.vitest.projects.map(async (project) => {
8015
7686
  const { testFiles, typecheckTestFiles } = await project.globTestFiles(parsedFilters.map((f) => f.filename));
8016
7687
  testFiles.forEach((file) => {
8017
7688
  const lines = testLines[file];
8018
7689
  testLocHasMatch[file] = true;
8019
7690
  const spec = project.createSpecification(file, lines);
8020
- this.ensureSpecificationCached(spec);
8021
- files.push(spec);
8022
- });
8023
- typecheckTestFiles.forEach((file) => {
7691
+ this.ensureSpecificationCached(spec), files.push(spec);
7692
+ }), typecheckTestFiles.forEach((file) => {
8024
7693
  const lines = testLines[file];
8025
7694
  testLocHasMatch[file] = true;
8026
7695
  const spec = project.createSpecification(file, lines, "typescript");
8027
- this.ensureSpecificationCached(spec);
8028
- files.push(spec);
7696
+ this.ensureSpecificationCached(spec), files.push(spec);
8029
7697
  });
8030
- }));
8031
- Object.entries(testLines).forEach(([filepath, loc]) => {
7698
+ })), Object.entries(testLines).forEach(([filepath, loc]) => {
8032
7699
  if (loc.length !== 0 && !testLocHasMatch[filepath]) throw new LocationFilterFileNotFoundError(relative(dir, filepath));
8033
- });
8034
- return files;
7700
+ }), files;
8035
7701
  }
8036
7702
  clearCache(moduleId) {
8037
7703
  if (moduleId) this._cachedSpecs.delete(moduleId);
@@ -8041,30 +7707,20 @@ class VitestSpecifications {
8041
7707
  return this._cachedSpecs.get(moduleId);
8042
7708
  }
8043
7709
  ensureSpecificationCached(spec) {
8044
- const file = spec.moduleId;
8045
- const specs = this._cachedSpecs.get(file) || [];
8046
- const index = specs.findIndex((_s) => _s.project === spec.project && _s.pool === spec.pool);
8047
- if (index === -1) {
8048
- specs.push(spec);
8049
- this._cachedSpecs.set(file, specs);
8050
- } else specs.splice(index, 1, spec);
7710
+ const file = spec.moduleId, specs = this._cachedSpecs.get(file) || [], index = specs.findIndex((_s) => _s.project === spec.project && _s.pool === spec.pool);
7711
+ if (index === -1) specs.push(spec), this._cachedSpecs.set(file, specs);
7712
+ else specs.splice(index, 1, spec);
8051
7713
  return specs;
8052
7714
  }
8053
7715
  async filterTestsBySource(specs) {
8054
7716
  if (this.vitest.config.changed && !this.vitest.config.related) {
8055
- const { VitestGit } = await import('./git.BVQ8w_Sw.js');
8056
- const vitestGit = new VitestGit(this.vitest.config.root);
8057
- const related = await vitestGit.findChangedFiles({ changedSince: this.vitest.config.changed });
8058
- if (!related) {
8059
- process.exitCode = 1;
8060
- throw new GitNotFoundError();
8061
- }
7717
+ const { VitestGit } = await import('./git.BFNcloKD.js'), vitestGit = new VitestGit(this.vitest.config.root), related = await vitestGit.findChangedFiles({ changedSince: this.vitest.config.changed });
7718
+ if (!related) throw process.exitCode = 1, new GitNotFoundError();
8062
7719
  this.vitest.config.related = Array.from(new Set(related));
8063
7720
  }
8064
7721
  const related = this.vitest.config.related;
8065
7722
  if (!related) return specs;
8066
- const forceRerunTriggers = this.vitest.config.forceRerunTriggers;
8067
- const matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) : void 0;
7723
+ const forceRerunTriggers = this.vitest.config.forceRerunTriggers, matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) : void 0;
8068
7724
  if (matcher && related.some((file) => matcher(file))) return specs;
8069
7725
  // don't run anything if no related sources are found
8070
7726
  // if we are in watch mode, we want to process all tests
@@ -8072,8 +7728,7 @@ class VitestSpecifications {
8072
7728
  const testGraphs = await Promise.all(specs.map(async (spec) => {
8073
7729
  const deps = await this.getTestDependencies(spec);
8074
7730
  return [spec, deps];
8075
- }));
8076
- const runningTests = [];
7731
+ })), runningTests = [];
8077
7732
  for (const [specification, deps] of testGraphs)
8078
7733
  // if deps or the test itself were changed
8079
7734
  if (related.some((path) => path === specification.moduleId || deps.has(path))) runningTests.push(specification);
@@ -8083,8 +7738,7 @@ class VitestSpecifications {
8083
7738
  const addImports = async (project, filepath) => {
8084
7739
  if (deps.has(filepath)) return;
8085
7740
  deps.add(filepath);
8086
- const mod = project.vite.environments.ssr.moduleGraph.getModuleById(filepath);
8087
- const transformed = mod?.transformResult || await project.vite.environments.ssr.transformRequest(filepath);
7741
+ const mod = project.vite.environments.ssr.moduleGraph.getModuleById(filepath), transformed = mod?.transformResult || await project.vite.environments.ssr.transformRequest(filepath);
8088
7742
  if (!transformed) return;
8089
7743
  const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
8090
7744
  await Promise.all(dependencies.map(async (dep) => {
@@ -8092,9 +7746,7 @@ class VitestSpecifications {
8092
7746
  if (!fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) await addImports(project, fsPath);
8093
7747
  }));
8094
7748
  };
8095
- await addImports(spec.project, spec.moduleId);
8096
- deps.delete(spec.moduleId);
8097
- return deps;
7749
+ return await addImports(spec.project, spec.moduleId), deps.delete(spec.moduleId), deps;
8098
7750
  }
8099
7751
  }
8100
7752
 
@@ -8120,10 +7772,7 @@ class ReportedTaskImplementation {
8120
7772
  location;
8121
7773
  /** @internal */
8122
7774
  constructor(task, project) {
8123
- this.task = task;
8124
- this.project = project;
8125
- this.id = task.id;
8126
- this.location = task.location;
7775
+ this.task = task, this.project = project, this.id = task.id, this.location = task.location;
8127
7776
  }
8128
7777
  /**
8129
7778
  * Checks if the test did not fail the suite.
@@ -8145,8 +7794,7 @@ class ReportedTaskImplementation {
8145
7794
  */
8146
7795
  static register(task, project) {
8147
7796
  const state = new this(task, project);
8148
- storeTask(project, task, state);
8149
- return state;
7797
+ return storeTask(project, task, state), state;
8150
7798
  }
8151
7799
  }
8152
7800
  class TestCase extends ReportedTaskImplementation {
@@ -8170,9 +7818,7 @@ class TestCase extends ReportedTaskImplementation {
8170
7818
  parent;
8171
7819
  /** @internal */
8172
7820
  constructor(task, project) {
8173
- super(task, project);
8174
- this.name = task.name;
8175
- this.module = getReportedTask(project, task.file);
7821
+ super(task, project), this.name = task.name, this.module = getReportedTask(project, task.file);
8176
7822
  const suite = this.task.suite;
8177
7823
  if (suite) this.parent = getReportedTask(project, suite);
8178
7824
  else this.parent = this.module;
@@ -8194,8 +7840,7 @@ class TestCase extends ReportedTaskImplementation {
8194
7840
  * - **skipped**: Test was skipped during collection or dynamically with `ctx.skip()`.
8195
7841
  */
8196
7842
  result() {
8197
- const result = this.task.result;
8198
- const mode = result?.state || this.task.mode;
7843
+ const result = this.task.result, mode = result?.state || this.task.mode;
8199
7844
  if (!result && (mode === "skip" || mode === "todo")) return {
8200
7845
  state: "skipped",
8201
7846
  note: void 0,
@@ -8206,16 +7851,14 @@ class TestCase extends ReportedTaskImplementation {
8206
7851
  errors: void 0
8207
7852
  };
8208
7853
  const state = result.state === "fail" ? "failed" : result.state === "pass" ? "passed" : "skipped";
8209
- if (state === "skipped") return {
7854
+ return state === "skipped" ? {
8210
7855
  state,
8211
7856
  note: result.note,
8212
7857
  errors: void 0
8213
- };
8214
- if (state === "passed") return {
7858
+ } : state === "passed" ? {
8215
7859
  state,
8216
7860
  errors: result.errors
8217
- };
8218
- return {
7861
+ } : {
8219
7862
  state,
8220
7863
  errors: result.errors || []
8221
7864
  };
@@ -8234,8 +7877,7 @@ class TestCase extends ReportedTaskImplementation {
8234
7877
  const result = this.task.result;
8235
7878
  // startTime should always be available if the test has properly finished
8236
7879
  if (!result || !result.startTime) return void 0;
8237
- const duration = result.duration || 0;
8238
- const slow = duration > this.project.globalConfig.slowTestThreshold;
7880
+ const duration = result.duration || 0, slow = duration > this.project.globalConfig.slowTestThreshold;
8239
7881
  return {
8240
7882
  slow,
8241
7883
  heap: result.heap,
@@ -8251,8 +7893,7 @@ class TestCollection {
8251
7893
  #task;
8252
7894
  #project;
8253
7895
  constructor(task, project) {
8254
- this.#task = task;
8255
- this.#project = project;
7896
+ this.#task = task, this.#project = project;
8256
7897
  }
8257
7898
  /**
8258
7899
  * Returns the test or suite at a specific index.
@@ -8305,10 +7946,7 @@ class TestCollection {
8305
7946
  * Filters all suites that are part of this collection and its children.
8306
7947
  */
8307
7948
  *allSuites() {
8308
- for (const child of this) if (child.type === "suite") {
8309
- yield child;
8310
- yield* child.children.allSuites();
8311
- }
7949
+ for (const child of this) if (child.type === "suite") yield child, yield* child.children.allSuites();
8312
7950
  }
8313
7951
  *[Symbol.iterator]() {
8314
7952
  for (const task of this.#task.tasks) yield getReportedTask(this.#project, task);
@@ -8321,8 +7959,7 @@ class SuiteImplementation extends ReportedTaskImplementation {
8321
7959
  children;
8322
7960
  /** @internal */
8323
7961
  constructor(task, project) {
8324
- super(task, project);
8325
- this.children = new TestCollection(task, project);
7962
+ super(task, project), this.children = new TestCollection(task, project);
8326
7963
  }
8327
7964
  /**
8328
7965
  * Errors that happened outside of the test run during collection, like syntax errors.
@@ -8352,9 +7989,7 @@ class TestSuite extends SuiteImplementation {
8352
7989
  options;
8353
7990
  /** @internal */
8354
7991
  constructor(task, project) {
8355
- super(task, project);
8356
- this.name = task.name;
8357
- this.module = getReportedTask(project, task.file);
7992
+ super(task, project), this.name = task.name, this.module = getReportedTask(project, task.file);
8358
7993
  const suite = this.task.suite;
8359
7994
  if (suite) this.parent = getReportedTask(project, suite);
8360
7995
  else this.parent = this.module;
@@ -8385,29 +8020,21 @@ class TestModule extends SuiteImplementation {
8385
8020
  moduleId;
8386
8021
  /** @internal */
8387
8022
  constructor(task, project) {
8388
- super(task, project);
8389
- this.moduleId = task.filepath;
8023
+ super(task, project), this.moduleId = task.filepath;
8390
8024
  }
8391
8025
  /**
8392
8026
  * Checks the running state of the test file.
8393
8027
  */
8394
8028
  state() {
8395
8029
  const state = this.task.result?.state;
8396
- if (state === "queued") return "queued";
8397
- return getSuiteState(this.task);
8030
+ return state === "queued" ? "queued" : getSuiteState(this.task);
8398
8031
  }
8399
8032
  /**
8400
8033
  * Useful information about the module like duration, memory usage, etc.
8401
8034
  * If the module was not executed yet, all diagnostic values will return `0`.
8402
8035
  */
8403
8036
  diagnostic() {
8404
- const setupDuration = this.task.setupDuration || 0;
8405
- const collectDuration = this.task.collectDuration || 0;
8406
- const prepareDuration = this.task.prepareDuration || 0;
8407
- const environmentSetupDuration = this.task.environmentLoad || 0;
8408
- const duration = this.task.result?.duration || 0;
8409
- const heap = this.task.result?.heap;
8410
- const importDurations = this.task.importDurations ?? {};
8037
+ const setupDuration = this.task.setupDuration || 0, collectDuration = this.task.collectDuration || 0, prepareDuration = this.task.prepareDuration || 0, environmentSetupDuration = this.task.environmentLoad || 0, duration = this.task.result?.duration || 0, heap = this.task.result?.heap, importDurations = this.task.importDurations ?? {};
8411
8038
  return {
8412
8039
  environmentSetupDuration,
8413
8040
  prepareDuration,
@@ -8439,8 +8066,7 @@ function getReportedTask(project, runnerTask) {
8439
8066
  return reportedTask;
8440
8067
  }
8441
8068
  function getSuiteState(task) {
8442
- const mode = task.mode;
8443
- const state = task.result?.state;
8069
+ const mode = task.mode, state = task.result?.state;
8444
8070
  if (mode === "skip" || mode === "todo" || state === "skip" || state === "todo") return "skipped";
8445
8071
  if (state == null || state === "run" || state === "only") return "pending";
8446
8072
  if (state === "fail") return "failed";
@@ -8449,8 +8075,7 @@ function getSuiteState(task) {
8449
8075
  }
8450
8076
 
8451
8077
  function isAggregateError(err) {
8452
- if (typeof AggregateError !== "undefined" && err instanceof AggregateError) return true;
8453
- return err instanceof Error && "errors" in err;
8078
+ return typeof AggregateError !== "undefined" && err instanceof AggregateError ? true : err instanceof Error && "errors" in err;
8454
8079
  }
8455
8080
  class StateManager {
8456
8081
  filesMap = /* @__PURE__ */ new Map();
@@ -8481,12 +8106,7 @@ class StateManager {
8481
8106
  const _error = error;
8482
8107
  if (_error && typeof _error === "object" && _error.code === "VITEST_PENDING") {
8483
8108
  const task = this.idMap.get(_error.taskId);
8484
- if (task) {
8485
- task.mode = "skip";
8486
- task.result ??= { state: "skip" };
8487
- task.result.state = "skip";
8488
- task.result.note = _error.note;
8489
- }
8109
+ if (task) task.mode = "skip", task.result ??= { state: "skip" }, task.result.state = "skip", task.result.note = _error.note;
8490
8110
  return;
8491
8111
  }
8492
8112
  if (!this.onUnhandledError || this.onUnhandledError(error) !== false) this.errorsSet.add(error);
@@ -8510,12 +8130,8 @@ class StateManager {
8510
8130
  * Return files that were running or collected.
8511
8131
  */
8512
8132
  getFiles(keys) {
8513
- if (keys) return keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local);
8514
- return Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
8515
- // print typecheck files first
8516
- if (f1.meta?.typecheck && f2.meta?.typecheck) return 0;
8517
- if (f1.meta?.typecheck) return -1;
8518
- return 1;
8133
+ return keys ? keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local) : Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
8134
+ return f1.meta?.typecheck && f2.meta?.typecheck ? 0 : f1.meta?.typecheck ? -1 : 1;
8519
8135
  });
8520
8136
  }
8521
8137
  getTestModules(keys) {
@@ -8534,25 +8150,17 @@ class StateManager {
8534
8150
  }
8535
8151
  collectFiles(project, files = []) {
8536
8152
  files.forEach((file) => {
8537
- const existing = this.filesMap.get(file.filepath) || [];
8538
- const otherFiles = existing.filter((i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck);
8539
- const currentFile = existing.find((i) => i.projectName === file.projectName);
8153
+ const existing = this.filesMap.get(file.filepath) || [], otherFiles = existing.filter((i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck), currentFile = existing.find((i) => i.projectName === file.projectName);
8540
8154
  // keep logs for the previous file because it should always be initiated before the collections phase
8541
8155
  // which means that all logs are collected during the collection and not inside tests
8542
8156
  if (currentFile) file.logs = currentFile.logs;
8543
- otherFiles.push(file);
8544
- this.filesMap.set(file.filepath, otherFiles);
8545
- this.updateId(file, project);
8157
+ otherFiles.push(file), this.filesMap.set(file.filepath, otherFiles), this.updateId(file, project);
8546
8158
  });
8547
8159
  }
8548
8160
  clearFiles(project, paths = []) {
8549
8161
  paths.forEach((path) => {
8550
- const files = this.filesMap.get(path);
8551
- const fileTask = createFileTask(path, project.config.root, project.config.name);
8552
- fileTask.local = true;
8553
- TestModule.register(fileTask, project);
8554
- this.idMap.set(fileTask.id, fileTask);
8555
- if (!files) {
8162
+ const files = this.filesMap.get(path), fileTask = createFileTask(path, project.config.root, project.config.name);
8163
+ if (fileTask.local = true, TestModule.register(fileTask, project), this.idMap.set(fileTask.id, fileTask), !files) {
8556
8164
  this.filesMap.set(path, [fileTask]);
8557
8165
  return;
8558
8166
  }
@@ -8563,14 +8171,14 @@ class StateManager {
8563
8171
  });
8564
8172
  }
8565
8173
  updateId(task, project) {
8566
- if (this.idMap.get(task.id) === task) return;
8567
- if (task.type === "suite" && "filepath" in task) TestModule.register(task, project);
8568
- else if (task.type === "suite") TestSuite.register(task, project);
8569
- else TestCase.register(task, project);
8570
- this.idMap.set(task.id, task);
8571
- if (task.type === "suite") task.tasks.forEach((task) => {
8572
- this.updateId(task, project);
8573
- });
8174
+ if (this.idMap.get(task.id) !== task) {
8175
+ if (task.type === "suite" && "filepath" in task) TestModule.register(task, project);
8176
+ else if (task.type === "suite") TestSuite.register(task, project);
8177
+ else TestCase.register(task, project);
8178
+ if (this.idMap.set(task.id, task), task.type === "suite") task.tasks.forEach((task) => {
8179
+ this.updateId(task, project);
8180
+ });
8181
+ }
8574
8182
  }
8575
8183
  getReportedEntity(task) {
8576
8184
  return this.reportedTasksMap.get(task);
@@ -8579,10 +8187,8 @@ class StateManager {
8579
8187
  for (const [id, result, meta] of packs) {
8580
8188
  const task = this.idMap.get(id);
8581
8189
  if (task) {
8582
- task.result = result;
8583
- task.meta = meta;
8584
8190
  // skipped with new PendingError
8585
- if (result?.state === "skip") task.mode = "skip";
8191
+ if (task.result = result, task.meta = meta, result?.state === "skip") task.mode = "skip";
8586
8192
  }
8587
8193
  }
8588
8194
  }
@@ -9059,10 +8665,7 @@ class TestRun {
9059
8665
  }
9060
8666
  async start(specifications) {
9061
8667
  const filepaths = specifications.map((spec) => spec.moduleId);
9062
- this.vitest.state.collectPaths(filepaths);
9063
- await this.vitest.report("onPathsCollected", Array.from(new Set(filepaths)));
9064
- await this.vitest.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
9065
- await this.vitest.report("onTestRunStart", [...specifications]);
8668
+ this.vitest.state.collectPaths(filepaths), await this.vitest.report("onTestRunStart", [...specifications]);
9066
8669
  }
9067
8670
  async enqueued(project, file) {
9068
8671
  this.vitest.state.collectFiles(project, [file]);
@@ -9070,25 +8673,17 @@ class TestRun {
9070
8673
  await this.vitest.report("onTestModuleQueued", testModule);
9071
8674
  }
9072
8675
  async collected(project, files) {
9073
- this.vitest.state.collectFiles(project, files);
9074
- await Promise.all([this.vitest.report("onCollected", files), ...files.map((file) => {
8676
+ this.vitest.state.collectFiles(project, files), await Promise.all(files.map((file) => {
9075
8677
  const testModule = this.vitest.state.getReportedEntity(file);
9076
8678
  return this.vitest.report("onTestModuleCollected", testModule);
9077
- })]);
8679
+ }));
9078
8680
  }
9079
8681
  async log(log) {
9080
- this.vitest.state.updateUserLog(log);
9081
- await this.vitest.report("onUserConsoleLog", log);
8682
+ this.vitest.state.updateUserLog(log), await this.vitest.report("onUserConsoleLog", log);
9082
8683
  }
9083
8684
  async annotate(testId, annotation) {
9084
- const task = this.vitest.state.idMap.get(testId);
9085
- const entity = task && this.vitest.state.getReportedEntity(task);
9086
- assert$1(task && entity, `Entity must be found for task ${task?.name || testId}`);
9087
- assert$1(entity.type === "test", `Annotation can only be added to a test, instead got ${entity.type}`);
9088
- await this.resolveTestAttachment(entity, annotation);
9089
- entity.task.annotations.push(annotation);
9090
- await this.vitest.report("onTestCaseAnnotate", entity, annotation);
9091
- return annotation;
8685
+ const task = this.vitest.state.idMap.get(testId), entity = task && this.vitest.state.getReportedEntity(task);
8686
+ return assert$1(task && entity, `Entity must be found for task ${task?.name || testId}`), assert$1(entity.type === "test", `Annotation can only be added to a test, instead got ${entity.type}`), await this.resolveTestAttachment(entity, annotation), entity.task.annotations.push(annotation), await this.vitest.report("onTestCaseAnnotate", entity, annotation), annotation;
9092
8687
  }
9093
8688
  async updated(update, events) {
9094
8689
  this.vitest.state.updateTasks(update);
@@ -9101,30 +8696,21 @@ class TestRun {
9101
8696
  await this.vitest.report("onTaskUpdate", update, events);
9102
8697
  }
9103
8698
  async end(specifications, errors, coverage) {
8699
+ if (coverage) await this.vitest.report("onCoverage", coverage);
9104
8700
  // specification won't have the File task if they were filtered by the --shard command
9105
- const modules = specifications.map((spec) => spec.testModule).filter((s) => s != null);
9106
- const files = modules.map((m) => m.task);
9107
- const state = this.vitest.isCancelling ? "interrupted" : this.hasFailed(modules) ? "failed" : "passed";
8701
+ const modules = specifications.map((spec) => spec.testModule).filter((s) => s != null), state = this.vitest.isCancelling ? "interrupted" : this.hasFailed(modules) ? "failed" : "passed";
9108
8702
  if (state !== "passed") process.exitCode = 1;
9109
- try {
9110
- await Promise.all([this.vitest.report("onTestRunEnd", modules, [...errors], state), this.vitest.report("onFinished", files, errors, coverage)]);
9111
- } finally {
9112
- if (coverage) await this.vitest.report("onCoverage", coverage);
9113
- }
8703
+ this.vitest.report("onTestRunEnd", modules, [...errors], state);
9114
8704
  }
9115
8705
  hasFailed(modules) {
9116
- if (!modules.length) return !this.vitest.config.passWithNoTests;
9117
- return modules.some((m) => !m.ok());
8706
+ return modules.length ? modules.some((m) => !m.ok()) : !this.vitest.config.passWithNoTests;
9118
8707
  }
9119
8708
  async reportEvent(id, event, data) {
9120
- const task = this.vitest.state.idMap.get(id);
9121
- const entity = task && this.vitest.state.getReportedEntity(task);
9122
- assert$1(task && entity, `Entity must be found for task ${task?.name || id}`);
9123
- if (event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
8709
+ const task = this.vitest.state.idMap.get(id), entity = task && this.vitest.state.getReportedEntity(task);
8710
+ if (assert$1(task && entity, `Entity must be found for task ${task?.name || id}`), event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
9124
8711
  if (event === "suite-prepare" && entity.type === "module") return await this.vitest.report("onTestModuleStart", entity);
9125
8712
  if (event === "suite-finished") {
9126
- assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module");
9127
- if (entity.state() === "skipped")
8713
+ if (assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module"), entity.state() === "skipped")
9128
8714
  // everything inside suite or a module is skipped,
9129
8715
  // so we won't get any children events
9130
8716
  // we need to report everything manually
@@ -9136,8 +8722,7 @@ class TestRun {
9136
8722
  if (event === "test-prepare" && entity.type === "test") return await this.vitest.report("onTestCaseReady", entity);
9137
8723
  if (event === "test-finished" && entity.type === "test") return await this.vitest.report("onTestCaseResult", entity);
9138
8724
  if (event.startsWith("before-hook") || event.startsWith("after-hook")) {
9139
- const isBefore = event.startsWith("before-hook");
9140
- const hook = entity.type === "test" ? {
8725
+ const isBefore = event.startsWith("before-hook"), hook = entity.type === "test" ? {
9141
8726
  name: isBefore ? "beforeEach" : "afterEach",
9142
8727
  entity
9143
8728
  } : {
@@ -9149,37 +8734,25 @@ class TestRun {
9149
8734
  // this can only happen in --merge-reports, and annotation is already resolved
9150
8735
  if (event === "test-annotation") {
9151
8736
  const annotation = data?.annotation;
9152
- assert$1(annotation && entity.type === "test");
9153
- await this.vitest.report("onTestCaseAnnotate", entity, annotation);
8737
+ assert$1(annotation && entity.type === "test"), await this.vitest.report("onTestCaseAnnotate", entity, annotation);
9154
8738
  }
9155
8739
  }
9156
8740
  }
9157
8741
  async resolveTestAttachment(test, annotation) {
9158
- const project = test.project;
9159
- const attachment = annotation.attachment;
8742
+ const project = test.project, attachment = annotation.attachment;
9160
8743
  if (!attachment) return attachment;
9161
8744
  const path = attachment.path;
9162
8745
  if (path && !path.startsWith("http://") && !path.startsWith("https://")) {
9163
- const currentPath = resolve(project.config.root, path);
9164
- const hash = createHash("sha1").update(currentPath).digest("hex");
9165
- const newPath = resolve(project.config.attachmentsDir, `${sanitizeFilePath(annotation.message)}-${hash}${extname(currentPath)}`);
9166
- await mkdir(dirname(newPath), { recursive: true });
9167
- await copyFile(currentPath, newPath);
9168
- attachment.path = newPath;
8746
+ const currentPath = resolve(project.config.root, path), hash = createHash("sha1").update(currentPath).digest("hex"), newPath = resolve(project.config.attachmentsDir, `${sanitizeFilePath(annotation.message)}-${hash}${extname(currentPath)}`);
8747
+ await mkdir(dirname(newPath), { recursive: true }), await copyFile(currentPath, newPath), attachment.path = newPath;
9169
8748
  const contentType = attachment.contentType ?? mime.getType(basename(currentPath));
9170
8749
  attachment.contentType = contentType || void 0;
9171
8750
  }
9172
8751
  return attachment;
9173
8752
  }
9174
8753
  async reportChildren(children) {
9175
- for (const child of children) if (child.type === "test") {
9176
- await this.vitest.report("onTestCaseReady", child);
9177
- await this.vitest.report("onTestCaseResult", child);
9178
- } else {
9179
- await this.vitest.report("onTestSuiteReady", child);
9180
- await this.reportChildren(child.children);
9181
- await this.vitest.report("onTestSuiteResult", child);
9182
- }
8754
+ for (const child of children) if (child.type === "test") await this.vitest.report("onTestCaseReady", child), await this.vitest.report("onTestCaseResult", child);
8755
+ else await this.vitest.report("onTestSuiteReady", child), await this.reportChildren(child.children), await this.vitest.report("onTestSuiteResult", child);
9183
8756
  }
9184
8757
  }
9185
8758
  function sanitizeFilePath(s) {
@@ -9207,23 +8780,15 @@ class VitestWatcher {
9207
8780
  * @internal
9208
8781
  */
9209
8782
  onWatcherRerun(cb) {
9210
- this._onRerun.push(cb);
9211
- return this;
8783
+ return this._onRerun.push(cb), this;
9212
8784
  }
9213
8785
  unregisterWatcher = noop;
9214
8786
  registerWatcher() {
9215
8787
  const watcher = this.vitest.vite.watcher;
9216
8788
  if (this.vitest.config.forceRerunTriggers.length) watcher.add(this.vitest.config.forceRerunTriggers);
9217
- watcher.on("change", this.onChange);
9218
- watcher.on("unlink", this.onUnlink);
9219
- watcher.on("add", this.onAdd);
9220
- this.unregisterWatcher = () => {
9221
- watcher.off("change", this.onChange);
9222
- watcher.off("unlink", this.onUnlink);
9223
- watcher.off("add", this.onAdd);
9224
- this.unregisterWatcher = noop;
9225
- };
9226
- return this;
8789
+ return watcher.on("change", this.onChange), watcher.on("unlink", this.onUnlink), watcher.on("add", this.onAdd), this.unregisterWatcher = () => {
8790
+ watcher.off("change", this.onChange), watcher.off("unlink", this.onUnlink), watcher.off("add", this.onAdd), this.unregisterWatcher = noop;
8791
+ }, this;
9227
8792
  }
9228
8793
  scheduleRerun(file) {
9229
8794
  this._onRerun.forEach((cb) => cb(file));
@@ -9231,25 +8796,17 @@ class VitestWatcher {
9231
8796
  getTestFilesFromWatcherTrigger(id) {
9232
8797
  if (!this.vitest.config.watchTriggerPatterns) return false;
9233
8798
  let triggered = false;
9234
- this.vitest.config.watchTriggerPatterns.forEach((definition) => {
8799
+ return this.vitest.config.watchTriggerPatterns.forEach((definition) => {
9235
8800
  const exec = definition.pattern.exec(id);
9236
8801
  if (exec) {
9237
8802
  const files = definition.testsToRun(id, exec);
9238
- if (Array.isArray(files)) {
9239
- triggered = true;
9240
- files.forEach((file) => this.changedTests.add(resolve(this.vitest.config.root, file)));
9241
- } else if (typeof files === "string") {
9242
- triggered = true;
9243
- this.changedTests.add(resolve(this.vitest.config.root, files));
9244
- }
8803
+ if (Array.isArray(files)) triggered = true, files.forEach((file) => this.changedTests.add(resolve(this.vitest.config.root, file)));
8804
+ else if (typeof files === "string") triggered = true, this.changedTests.add(resolve(this.vitest.config.root, files));
9245
8805
  }
9246
- });
9247
- return triggered;
8806
+ }), triggered;
9248
8807
  }
9249
8808
  onChange = (id) => {
9250
- id = slash(id);
9251
- this.vitest.logger.clearHighlightCache(id);
9252
- this.vitest.invalidateFile(id);
8809
+ id = slash(id), this.vitest.logger.clearHighlightCache(id), this.vitest.invalidateFile(id);
9253
8810
  const testFiles = this.getTestFilesFromWatcherTrigger(id);
9254
8811
  if (testFiles) this.scheduleRerun(id);
9255
8812
  else {
@@ -9258,21 +8815,10 @@ class VitestWatcher {
9258
8815
  }
9259
8816
  };
9260
8817
  onUnlink = (id) => {
9261
- id = slash(id);
9262
- this.vitest.logger.clearHighlightCache(id);
9263
- this.invalidates.add(id);
9264
- if (this.vitest.state.filesMap.has(id)) {
9265
- this.vitest.projects.forEach((project) => project._removeCachedTestFile(id));
9266
- this.vitest.state.filesMap.delete(id);
9267
- this.vitest.cache.results.removeFromCache(id);
9268
- this.vitest.cache.stats.removeStats(id);
9269
- this.changedTests.delete(id);
9270
- this.vitest.report("onTestRemoved", id);
9271
- }
8818
+ if (id = slash(id), this.vitest.logger.clearHighlightCache(id), this.invalidates.add(id), this.vitest.state.filesMap.has(id)) this.vitest.projects.forEach((project) => project._removeCachedTestFile(id)), this.vitest.state.filesMap.delete(id), this.vitest.cache.results.removeFromCache(id), this.vitest.cache.stats.removeStats(id), this.changedTests.delete(id), this.vitest.report("onTestRemoved", id);
9272
8819
  };
9273
8820
  onAdd = (id) => {
9274
- id = slash(id);
9275
- this.vitest.invalidateFile(id);
8821
+ id = slash(id), this.vitest.invalidateFile(id);
9276
8822
  const testFiles = this.getTestFilesFromWatcherTrigger(id);
9277
8823
  if (testFiles) {
9278
8824
  this.scheduleRerun(id);
@@ -9280,13 +8826,10 @@ class VitestWatcher {
9280
8826
  }
9281
8827
  let fileContent;
9282
8828
  const matchingProjects = [];
9283
- this.vitest.projects.forEach((project) => {
8829
+ if (this.vitest.projects.forEach((project) => {
9284
8830
  if (project.matchesTestGlob(id, () => fileContent ??= readFileSync(id, "utf-8"))) matchingProjects.push(project);
9285
- });
9286
- if (matchingProjects.length > 0) {
9287
- this.changedTests.add(id);
9288
- this.scheduleRerun(id);
9289
- } else {
8831
+ }), matchingProjects.length > 0) this.changedTests.add(id), this.scheduleRerun(id);
8832
+ else {
9290
8833
  // it's possible that file was already there but watcher triggered "add" event instead
9291
8834
  const needsRerun = this.handleFileChanged(id);
9292
8835
  if (needsRerun) this.scheduleRerun(id);
@@ -9294,51 +8837,33 @@ class VitestWatcher {
9294
8837
  };
9295
8838
  handleSetupFile(filepath) {
9296
8839
  let isSetupFile = false;
9297
- this.vitest.projects.forEach((project) => {
9298
- if (!project.config.setupFiles.includes(filepath)) return;
9299
- this.vitest.state.filesMap.forEach((files) => {
8840
+ return this.vitest.projects.forEach((project) => {
8841
+ project.config.setupFiles.includes(filepath) && this.vitest.state.filesMap.forEach((files) => {
9300
8842
  files.forEach((file) => {
9301
- if (file.projectName === project.name) {
9302
- isSetupFile = true;
9303
- this.changedTests.add(file.filepath);
9304
- }
8843
+ if (file.projectName === project.name) isSetupFile = true, this.changedTests.add(file.filepath);
9305
8844
  });
9306
8845
  });
9307
- });
9308
- return isSetupFile;
8846
+ }), isSetupFile;
9309
8847
  }
9310
8848
  /**
9311
8849
  * @returns A value indicating whether rerun is needed (changedTests was mutated)
9312
8850
  */
9313
8851
  handleFileChanged(filepath) {
9314
8852
  if (this.changedTests.has(filepath) || this.invalidates.has(filepath)) return false;
9315
- if (pm.isMatch(filepath, this.vitest.config.forceRerunTriggers)) {
9316
- this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file));
9317
- return true;
9318
- }
8853
+ if (pm.isMatch(filepath, this.vitest.config.forceRerunTriggers)) return this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file)), true;
9319
8854
  if (this.handleSetupFile(filepath)) return true;
9320
8855
  const projects = this.vitest.projects.filter((project) => {
9321
8856
  const moduleGraph = project.browser?.vite.moduleGraph || project.vite.moduleGraph;
9322
8857
  return moduleGraph.getModulesByFile(filepath)?.size;
9323
8858
  });
9324
- if (!projects.length) {
9325
- // if there are no modules it's possible that server was restarted
9326
- // we don't have information about importers anymore, so let's check if the file is a test file at least
9327
- if (this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project._isCachedTestFile(filepath))) {
9328
- this.changedTests.add(filepath);
9329
- return true;
9330
- }
9331
- return false;
9332
- }
8859
+ if (!projects.length) return this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project._isCachedTestFile(filepath)) ? (this.changedTests.add(filepath), true) : false;
9333
8860
  const files = [];
9334
8861
  for (const project of projects) {
9335
8862
  const mods = project.browser?.vite.moduleGraph.getModulesByFile(filepath) || project.vite.moduleGraph.getModulesByFile(filepath);
9336
8863
  if (!mods || !mods.size) continue;
9337
- this.invalidates.add(filepath);
9338
8864
  // one of test files that we already run, or one of test files that we can run
9339
- if (this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
9340
- this.changedTests.add(filepath);
9341
- files.push(filepath);
8865
+ if (this.invalidates.add(filepath), this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
8866
+ this.changedTests.add(filepath), files.push(filepath);
9342
8867
  continue;
9343
8868
  }
9344
8869
  let rerun = false;
@@ -9409,12 +8934,7 @@ class Vitest {
9409
8934
  _cache;
9410
8935
  _snapshot;
9411
8936
  constructor(mode, cliOptions, options = {}) {
9412
- this.mode = mode;
9413
- this._cliOptions = cliOptions;
9414
- this.logger = new Logger(this, options.stdout, options.stderr);
9415
- this.packageInstaller = options.packageInstaller || new VitestPackageInstaller();
9416
- this.specifications = new VitestSpecifications(this);
9417
- this.watcher = new VitestWatcher(this).onWatcherRerun((file) => this.scheduleRerun([file]));
8937
+ this.mode = mode, this._cliOptions = cliOptions, this.logger = new Logger(this, options.stdout, options.stderr), this.packageInstaller = options.packageInstaller || new VitestPackageInstaller(), this.specifications = new VitestSpecifications(this), this.watcher = new VitestWatcher(this).onWatcherRerun((file) => this.scheduleRerun([file]));
9418
8938
  }
9419
8939
  _onRestartListeners = [];
9420
8940
  _onClose = [];
@@ -9434,8 +8954,7 @@ class Vitest {
9434
8954
  * The global config.
9435
8955
  */
9436
8956
  get config() {
9437
- assert(this._config, "config");
9438
- return this._config;
8957
+ return assert(this._config, "config"), this._config;
9439
8958
  }
9440
8959
  /** @deprecated use `vitest.vite` instead */
9441
8960
  get server() {
@@ -9445,30 +8964,26 @@ class Vitest {
9445
8964
  * Global Vite's dev server instance.
9446
8965
  */
9447
8966
  get vite() {
9448
- assert(this._vite, "vite", "server");
9449
- return this._vite;
8967
+ return assert(this._vite, "vite", "server"), this._vite;
9450
8968
  }
9451
8969
  /**
9452
8970
  * The global test state manager.
9453
8971
  * @experimental The State API is experimental and not subject to semver.
9454
8972
  */
9455
8973
  get state() {
9456
- assert(this._state, "state");
9457
- return this._state;
8974
+ return assert(this._state, "state"), this._state;
9458
8975
  }
9459
8976
  /**
9460
8977
  * The global snapshot manager. You can access the current state on `snapshot.summary`.
9461
8978
  */
9462
8979
  get snapshot() {
9463
- assert(this._snapshot, "snapshot", "snapshot manager");
9464
- return this._snapshot;
8980
+ return assert(this._snapshot, "snapshot", "snapshot manager"), this._snapshot;
9465
8981
  }
9466
8982
  /**
9467
8983
  * Test results and test file stats cache. Primarily used by the sequencer to sort tests.
9468
8984
  */
9469
8985
  get cache() {
9470
- assert(this._cache, "cache");
9471
- return this._cache;
8986
+ return assert(this._cache, "cache"), this._cache;
9472
8987
  }
9473
8988
  /** @deprecated internal */
9474
8989
  setServer(options, server) {
@@ -9476,48 +8991,21 @@ class Vitest {
9476
8991
  }
9477
8992
  /** @internal */
9478
8993
  async _setServer(options, server) {
9479
- this.watcher.unregisterWatcher();
9480
- clearTimeout(this._rerunTimer);
9481
- this.restartsCount += 1;
9482
- this.pool?.close?.();
9483
- this.pool = void 0;
9484
- this.closingPromise = void 0;
9485
- this.projects = [];
9486
- this.coverageProvider = void 0;
9487
- this.runningPromise = void 0;
9488
- this.coreWorkspaceProject = void 0;
9489
- this.specifications.clearCache();
9490
- this._onUserTestsRerun = [];
9491
- this._vite = server;
8994
+ this.watcher.unregisterWatcher(), clearTimeout(this._rerunTimer), this.restartsCount += 1, this.pool?.close?.(), this.pool = void 0, this.closingPromise = void 0, this.projects = [], this.coverageProvider = void 0, this.runningPromise = void 0, this.coreWorkspaceProject = void 0, this.specifications.clearCache(), this._onUserTestsRerun = [], this._vite = server;
9492
8995
  const resolved = resolveConfig(this, options, server.config);
9493
- this._config = resolved;
9494
- this._state = new StateManager({ onUnhandledError: resolved.onUnhandledError });
9495
- this._cache = new VitestCache(this.version);
9496
- this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
9497
- this._testRun = new TestRun(this);
9498
- if (this.config.watch) this.watcher.registerWatcher();
8996
+ if (this._config = resolved, this._state = new StateManager({ onUnhandledError: resolved.onUnhandledError }), this._cache = new VitestCache(this.version), this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions }), this._testRun = new TestRun(this), this.config.watch) this.watcher.registerWatcher();
9499
8997
  this._resolver = new VitestResolver(server.config.cacheDir, resolved);
9500
8998
  const environment = server.environments.__vitest__;
9501
- this.runner = new ServerModuleRunner(environment, this._resolver, resolved);
9502
- if (this.config.watch) {
8999
+ if (this.runner = new ServerModuleRunner(environment, this._resolver, resolved), this.config.watch) {
9503
9000
  // hijack server restart
9504
9001
  const serverRestart = server.restart;
9505
- server.restart = async (...args) => {
9506
- await Promise.all(this._onRestartListeners.map((fn) => fn()));
9507
- this.report("onServerRestart");
9508
- await this.close();
9509
- await serverRestart(...args);
9510
- };
9511
9002
  // since we set `server.hmr: false`, Vite does not auto restart itself
9512
- server.watcher.on("change", async (file) => {
9003
+ server.restart = async (...args) => {
9004
+ await Promise.all(this._onRestartListeners.map((fn) => fn())), this.report("onServerRestart"), await this.close(), await serverRestart(...args);
9005
+ }, server.watcher.on("change", async (file) => {
9513
9006
  file = normalize(file);
9514
9007
  const isConfig = file === server.config.configFile || this.projects.some((p) => p.vite.config.configFile === file);
9515
- if (isConfig) {
9516
- await Promise.all(this._onRestartListeners.map((fn) => fn("config")));
9517
- this.report("onServerRestart", "config");
9518
- await this.close();
9519
- await serverRestart();
9520
- }
9008
+ if (isConfig) await Promise.all(this._onRestartListeners.map((fn) => fn("config"))), this.report("onServerRestart", "config"), await this.close(), await serverRestart();
9521
9009
  });
9522
9010
  }
9523
9011
  this.cache.results.setConfig(resolved.root, resolved.cache);
@@ -9525,28 +9013,24 @@ class Vitest {
9525
9013
  await this.cache.results.readFromCache();
9526
9014
  } catch {}
9527
9015
  const projects = await this.resolveProjects(this._cliOptions);
9528
- this.projects = projects;
9529
- await Promise.all(projects.flatMap((project) => {
9016
+ if (this.projects = projects, await Promise.all(projects.flatMap((project) => {
9530
9017
  const hooks = project.vite.config.getSortedPluginHooks("configureVitest");
9531
9018
  return hooks.map((hook) => hook({
9532
9019
  project,
9533
9020
  vitest: this,
9534
9021
  injectTestProjects: this.injectTestProject
9535
9022
  }));
9536
- }));
9537
- if (this._cliOptions.browser?.enabled) {
9023
+ })), this._cliOptions.browser?.enabled) {
9538
9024
  const browserProjects = this.projects.filter((p) => p.config.browser.enabled);
9539
9025
  if (!browserProjects.length) throw new Error(`Vitest received --browser flag, but no project had a browser configuration.`);
9540
9026
  }
9541
9027
  if (!this.projects.length) {
9542
9028
  const filter = toArray(resolved.project).join("\", \"");
9543
- if (filter) throw new Error(`No projects matched the filter "${filter}".`);
9544
- else throw new Error(`Vitest wasn't able to resolve any project.`);
9029
+ throw filter ? new Error(`No projects matched the filter "${filter}".`) : new Error(`Vitest wasn't able to resolve any project.`);
9545
9030
  }
9546
9031
  if (!this.coreWorkspaceProject) this.coreWorkspaceProject = TestProject._createBasicProject(this);
9547
9032
  if (this.config.testNamePattern) this.configOverride.testNamePattern = this.config.testNamePattern;
9548
- this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this);
9549
- await Promise.all(this._onSetServer.map((fn) => fn()));
9033
+ this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this), await Promise.all(this._onSetServer.map((fn) => fn()));
9550
9034
  }
9551
9035
  /**
9552
9036
  * Inject new test projects into the workspace.
@@ -9554,10 +9038,8 @@ class Vitest {
9554
9038
  * @returns An array of new test projects. Can be empty if the name was filtered out.
9555
9039
  */
9556
9040
  injectTestProject = async (config) => {
9557
- const currentNames = new Set(this.projects.map((p) => p.name));
9558
- const projects = await resolveProjects(this, this._cliOptions, void 0, Array.isArray(config) ? config : [config], currentNames);
9559
- this.projects.push(...projects);
9560
- return projects;
9041
+ const currentNames = new Set(this.projects.map((p) => p.name)), projects = await resolveProjects(this, this._cliOptions, void 0, Array.isArray(config) ? config : [config], currentNames);
9042
+ return this.projects.push(...projects), projects;
9561
9043
  };
9562
9044
  /**
9563
9045
  * Provide a value to the test context. This value will be available to all tests with `inject`.
@@ -9573,9 +9055,7 @@ class Vitest {
9573
9055
  }
9574
9056
  /** @internal */
9575
9057
  _ensureRootProject() {
9576
- if (this.coreWorkspaceProject) return this.coreWorkspaceProject;
9577
- this.coreWorkspaceProject = TestProject._createBasicProject(this);
9578
- return this.coreWorkspaceProject;
9058
+ return this.coreWorkspaceProject ||= TestProject._createBasicProject(this), this.coreWorkspaceProject;
9579
9059
  }
9580
9060
  /** @deprecated use `getRootProject` instead */
9581
9061
  getCoreWorkspaceProject() {
@@ -9592,8 +9072,7 @@ class Vitest {
9592
9072
  * @deprecated use Reported Task API instead
9593
9073
  */
9594
9074
  getProjectByTaskId(taskId) {
9595
- const task = this.state.idMap.get(taskId);
9596
- const projectName = task.projectName || task?.file?.projectName || "";
9075
+ const task = this.state.idMap.get(taskId), projectName = task.projectName || task?.file?.projectName || "";
9597
9076
  return this.getProjectByName(projectName);
9598
9077
  }
9599
9078
  getProjectByName(name) {
@@ -9615,8 +9094,7 @@ class Vitest {
9615
9094
  // user can filter projects with --project flag, `getDefaultTestProject`
9616
9095
  // returns the project only if it matches the filter
9617
9096
  const project = getDefaultTestProject(this);
9618
- if (!project) return [];
9619
- return resolveBrowserProjects(this, new Set([project.name]), [project]);
9097
+ return project ? resolveBrowserProjects(this, new Set([project.name]), [project]) : [];
9620
9098
  }
9621
9099
  /**
9622
9100
  * Glob test files in every project and create a TestSpecification for each file and pool.
@@ -9626,13 +9104,10 @@ class Vitest {
9626
9104
  return this.specifications.globTestSpecifications(filters);
9627
9105
  }
9628
9106
  async initCoverageProvider() {
9629
- if (this.coverageProvider !== void 0) return;
9630
- this.coverageProvider = await getCoverageProvider(this.config.coverage, this.runner);
9631
- if (this.coverageProvider) {
9632
- await this.coverageProvider.initialize(this);
9633
- this.config.coverage = this.coverageProvider.resolveOptions();
9107
+ if (this.coverageProvider === void 0) {
9108
+ if (this.coverageProvider = await getCoverageProvider(this.config.coverage, this.runner), this.coverageProvider) await this.coverageProvider.initialize(this), this.config.coverage = this.coverageProvider.resolveOptions();
9109
+ return this.coverageProvider;
9634
9110
  }
9635
- return this.coverageProvider;
9636
9111
  }
9637
9112
  /**
9638
9113
  * Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified).
@@ -9645,23 +9120,15 @@ class Vitest {
9645
9120
  errors,
9646
9121
  coverages,
9647
9122
  executionTimes
9648
- };
9649
- await this.report("onInit", this);
9650
- await this.report("onPathsCollected", files.flatMap((f) => f.filepath));
9123
+ }, await this.report("onInit", this);
9651
9124
  const specifications = [];
9652
9125
  for (const file of files) {
9653
- const project = this.getProjectByName(file.projectName || "");
9654
- const specification = project.createSpecification(file.filepath, void 0, file.pool);
9126
+ const project = this.getProjectByName(file.projectName || ""), specification = project.createSpecification(file.filepath, void 0, file.pool);
9655
9127
  specifications.push(specification);
9656
9128
  }
9657
- await this.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
9658
9129
  await this._testRun.start(specifications).catch(noop);
9659
9130
  for (const file of files) await this._reportFileTask(file);
9660
- this._checkUnhandledErrors(errors);
9661
- await this._testRun.end(specifications, errors).catch(noop);
9662
- await this.initCoverageProvider();
9663
- await this.coverageProvider?.mergeReports?.(coverages);
9664
- return {
9131
+ return this._checkUnhandledErrors(errors), await this._testRun.end(specifications, errors).catch(noop), await this.initCoverageProvider(), await this.coverageProvider?.mergeReports?.(coverages), {
9665
9132
  testModules: this.state.getTestModules(),
9666
9133
  unhandledErrors: this.state.getUnhandledErrors()
9667
9134
  };
@@ -9669,10 +9136,8 @@ class Vitest {
9669
9136
  /** @internal */
9670
9137
  async _reportFileTask(file) {
9671
9138
  const project = this.getProjectByName(file.projectName || "");
9672
- await this._testRun.enqueued(project, file).catch(noop);
9673
- await this._testRun.collected(project, [file]).catch(noop);
9674
- const logs = [];
9675
- const { packs, events } = convertTasksToEvents(file, (task) => {
9139
+ await this._testRun.enqueued(project, file).catch(noop), await this._testRun.collected(project, [file]).catch(noop);
9140
+ const logs = [], { packs, events } = convertTasksToEvents(file, (task) => {
9676
9141
  if (task.logs) logs.push(...task.logs);
9677
9142
  });
9678
9143
  logs.sort((log1, log2) => log1.time - log2.time);
@@ -9681,12 +9146,10 @@ class Vitest {
9681
9146
  }
9682
9147
  async collect(filters) {
9683
9148
  const files = await this.specifications.getRelevantTestSpecifications(filters);
9684
- // if run with --changed, don't exit if no tests are found
9685
- if (!files.length) return {
9149
+ return files.length ? this.collectTests(files) : {
9686
9150
  testModules: [],
9687
9151
  unhandledErrors: []
9688
9152
  };
9689
- return this.collectTests(files);
9690
9153
  }
9691
9154
  /** @deprecated use `getRelevantTestSpecifications` instead */
9692
9155
  listFiles(filters) {
@@ -9709,8 +9172,7 @@ class Vitest {
9709
9172
  */
9710
9173
  async start(filters) {
9711
9174
  try {
9712
- await this.initCoverageProvider();
9713
- await this.coverageProvider?.clean(this.config.coverage.clean);
9175
+ await this.initCoverageProvider(), await this.coverageProvider?.clean(this.config.coverage.clean);
9714
9176
  } finally {
9715
9177
  await this.report("onInit", this);
9716
9178
  }
@@ -9720,20 +9182,13 @@ class Vitest {
9720
9182
  if (!files.length) {
9721
9183
  await this._testRun.start([]);
9722
9184
  const coverage = await this.coverageProvider?.generateCoverage?.({ allTestsRun: true });
9723
- await this._testRun.end([], [], coverage);
9724
- // Report coverage for uncovered files
9725
- await this.reportCoverage(coverage, true);
9726
- if (!this.config.watch || !(this.config.changed || this.config.related?.length)) throw new FilesNotFoundError(this.mode);
9185
+ if (await this._testRun.end([], [], coverage), await this.reportCoverage(coverage, true), !this.config.watch || !(this.config.changed || this.config.related?.length)) throw new FilesNotFoundError(this.mode);
9727
9186
  }
9728
9187
  let testModules = {
9729
9188
  testModules: [],
9730
9189
  unhandledErrors: []
9731
9190
  };
9732
- if (files.length) {
9733
- // populate once, update cache on watch
9734
- await this.cache.stats.populateStats(this.config.root, files);
9735
- testModules = await this.runFiles(files, true);
9736
- }
9191
+ if (files.length) await this.cache.stats.populateStats(this.config.root, files), testModules = await this.runFiles(files, true);
9737
9192
  if (this.config.watch) await this.report("onWatcherStart");
9738
9193
  return testModules;
9739
9194
  }
@@ -9743,14 +9198,11 @@ class Vitest {
9743
9198
  */
9744
9199
  async init() {
9745
9200
  try {
9746
- await this.initCoverageProvider();
9747
- await this.coverageProvider?.clean(this.config.coverage.clean);
9201
+ await this.initCoverageProvider(), await this.coverageProvider?.clean(this.config.coverage.clean);
9748
9202
  } finally {
9749
9203
  await this.report("onInit", this);
9750
9204
  }
9751
- // populate test files cache so watch mode can trigger a file rerun
9752
- await this.globTestSpecifications();
9753
- if (this.config.watch) await this.report("onWatcherStart");
9205
+ if (await this.globTestSpecifications(), this.config.watch) await this.report("onWatcherStart");
9754
9206
  }
9755
9207
  /**
9756
9208
  * @deprecated remove when vscode extension supports "getModuleSpecifications"
@@ -9783,8 +9235,7 @@ class Vitest {
9783
9235
  * @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
9784
9236
  */
9785
9237
  runTestSpecifications(specifications, allTestsRun = false) {
9786
- specifications.forEach((spec) => this.specifications.ensureSpecificationCached(spec));
9787
- return this.runFiles(specifications, allTestsRun);
9238
+ return specifications.forEach((spec) => this.specifications.ensureSpecificationCached(spec)), this.runFiles(specifications, allTestsRun);
9788
9239
  }
9789
9240
  /**
9790
9241
  * Rerun files and trigger `onWatcherRerun`, `onWatcherStart` and `onTestsRerun` events.
@@ -9796,24 +9247,14 @@ class Vitest {
9796
9247
  const files = specifications.map((spec) => spec.moduleId);
9797
9248
  await Promise.all([this.report("onWatcherRerun", files, "rerun test"), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
9798
9249
  const result = await this.runTestSpecifications(specifications, allTestsRun);
9799
- await this.report("onWatcherStart", this.state.getFiles(files));
9800
- return result;
9250
+ return await this.report("onWatcherStart", this.state.getFiles(files)), result;
9801
9251
  }
9802
9252
  async runFiles(specs, allTestsRun) {
9803
- await this._testRun.start(specs);
9804
- // previous run
9805
- await this.runningPromise;
9806
- this._onCancelListeners = [];
9807
- this.isCancelling = false;
9808
- // schedule the new run
9809
- this.runningPromise = (async () => {
9253
+ return await this._testRun.start(specs), await this.runningPromise, this._onCancelListeners = [], this.isCancelling = false, this.runningPromise = (async () => {
9810
9254
  try {
9811
9255
  if (!this.pool) this.pool = createPool(this);
9812
9256
  const invalidates = Array.from(this.watcher.invalidates);
9813
- this.watcher.invalidates.clear();
9814
- this.snapshot.clear();
9815
- this.state.clearErrors();
9816
- if (!this.isFirstRun && this.config.coverage.cleanOnRerun) await this.coverageProvider?.clean();
9257
+ if (this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), !this.isFirstRun && this.config.coverage.cleanOnRerun) await this.coverageProvider?.clean();
9817
9258
  await this.initializeGlobalSetup(specs);
9818
9259
  try {
9819
9260
  await this.pool.runTests(specs, invalidates);
@@ -9830,21 +9271,12 @@ class Vitest {
9830
9271
  unhandledErrors: this.state.getUnhandledErrors()
9831
9272
  };
9832
9273
  } finally {
9833
- // TODO: wait for coverage only if `onFinished` is defined
9834
- const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun });
9835
- const errors = this.state.getUnhandledErrors();
9836
- this._checkUnhandledErrors(errors);
9837
- await this._testRun.end(specs, errors, coverage);
9838
- await this.reportCoverage(coverage, allTestsRun);
9274
+ const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun }), errors = this.state.getUnhandledErrors();
9275
+ this._checkUnhandledErrors(errors), await this._testRun.end(specs, errors, coverage), await this.reportCoverage(coverage, allTestsRun);
9839
9276
  }
9840
9277
  })().finally(() => {
9841
- this.runningPromise = void 0;
9842
- this.isFirstRun = false;
9843
- // all subsequent runs will treat this as a fresh run
9844
- this.config.changed = false;
9845
- this.config.related = void 0;
9846
- });
9847
- return await this.runningPromise;
9278
+ this.runningPromise = void 0, this.isFirstRun = false, this.config.changed = false, this.config.related = void 0;
9279
+ }), await this.runningPromise;
9848
9280
  }
9849
9281
  /**
9850
9282
  * Collect tests in specified modules. Vitest will run the files to collect tests.
@@ -9852,19 +9284,10 @@ class Vitest {
9852
9284
  */
9853
9285
  async collectTests(specifications) {
9854
9286
  const filepaths = specifications.map((spec) => spec.moduleId);
9855
- this.state.collectPaths(filepaths);
9856
- // previous run
9857
- await this.runningPromise;
9858
- this._onCancelListeners = [];
9859
- this.isCancelling = false;
9860
- // schedule the new run
9861
- this.runningPromise = (async () => {
9287
+ return this.state.collectPaths(filepaths), await this.runningPromise, this._onCancelListeners = [], this.isCancelling = false, this.runningPromise = (async () => {
9862
9288
  if (!this.pool) this.pool = createPool(this);
9863
9289
  const invalidates = Array.from(this.watcher.invalidates);
9864
- this.watcher.invalidates.clear();
9865
- this.snapshot.clear();
9866
- this.state.clearErrors();
9867
- await this.initializeGlobalSetup(specifications);
9290
+ this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), await this.initializeGlobalSetup(specifications);
9868
9291
  try {
9869
9292
  await this.pool.collectTests(specifications, invalidates);
9870
9293
  } catch (err) {
@@ -9879,28 +9302,21 @@ class Vitest {
9879
9302
  unhandledErrors: this.state.getUnhandledErrors()
9880
9303
  };
9881
9304
  })().finally(() => {
9882
- this.runningPromise = void 0;
9883
- // all subsequent runs will treat this as a fresh run
9884
- this.config.changed = false;
9885
- this.config.related = void 0;
9886
- });
9887
- return await this.runningPromise;
9305
+ this.runningPromise = void 0, this.config.changed = false, this.config.related = void 0;
9306
+ }), await this.runningPromise;
9888
9307
  }
9889
9308
  /**
9890
9309
  * Gracefully cancel the current test run. Vitest will wait until all running tests are finished before cancelling.
9891
9310
  */
9892
9311
  async cancelCurrentRun(reason) {
9893
- this.isCancelling = true;
9894
- await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
9895
- await this.runningPromise;
9312
+ this.isCancelling = true, await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason))), await this.runningPromise;
9896
9313
  }
9897
9314
  /** @internal */
9898
9315
  async _initBrowserServers() {
9899
9316
  await Promise.all(this.projects.map((p) => p._initBrowserServer()));
9900
9317
  }
9901
9318
  async initializeGlobalSetup(paths) {
9902
- const projects = new Set(paths.map((spec) => spec.project));
9903
- const coreProject = this.getRootProject();
9319
+ const projects = new Set(paths.map((spec) => spec.project)), coreProject = this.getRootProject();
9904
9320
  if (!projects.has(coreProject)) projects.add(coreProject);
9905
9321
  for (const project of projects) await project._initializeGlobalSetup();
9906
9322
  }
@@ -9914,8 +9330,7 @@ class Vitest {
9914
9330
  const specifications = files.flatMap((file) => this.getModuleSpecifications(file));
9915
9331
  await Promise.all([this.report("onWatcherRerun", files, trigger), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
9916
9332
  const testResult = await this.runFiles(specifications, allTestsRun);
9917
- await this.report("onWatcherStart", this.state.getFiles(files));
9918
- return testResult;
9333
+ return await this.report("onWatcherStart", this.state.getFiles(files)), testResult;
9919
9334
  }
9920
9335
  /** @internal */
9921
9336
  async rerunTask(id) {
@@ -9935,9 +9350,8 @@ class Vitest {
9935
9350
  // Empty test name pattern should reset filename pattern as well
9936
9351
  if (pattern === "") this.filenamePattern = void 0;
9937
9352
  const testNamePattern = pattern ? new RegExp(pattern) : void 0;
9938
- this.configOverride.testNamePattern = testNamePattern;
9939
9353
  // filter only test files that have tests matching the pattern
9940
- if (testNamePattern) files = files.filter((filepath) => {
9354
+ if (this.configOverride.testNamePattern = testNamePattern, testNamePattern) files = files.filter((filepath) => {
9941
9355
  const files = this.state.getFiles([filepath]);
9942
9356
  return !files.length || files.some((file) => {
9943
9357
  const tasks = getTasks(file);
@@ -9961,9 +9375,7 @@ class Vitest {
9961
9375
  * @param files The list of files on the file system
9962
9376
  */
9963
9377
  async updateSnapshot(files) {
9964
- // default to failed files
9965
- files = files || [...this.state.getFailedFilepaths(), ...this.snapshot.summary.uncheckedKeysByFile.map((s) => s.filePath)];
9966
- this.enableSnapshotUpdate();
9378
+ files = files || [...this.state.getFailedFilepaths(), ...this.snapshot.summary.uncheckedKeysByFile.map((s) => s.filePath)], this.enableSnapshotUpdate();
9967
9379
  try {
9968
9380
  return await this.rerunFiles(files, "update snapshot", false);
9969
9381
  } finally {
@@ -9981,15 +9393,13 @@ class Vitest {
9981
9393
  this.configOverride.snapshotOptions = {
9982
9394
  updateSnapshot: "all",
9983
9395
  snapshotEnvironment: null
9984
- };
9985
- this.snapshot.options.updateSnapshot = "all";
9396
+ }, this.snapshot.options.updateSnapshot = "all";
9986
9397
  }
9987
9398
  /**
9988
9399
  * Disable the mode that allows updating snapshots when running tests.
9989
9400
  */
9990
9401
  resetSnapshotUpdate() {
9991
- delete this.configOverride.snapshotOptions;
9992
- this.snapshot.options.updateSnapshot = this.config.snapshotOptions.updateSnapshot;
9402
+ delete this.configOverride.snapshotOptions, this.snapshot.options.updateSnapshot = this.config.snapshotOptions.updateSnapshot;
9993
9403
  }
9994
9404
  /**
9995
9405
  * Set the global test name pattern to a regexp.
@@ -10009,39 +9419,26 @@ class Vitest {
10009
9419
  // we can't use a single `triggerId` yet because vscode extension relies on this
10010
9420
  async scheduleRerun(triggerId) {
10011
9421
  const currentCount = this.restartsCount;
10012
- clearTimeout(this._rerunTimer);
10013
- await this.runningPromise;
10014
- clearTimeout(this._rerunTimer);
10015
- // server restarted
10016
- if (this.restartsCount !== currentCount) return;
10017
- this._rerunTimer = setTimeout(async () => {
9422
+ clearTimeout(this._rerunTimer), await this.runningPromise, clearTimeout(this._rerunTimer), this.restartsCount === currentCount && (this._rerunTimer = setTimeout(async () => {
10018
9423
  if (this.watcher.changedTests.size === 0) {
10019
9424
  this.watcher.invalidates.clear();
10020
9425
  return;
10021
9426
  }
10022
9427
  // server restarted
10023
9428
  if (this.restartsCount !== currentCount) return;
10024
- this.isFirstRun = false;
10025
- this.snapshot.clear();
9429
+ this.isFirstRun = false, this.snapshot.clear();
10026
9430
  let files = Array.from(this.watcher.changedTests);
10027
9431
  if (this.filenamePattern) {
10028
9432
  const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
10029
- files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
10030
9433
  // A file that does not match the current filename pattern was changed
10031
- if (files.length === 0) return;
9434
+ if (files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file)), files.length === 0) return;
10032
9435
  }
10033
9436
  this.watcher.changedTests.clear();
10034
- const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id)));
10035
- const triggerLabel = Array.from(triggerIds).join(", ");
10036
- // get file specifications and filter them if needed
10037
- const specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
10038
- if (this._onFilterWatchedSpecification.length === 0) return true;
10039
- return this._onFilterWatchedSpecification.every((fn) => fn(specification));
9437
+ const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id))), triggerLabel = Array.from(triggerIds).join(", "), specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
9438
+ return this._onFilterWatchedSpecification.length === 0 ? true : this._onFilterWatchedSpecification.every((fn) => fn(specification));
10040
9439
  });
10041
- await Promise.all([this.report("onWatcherRerun", files, triggerLabel), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
10042
- await this.runFiles(specifications, false);
10043
- await this.report("onWatcherStart", this.state.getFiles(files));
10044
- }, WATCHER_DEBOUNCE);
9440
+ await Promise.all([this.report("onWatcherRerun", files, triggerLabel), ...this._onUserTestsRerun.map((fn) => fn(specifications))]), await this.runFiles(specifications, false), await this.report("onWatcherStart", this.state.getFiles(files));
9441
+ }, WATCHER_DEBOUNCE));
10045
9442
  }
10046
9443
  /**
10047
9444
  * Invalidate a file in all projects.
@@ -10065,8 +9462,7 @@ class Vitest {
10065
9462
  }
10066
9463
  async reportCoverage(coverage, allTestsRun) {
10067
9464
  if (this.state.getCountOfFailedTests() > 0) {
10068
- await this.coverageProvider?.onTestFailure?.();
10069
- if (!this.config.coverage.reportOnFailure) return;
9465
+ if (await this.coverageProvider?.onTestFailure?.(), !this.config.coverage.reportOnFailure) return;
10070
9466
  }
10071
9467
  if (this.coverageProvider) {
10072
9468
  await this.coverageProvider.reportCoverage(coverage, { allTestsRun });
@@ -10089,11 +9485,9 @@ class Vitest {
10089
9485
  // it's possible that it's not initialized at all because it's not running any tests
10090
9486
  if (this.coreWorkspaceProject && !this.projects.includes(this.coreWorkspaceProject)) closePromises.push(this.coreWorkspaceProject.close().then(() => this._vite = void 0));
10091
9487
  if (this.pool) closePromises.push((async () => {
10092
- await this.pool?.close?.();
10093
- this.pool = void 0;
9488
+ await this.pool?.close?.(), this.pool = void 0;
10094
9489
  })());
10095
- closePromises.push(...this._onClose.map((fn) => fn()));
10096
- return Promise.allSettled(closePromises).then((results) => {
9490
+ return closePromises.push(...this._onClose.map((fn) => fn())), Promise.allSettled(closePromises).then((results) => {
10097
9491
  results.forEach((r) => {
10098
9492
  if (r.status === "rejected") this.logger.error("error during close", r.reason);
10099
9493
  });
@@ -10106,11 +9500,9 @@ class Vitest {
10106
9500
  * @param force If true, the process will exit immediately after closing the projects.
10107
9501
  */
10108
9502
  async exit(force = false) {
10109
- setTimeout(() => {
9503
+ if (setTimeout(() => {
10110
9504
  this.report("onProcessTimeout").then(() => {
10111
- console.warn(`close timed out after ${this.config.teardownTimeout}ms`);
10112
- this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause));
10113
- if (!this.pool) {
9505
+ if (console.warn(`close timed out after ${this.config.teardownTimeout}ms`), this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause)), !this.pool) {
10114
9506
  const runningServers = [this._vite, ...this.projects.map((p) => p._vite)].filter(Boolean).length;
10115
9507
  if (runningServers === 1) console.warn("Tests closed successfully but something prevents Vite server from exiting");
10116
9508
  else if (runningServers > 1) console.warn(`Tests closed successfully but something prevents ${runningServers} Vite servers from exiting`);
@@ -10119,9 +9511,7 @@ class Vitest {
10119
9511
  }
10120
9512
  process.exit();
10121
9513
  });
10122
- }, this.config.teardownTimeout).unref();
10123
- await this.close();
10124
- if (force) process.exit();
9514
+ }, this.config.teardownTimeout).unref(), await this.close(), force) process.exit();
10125
9515
  }
10126
9516
  /** @internal */
10127
9517
  async report(name, ...args) {
@@ -10203,9 +9593,7 @@ class Vitest {
10203
9593
  */
10204
9594
  matchesProjectFilter(name) {
10205
9595
  const projects = this._config?.project || this._cliOptions?.project;
10206
- // no filters applied, any project can be included
10207
- if (!projects || !projects.length) return true;
10208
- return toArray(projects).some((project) => {
9596
+ return !projects || !projects.length ? true : toArray(projects).some((project) => {
10209
9597
  const regexp = wildcardPatternToRegExp(project);
10210
9598
  return regexp.test(name);
10211
9599
  });
@@ -10218,8 +9606,7 @@ function assert(condition, property, name = property) {
10218
9606
  async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(options))) {
10219
9607
  const userConfig = deepMerge({}, options);
10220
9608
  async function UIPlugin() {
10221
- await vitest.packageInstaller.ensureInstalled("@vitest/ui", options.root || process.cwd(), vitest.version);
10222
- return (await import('@vitest/ui')).default(vitest);
9609
+ return await vitest.packageInstaller.ensureInstalled("@vitest/ui", options.root || process.cwd(), vitest.version), (await import('@vitest/ui')).default(vitest);
10223
9610
  }
10224
9611
  return [
10225
9612
  {
@@ -10245,14 +9632,9 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
10245
9632
  let open = false;
10246
9633
  if (testConfig.ui && testConfig.open) open = testConfig.uiBase ?? "/__vitest__/";
10247
9634
  const resolveOptions = getDefaultResolveOptions();
10248
- const config = {
9635
+ let config = {
10249
9636
  root: viteConfig.test?.root || options.root,
10250
9637
  define: { "process.env.NODE_ENV": "process.env.NODE_ENV" },
10251
- esbuild: viteConfig.esbuild === false ? false : {
10252
- target: viteConfig.esbuild?.target || "node18",
10253
- sourcemap: "external",
10254
- legalComments: "inline"
10255
- },
10256
9638
  resolve: {
10257
9639
  ...resolveOptions,
10258
9640
  alias: testConfig.alias
@@ -10282,21 +9664,29 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
10282
9664
  deps: testConfig.deps ?? viteConfig.test?.deps
10283
9665
  }
10284
9666
  };
9667
+ if ("rolldownVersion" in vite) config = {
9668
+ ...config,
9669
+ oxc: viteConfig.oxc === false ? false : { target: viteConfig.oxc?.target || "node18" }
9670
+ };
9671
+ else config = {
9672
+ ...config,
9673
+ esbuild: viteConfig.esbuild === false ? false : {
9674
+ target: viteConfig.esbuild?.target || "node18",
9675
+ sourcemap: "external",
9676
+ legalComments: "inline"
9677
+ }
9678
+ };
10285
9679
  // inherit so it's available in VitestOptimizer
10286
9680
  // I cannot wait to rewrite all of this in Vitest 4
10287
9681
  if (options.cache != null) config.test.cache = options.cache;
10288
9682
  if (vitest.configOverride.project)
10289
9683
  // project filter was set by the user, so we need to filter the project
10290
9684
  options.project = vitest.configOverride.project;
10291
- config.customLogger = createViteLogger(vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
10292
- config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
10293
9685
  // chokidar fsevents is unstable on macos when emitting "ready" event
10294
- if (process.platform === "darwin" && false);
9686
+ if (config.customLogger = createViteLogger(vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false }), config.customLogger = silenceImportViteIgnoreWarning(config.customLogger), process.platform === "darwin" && false);
10295
9687
  const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
10296
9688
  if (classNameStrategy !== "scoped") {
10297
- config.css ??= {};
10298
- config.css.modules ??= {};
10299
- if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
9689
+ if (config.css ??= {}, config.css.modules ??= {}, config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
10300
9690
  const root = vitest.config.root || options.root || process.cwd();
10301
9691
  return generateScopedClassName(classNameStrategy, name, relative(root, filename));
10302
9692
  };
@@ -10307,17 +9697,11 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
10307
9697
  const viteConfigTest = viteConfig.test || {};
10308
9698
  if (viteConfigTest.watch === false) viteConfigTest.run = true;
10309
9699
  if ("alias" in viteConfigTest) delete viteConfigTest.alias;
10310
- // viteConfig.test is final now, merge it for real
10311
- options = deepMerge({}, configDefaults, viteConfigTest, options);
10312
- options.api = resolveApiServerConfig(options, defaultPort);
9700
+ options = deepMerge({}, configDefaults, viteConfigTest, options), options.api = resolveApiServerConfig(options, defaultPort);
10313
9701
  // we replace every "import.meta.env" with "process.env"
10314
9702
  // to allow reassigning, so we need to put all envs on process.env
10315
9703
  const { PROD, DEV,...envs } = viteConfig.env;
10316
- // process.env can have only string values and will cast string on it if we pass other type,
10317
- // so we are making them truthy
10318
- process.env.PROD ??= PROD ? "1" : "";
10319
- process.env.DEV ??= DEV ? "1" : "";
10320
- for (const name in envs) process.env[name] ??= envs[name];
9704
+ for (const name in process.env.PROD ??= PROD ? "1" : "", process.env.DEV ??= DEV ? "1" : "", envs) process.env[name] ??= envs[name];
10321
9705
  // don't watch files in run mode
10322
9706
  if (!options.watch) viteConfig.server.watch = null;
10323
9707
  if (options.ui)
@@ -10337,8 +9721,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
10337
9721
  order: "post",
10338
9722
  async handler(server) {
10339
9723
  if (options.watch && false);
10340
- await vitest._setServer(options, server);
10341
- if (options.api && options.watch) (await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
9724
+ if (await vitest._setServer(options, server), options.api && options.watch) (await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
10342
9725
  // #415, in run mode we don't need the watcher, close it would improve the performance
10343
9726
  if (!options.watch) await server.watcher.close();
10344
9727
  }
@@ -10360,25 +9743,19 @@ function removeUndefinedValues(obj) {
10360
9743
  }
10361
9744
 
10362
9745
  async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {}) {
10363
- const ctx = new Vitest(mode, deepClone(options), vitestOptions);
10364
- const root = slash(resolve$1(options.root || process.cwd()));
10365
- const configPath = options.config === false ? false : options.config ? resolve$1(root, options.config) : await findUp(configFiles, { cwd: root });
9746
+ const ctx = new Vitest(mode, deepClone(options), vitestOptions), root = slash(resolve$1(options.root || process.cwd())), configPath = options.config === false ? false : options.config ? resolve$1(root, options.config) : await findUp(configFiles, { cwd: root });
10366
9747
  options.config = configPath;
10367
- const { browser: _removeBrowser,...restOptions } = options;
10368
- const config = {
9748
+ const { browser: _removeBrowser,...restOptions } = options, config = {
10369
9749
  configFile: configPath,
10370
9750
  configLoader: options.configLoader,
10371
9751
  mode: options.mode || mode,
10372
9752
  plugins: await VitestPlugin(restOptions, ctx)
10373
- };
10374
- const server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
9753
+ }, server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
10375
9754
  if (ctx.config.api?.port) await server.listen();
10376
9755
  return ctx;
10377
9756
  }
10378
9757
 
10379
- const MAX_RESULT_COUNT = 10;
10380
- const SELECTION_MAX_INDEX = 7;
10381
- const ESC = "\x1B[";
9758
+ const MAX_RESULT_COUNT = 10, SELECTION_MAX_INDEX = 7, ESC = "\x1B[";
10382
9759
  class WatchFilter {
10383
9760
  filterRL;
10384
9761
  currentKeyword = void 0;
@@ -10389,23 +9766,17 @@ class WatchFilter {
10389
9766
  stdin;
10390
9767
  stdout;
10391
9768
  constructor(message, stdin = process.stdin, stdout$1 = stdout()) {
10392
- this.message = message;
10393
- this.stdin = stdin;
10394
- this.stdout = stdout$1;
10395
- this.filterRL = readline.createInterface({
9769
+ if (this.message = message, this.stdin = stdin, this.stdout = stdout$1, this.filterRL = readline.createInterface({
10396
9770
  input: this.stdin,
10397
9771
  escapeCodeTimeout: 50
10398
- });
10399
- readline.emitKeypressEvents(this.stdin, this.filterRL);
10400
- if (this.stdin.isTTY) this.stdin.setRawMode(true);
9772
+ }), readline.emitKeypressEvents(this.stdin, this.filterRL), this.stdin.isTTY) this.stdin.setRawMode(true);
10401
9773
  }
10402
9774
  async filter(filterFunc) {
10403
9775
  this.write(this.promptLine());
10404
9776
  const resultPromise = createDefer();
10405
9777
  this.onKeyPress = this.filterHandler(filterFunc, (result) => {
10406
9778
  resultPromise.resolve(result);
10407
- });
10408
- this.stdin.on("keypress", this.onKeyPress);
9779
+ }), this.stdin.on("keypress", this.onKeyPress);
10409
9780
  try {
10410
9781
  return await resultPromise;
10411
9782
  } finally {
@@ -10421,13 +9792,11 @@ class WatchFilter {
10421
9792
  break;
10422
9793
  case key?.ctrl && key?.name === "c":
10423
9794
  case key?.name === "escape":
10424
- this.write(`${ESC}1G${ESC}0J`);
10425
- onSubmit(void 0);
9795
+ this.write(`${ESC}1G${ESC}0J`), onSubmit(void 0);
10426
9796
  return;
10427
9797
  case key?.name === "enter":
10428
9798
  case key?.name === "return":
10429
- onSubmit(this.results[this.selectionIndex] || this.currentKeyword || "");
10430
- this.currentKeyword = void 0;
9799
+ onSubmit(this.results[this.selectionIndex] || this.currentKeyword || ""), this.currentKeyword = void 0;
10431
9800
  break;
10432
9801
  case key?.name === "up":
10433
9802
  if (this.selectionIndex && this.selectionIndex > 0) this.selectionIndex--;
@@ -10454,17 +9823,13 @@ class WatchFilter {
10454
9823
  const resultCountLine = this.results.length === 1 ? `Pattern matches ${this.results.length} result` : `Pattern matches ${this.results.length} results`;
10455
9824
  let resultBody = "";
10456
9825
  if (this.results.length > MAX_RESULT_COUNT) {
10457
- const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0;
10458
- const displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset);
10459
- const remainingResultCount = this.results.length - offset - displayResults.length;
10460
- resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n")}`;
10461
- if (remainingResultCount > 0) resultBody += `
9826
+ const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0, displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset), remainingResultCount = this.results.length - offset - displayResults.length;
9827
+ if (resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n")}`, remainingResultCount > 0) resultBody += `
10462
9828
  ${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "result" : "results"}`)}`;
10463
9829
  } else resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n");
10464
9830
  printStr += `\n${resultCountLine}\n${resultBody}`;
10465
9831
  }
10466
- this.eraseAndPrint(printStr);
10467
- this.restoreCursor();
9832
+ this.eraseAndPrint(printStr), this.restoreCursor();
10468
9833
  }
10469
9834
  keywordOffset() {
10470
9835
  return `? ${this.message} › `.length + 1;
@@ -10480,14 +9845,10 @@ ${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "
10480
9845
  // We have to take care of screen width in case of long lines
10481
9846
  rows += 1 + Math.floor(Math.max(stripVTControlCharacters(line).length - 1, 0) / columns);
10482
9847
  }
10483
- this.write(`${ESC}1G`);
10484
- this.write(`${ESC}J`);
10485
- this.write(str);
10486
- this.write(`${ESC}${rows - 1}A`);
9848
+ this.write(`${ESC}1G`), this.write(`${ESC}J`), this.write(str), this.write(`${ESC}${rows - 1}A`);
10487
9849
  }
10488
9850
  close() {
10489
- this.filterRL.close();
10490
- if (this.onKeyPress) this.stdin.removeListener("keypress", this.onKeyPress);
9851
+ if (this.filterRL.close(), this.onKeyPress) this.stdin.removeListener("keypress", this.onKeyPress);
10491
9852
  if (this.stdin.isTTY) this.stdin.setRawMode(false);
10492
9853
  }
10493
9854
  restoreCursor() {
@@ -10512,8 +9873,7 @@ const keys = [
10512
9873
  ["w", "filter by a project name"],
10513
9874
  ["b", "start the browser server if not started yet"],
10514
9875
  ["q", "quit"]
10515
- ];
10516
- const cancelKeys = [
9876
+ ], cancelKeys = [
10517
9877
  "space",
10518
9878
  "c",
10519
9879
  "h",
@@ -10531,17 +9891,12 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10531
9891
  // Cancel run and exit when ctrl-c or esc is pressed.
10532
9892
  // If cancelling takes long and key is pressed multiple times, exit forcefully.
10533
9893
  if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c") {
10534
- if (!ctx.isCancelling) {
10535
- ctx.logger.log(c.red("Cancelling test run. Press CTRL+c again to exit forcefully.\n"));
10536
- process.exitCode = 130;
10537
- await ctx.cancelCurrentRun("keyboard-input");
10538
- }
9894
+ if (!ctx.isCancelling) ctx.logger.log(c.red("Cancelling test run. Press CTRL+c again to exit forcefully.\n")), process.exitCode = 130, await ctx.cancelCurrentRun("keyboard-input");
10539
9895
  return ctx.exit(true);
10540
9896
  }
10541
9897
  // window not support suspend
10542
9898
  if (!isWindows && key && key.ctrl && key.name === "z") {
10543
- process.kill(process.ppid, "SIGTSTP");
10544
- process.kill(process.pid, "SIGTSTP");
9899
+ process.kill(process.ppid, "SIGTSTP"), process.kill(process.pid, "SIGTSTP");
10545
9900
  return;
10546
9901
  }
10547
9902
  const name = key?.name;
@@ -10570,24 +9925,17 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10570
9925
  if (name === "t") return inputNamePattern();
10571
9926
  // change fileNamePattern
10572
9927
  if (name === "p") return inputFilePattern();
10573
- if (name === "b") {
10574
- await ctx._initBrowserServers();
10575
- ctx.projects.forEach((project) => {
10576
- ctx.logger.log();
10577
- ctx.logger.printBrowserBanner(project);
10578
- });
10579
- return null;
10580
- }
9928
+ if (name === "b") return await ctx._initBrowserServers(), ctx.projects.forEach((project) => {
9929
+ ctx.logger.log(), ctx.logger.printBrowserBanner(project);
9930
+ }), null;
10581
9931
  }
10582
9932
  async function keypressHandler(str, key) {
10583
9933
  await _keypressHandler(str, key);
10584
9934
  }
10585
9935
  async function inputNamePattern() {
10586
9936
  off();
10587
- const watchFilter = new WatchFilter("Input test name pattern (RegExp)", stdin, stdout);
10588
- const filter = await watchFilter.filter((str) => {
10589
- const files = ctx.state.getFiles();
10590
- const tests = getTests(files);
9937
+ const watchFilter = new WatchFilter("Input test name pattern (RegExp)", stdin, stdout), filter = await watchFilter.filter((str) => {
9938
+ const files = ctx.state.getFiles(), tests = getTests(files);
10591
9939
  try {
10592
9940
  const reg = new RegExp(str);
10593
9941
  return tests.map((test) => test.name).filter((testName) => testName.match(reg));
@@ -10596,11 +9944,8 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10596
9944
  return [];
10597
9945
  }
10598
9946
  });
10599
- on();
10600
- if (typeof filter === "undefined") return;
10601
- const files = ctx.state.getFilepaths();
10602
- // if running in standalone mode, Vitest instance doesn't know about any test file
10603
- const cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
9947
+ if (on(), typeof filter === "undefined") return;
9948
+ const files = ctx.state.getFilepaths(), cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
10604
9949
  await ctx.changeNamePattern(filter?.trim() || "", cliFiles, "change pattern");
10605
9950
  }
10606
9951
  async function inputProjectName() {
@@ -10611,41 +9956,31 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10611
9956
  message: "Input a single project name",
10612
9957
  initial: ctx.config.project[0] || ""
10613
9958
  }]);
10614
- on();
10615
- await ctx.changeProjectName(filter.trim());
9959
+ on(), await ctx.changeProjectName(filter.trim());
10616
9960
  }
10617
9961
  async function inputFilePattern() {
10618
9962
  off();
10619
- const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout);
10620
- const filter = await watchFilter.filter(async (str) => {
9963
+ const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout), filter = await watchFilter.filter(async (str) => {
10621
9964
  const files = await ctx.globTestFiles([str]);
10622
9965
  return files.map((file) => relative(ctx.config.root, file[1])).filter((file, index, all) => all.indexOf(file) === index);
10623
9966
  });
10624
- on();
10625
- if (typeof filter === "undefined") return;
9967
+ if (on(), typeof filter === "undefined") return;
10626
9968
  latestFilename = filter?.trim() || "";
10627
9969
  const lastResults = watchFilter.getLastResults();
10628
9970
  await ctx.changeFilenamePattern(latestFilename, filter && lastResults.length ? lastResults.map((i) => resolve(ctx.config.root, i)) : void 0);
10629
9971
  }
10630
9972
  let rl;
10631
9973
  function on() {
10632
- off();
10633
- rl = readline.createInterface({
9974
+ if (off(), rl = readline.createInterface({
10634
9975
  input: stdin,
10635
9976
  escapeCodeTimeout: 50
10636
- });
10637
- readline.emitKeypressEvents(stdin, rl);
10638
- if (stdin.isTTY) stdin.setRawMode(true);
9977
+ }), readline.emitKeypressEvents(stdin, rl), stdin.isTTY) stdin.setRawMode(true);
10639
9978
  stdin.on("keypress", keypressHandler);
10640
9979
  }
10641
9980
  function off() {
10642
- rl?.close();
10643
- rl = void 0;
10644
- stdin.removeListener("keypress", keypressHandler);
10645
- if (stdin.isTTY) stdin.setRawMode(false);
9981
+ if (rl?.close(), rl = void 0, stdin.removeListener("keypress", keypressHandler), stdin.isTTY) stdin.setRawMode(false);
10646
9982
  }
10647
- on();
10648
- return function cleanup() {
9983
+ return on(), function cleanup() {
10649
9984
  off();
10650
9985
  };
10651
9986
  }
@@ -10656,20 +9991,14 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
10656
9991
  * Returns a Vitest instance if initialized successfully.
10657
9992
  */
10658
9993
  async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
10659
- const root = resolve(options.root || process.cwd());
10660
- const ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
9994
+ const root = resolve(options.root || process.cwd()), ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
10661
9995
  if (mode === "test" && ctx.config.coverage.enabled) {
10662
- const provider = ctx.config.coverage.provider || "v8";
10663
- const requiredPackages = CoverageProviderMap[provider];
9996
+ const provider = ctx.config.coverage.provider || "v8", requiredPackages = CoverageProviderMap[provider];
10664
9997
  if (requiredPackages) {
10665
- if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root, ctx.version)) {
10666
- process.exitCode = 1;
10667
- return ctx;
10668
- }
9998
+ if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root, ctx.version)) return process.exitCode = 1, ctx;
10669
9999
  }
10670
10000
  }
10671
- const stdin = vitestOptions?.stdin || process.stdin;
10672
- const stdout = vitestOptions?.stdout || process.stdout;
10001
+ const stdin = vitestOptions?.stdin || process.stdin, stdout = vitestOptions?.stdout || process.stdout;
10673
10002
  let stdinCleanup;
10674
10003
  if (stdin.isTTY && ctx.config.watch) stdinCleanup = registerConsoleShortcuts(ctx, stdin, stdout);
10675
10004
  ctx.onAfterSetServer(() => {
@@ -10681,55 +10010,27 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
10681
10010
  else if (ctx.config.standalone) await ctx.init();
10682
10011
  else await ctx.start(cliFilters);
10683
10012
  } catch (e) {
10684
- if (e instanceof FilesNotFoundError) return ctx;
10685
- if (e instanceof GitNotFoundError) {
10686
- ctx.logger.error(e.message);
10687
- return ctx;
10688
- }
10689
- if (e instanceof IncludeTaskLocationDisabledError || e instanceof RangeLocationFilterProvidedError || e instanceof LocationFilterFileNotFoundError) {
10690
- ctx.logger.printError(e, { verbose: false });
10691
- return ctx;
10692
- }
10693
- process.exitCode = 1;
10694
- ctx.logger.printError(e, {
10013
+ return e instanceof FilesNotFoundError ? ctx : e instanceof GitNotFoundError ? (ctx.logger.error(e.message), ctx) : e instanceof IncludeTaskLocationDisabledError || e instanceof RangeLocationFilterProvidedError || e instanceof LocationFilterFileNotFoundError ? (ctx.logger.printError(e, { verbose: false }), ctx) : (process.exitCode = 1, ctx.logger.printError(e, {
10695
10014
  fullStack: true,
10696
10015
  type: "Unhandled Error"
10697
- });
10698
- ctx.logger.error("\n\n");
10699
- return ctx;
10016
+ }), ctx.logger.error("\n\n"), ctx);
10700
10017
  }
10701
- if (ctx.shouldKeepServer()) return ctx;
10702
- stdinCleanup?.();
10703
- await ctx.close();
10704
- return ctx;
10018
+ return ctx.shouldKeepServer() ? ctx : (stdinCleanup?.(), await ctx.close(), ctx);
10705
10019
  }
10706
10020
  async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions, cliFilters) {
10707
- process.env.TEST = "true";
10708
- process.env.VITEST = "true";
10709
- process.env.NODE_ENV ??= "test";
10710
- if (options.run) options.watch = false;
10021
+ if (process.env.TEST = "true", process.env.VITEST = "true", process.env.NODE_ENV ??= "test", options.run) options.watch = false;
10711
10022
  if (options.standalone && (cliFilters?.length || 0) > 0) options.standalone = false;
10712
10023
  // this shouldn't affect _application root_ that can be changed inside config
10713
- const root = resolve(options.root || process.cwd());
10714
- const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);
10715
- const environmentPackage = getEnvPackageName(ctx.config.environment);
10716
- if (environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root)) {
10717
- process.exitCode = 1;
10718
- return ctx;
10719
- }
10720
- return ctx;
10024
+ const root = resolve(options.root || process.cwd()), ctx = await createVitest(mode, options, viteOverrides, vitestOptions), environmentPackage = getEnvPackageName(ctx.config.environment);
10025
+ return environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root) && (process.exitCode = 1), ctx;
10721
10026
  }
10722
10027
  function processCollected(ctx, files, options) {
10723
10028
  let errorsPrinted = false;
10724
- forEachSuite(files, (suite) => {
10029
+ if (forEachSuite(files, (suite) => {
10725
10030
  suite.errors().forEach((error) => {
10726
- errorsPrinted = true;
10727
- ctx.logger.printError(error, { project: suite.project });
10031
+ errorsPrinted = true, ctx.logger.printError(error, { project: suite.project });
10728
10032
  });
10729
- });
10730
- if (errorsPrinted) return;
10731
- if (typeof options.json !== "undefined") return processJsonOutput(files, options);
10732
- return formatCollectedAsString(files).forEach((test) => console.log(test));
10033
+ }), !errorsPrinted) return typeof options.json === "undefined" ? formatCollectedAsString(files).forEach((test) => console.log(test)) : processJsonOutput(files, options);
10733
10034
  }
10734
10035
  function outputFileList(files, options) {
10735
10036
  if (typeof options.json !== "undefined") return outputJsonFileList(files, options);
@@ -10739,8 +10040,7 @@ function outputJsonFileList(files, options) {
10739
10040
  if (typeof options.json === "boolean") return console.log(JSON.stringify(formatFilesAsJSON(files), null, 2));
10740
10041
  if (typeof options.json === "string") {
10741
10042
  const jsonPath = resolve(options.root || process.cwd(), options.json);
10742
- mkdirSync(dirname(jsonPath), { recursive: true });
10743
- writeFileSync(jsonPath, JSON.stringify(formatFilesAsJSON(files), null, 2));
10043
+ mkdirSync(dirname(jsonPath), { recursive: true }), writeFileSync(jsonPath, JSON.stringify(formatFilesAsJSON(files), null, 2));
10744
10044
  }
10745
10045
  }
10746
10046
  function formatFilesAsJSON(files) {
@@ -10761,8 +10061,7 @@ function processJsonOutput(files, options) {
10761
10061
  if (typeof options.json === "boolean") return console.log(JSON.stringify(formatCollectedAsJSON(files), null, 2));
10762
10062
  if (typeof options.json === "string") {
10763
10063
  const jsonPath = resolve(options.root || process.cwd(), options.json);
10764
- mkdirSync(dirname(jsonPath), { recursive: true });
10765
- writeFileSync(jsonPath, JSON.stringify(formatCollectedAsJSON(files), null, 2));
10064
+ mkdirSync(dirname(jsonPath), { recursive: true }), writeFileSync(jsonPath, JSON.stringify(formatCollectedAsJSON(files), null, 2));
10766
10065
  }
10767
10066
  }
10768
10067
  function forEachSuite(modules, callback) {
@@ -10773,7 +10072,7 @@ function forEachSuite(modules, callback) {
10773
10072
  }
10774
10073
  function formatCollectedAsJSON(files) {
10775
10074
  const results = [];
10776
- files.forEach((file) => {
10075
+ return files.forEach((file) => {
10777
10076
  for (const test of file.children.allTests()) {
10778
10077
  if (test.result().state === "skipped") continue;
10779
10078
  const result = {
@@ -10784,19 +10083,17 @@ function formatCollectedAsJSON(files) {
10784
10083
  if (test.location) result.location = test.location;
10785
10084
  results.push(result);
10786
10085
  }
10787
- });
10788
- return results;
10086
+ }), results;
10789
10087
  }
10790
10088
  function formatCollectedAsString(testModules) {
10791
10089
  const results = [];
10792
- testModules.forEach((testModule) => {
10090
+ return testModules.forEach((testModule) => {
10793
10091
  for (const test of testModule.children.allTests()) {
10794
10092
  if (test.result().state === "skipped") continue;
10795
10093
  const fullName = `${test.module.task.name} > ${test.fullName}`;
10796
10094
  results.push((test.project.name ? `[${test.project.name}] ` : "") + fullName);
10797
10095
  }
10798
- });
10799
- return results;
10096
+ }), results;
10800
10097
  }
10801
10098
  const envPackageNames = {
10802
10099
  "jsdom": "jsdom",
@@ -10804,10 +10101,7 @@ const envPackageNames = {
10804
10101
  "edge-runtime": "@edge-runtime/vm"
10805
10102
  };
10806
10103
  function getEnvPackageName(env) {
10807
- if (env === "node") return null;
10808
- if (env in envPackageNames) return envPackageNames[env];
10809
- if (env[0] === "." || isAbsolute(env)) return null;
10810
- return `vitest-environment-${env}`;
10104
+ return env === "node" ? null : env in envPackageNames ? envPackageNames[env] : env[0] === "." || isAbsolute(env) ? null : `vitest-environment-${env}`;
10811
10105
  }
10812
10106
 
10813
10107
  var cliApi = /*#__PURE__*/Object.freeze({