vitest 0.22.0 → 0.23.1

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 (49) hide show
  1. package/LICENSE.md +29 -29
  2. package/dist/browser.d.ts +5 -4
  3. package/dist/browser.mjs +12 -9
  4. package/dist/{chunk-api-setup.ecd02c18.mjs → chunk-api-setup.9e83ca0a.mjs} +92 -90
  5. package/dist/chunk-constants.6196597b.mjs +284 -0
  6. package/dist/{chunk-integrations-coverage.d205bd87.mjs → chunk-env-node.ceb43f1c.mjs} +31 -179
  7. package/dist/{chunk-install-pkg.3aa3eae6.mjs → chunk-install-pkg.e081fc1b.mjs} +3 -3
  8. package/dist/chunk-integrations-coverage.99c020eb.mjs +166 -0
  9. package/dist/chunk-integrations-globals.b1aa52c3.mjs +25 -0
  10. package/dist/{chunk-magic-string.efe26975.mjs → chunk-magic-string.56b2b543.mjs} +30 -10
  11. package/dist/{chunk-mock-date.debe9954.mjs → chunk-mock-date.f63a5ff2.mjs} +31 -193
  12. package/dist/{chunk-node-git.71b74da4.mjs → chunk-node-git.6f289b0a.mjs} +20 -16
  13. package/dist/{chunk-runtime-chain.6e363ba2.mjs → chunk-runtime-chain.8bfc559b.mjs} +507 -173
  14. package/dist/{chunk-runtime-error.975bd80a.mjs → chunk-runtime-error.252dd130.mjs} +206 -75
  15. package/dist/{chunk-runtime-hooks.4789e99d.mjs → chunk-runtime-hooks.c6b06bd8.mjs} +18 -12
  16. package/dist/{chunk-runtime-mocker.c91d29ce.mjs → chunk-runtime-mocker.d9690273.mjs} +19 -12
  17. package/dist/{chunk-runtime-rpc.29488183.mjs → chunk-runtime-rpc.48bd94e3.mjs} +1 -2
  18. package/dist/{chunk-utils-source-map.2a082ffd.mjs → chunk-utils-source-map.a1647f5f.mjs} +11 -5
  19. package/dist/{chunk-vite-node-client.d1ead698.mjs → chunk-vite-node-client.998e04d0.mjs} +92 -31
  20. package/dist/{chunk-vite-node-debug.ff1d2a9f.mjs → chunk-vite-node-debug.2d8a1dc3.mjs} +3 -4
  21. package/dist/{chunk-vite-node-externalize.3a38c8af.mjs → chunk-vite-node-externalize.3035bd5b.mjs} +515 -211
  22. package/dist/{chunk-vite-node-utils.d8e5ff7b.mjs → chunk-vite-node-utils.8a9b3014.mjs} +39 -41
  23. package/dist/cli-wrapper.mjs +54 -33
  24. package/dist/cli.mjs +31 -20
  25. package/dist/config.cjs +2 -2
  26. package/dist/config.d.ts +4 -3
  27. package/dist/config.mjs +2 -2
  28. package/dist/entry.mjs +20 -14
  29. package/dist/environments.d.ts +23 -0
  30. package/dist/environments.mjs +3 -0
  31. package/dist/{global-74489cc9.d.ts → global-ea084c9f.d.ts} +154 -24
  32. package/dist/{index-9eded9ec.d.ts → index-5f09f4d0.d.ts} +3 -2
  33. package/dist/index.d.ts +6 -5
  34. package/dist/index.mjs +7 -7
  35. package/dist/loader.mjs +5 -6
  36. package/dist/node.d.ts +5 -4
  37. package/dist/node.mjs +17 -16
  38. package/dist/suite.mjs +6 -6
  39. package/dist/vendor-index.0557b03a.mjs +147 -0
  40. package/dist/{vendor-index.9d9196cc.mjs → vendor-index.13e3bda3.mjs} +0 -0
  41. package/dist/{vendor-index.fbec8a81.mjs → vendor-index.4aeeb598.mjs} +2 -2
  42. package/dist/{vendor-index.2ae8040a.mjs → vendor-index.62ce5c33.mjs} +0 -0
  43. package/dist/{vendor-index.29636037.mjs → vendor-index.731a22f2.mjs} +0 -0
  44. package/dist/worker.mjs +20 -19
  45. package/package.json +18 -11
  46. package/dist/chunk-constants.d3f8437b.mjs +0 -38
  47. package/dist/chunk-integrations-globals.e81d2091.mjs +0 -27
  48. package/dist/chunk-utils-global.fa20c2f6.mjs +0 -5
  49. package/dist/vendor-picocolors.807856aa.mjs +0 -64
@@ -1,34 +1,35 @@
1
- import { x as resolve, j as join, y as basename, d as dirname, A as AggregateErrorPonyfill, z as isAbsolute, B as relative, s as slash$2, l as isNode, o as relativePath, C as getTests, e as getFullName, w as hasFailed, D as hasFailedSnapshot, E as getSuites, u as shuffle, t as toArray$1, F as normalize, n as noop$1, G as deepMerge, H as toNamespacedPath, g as getCallLastIndex, f as notNullish, I as ensurePackageInstalled, J as stdout } from './chunk-mock-date.debe9954.mjs';
2
- import { p as pLimit, g as getCoverageProvider, a as envPackageNames, C as CoverageProviderMap } from './chunk-integrations-coverage.d205bd87.mjs';
3
- import { loadConfigFromFile, createServer, mergeConfig } from 'vite';
1
+ import { a as resolve, j as join, b as basename, d as dirname, c as distDir, e as rootDir, p as picocolors, i as isAbsolute, r as relative, f as configFiles, g as defaultPort, n as normalize, t as toNamespacedPath, E as EXIT_CODE_RESTART } from './chunk-constants.6196597b.mjs';
2
+ import { p as pLimit, g as getCoverageProvider, C as CoverageProviderMap } from './chunk-integrations-coverage.99c020eb.mjs';
3
+ import { g as getEnvPackageName } from './chunk-env-node.ceb43f1c.mjs';
4
+ import { A as AggregateErrorPonyfill, s as slash$2, o as isNode, p as relativePath, z as getTests, e as getFullName, x as hasFailed, B as hasFailedSnapshot, C as getSuites, j as notNullish, v as shuffle, t as toArray$1, n as noop$1, D as deepMerge, b as getCallLastIndex, E as ensurePackageInstalled, F as stdout } from './chunk-mock-date.f63a5ff2.mjs';
5
+ import { loadConfigFromFile, normalizePath, createServer, mergeConfig } from 'vite';
4
6
  import path$a from 'path';
5
7
  import url, { fileURLToPath } from 'url';
6
8
  import process$1 from 'process';
7
9
  import fs$8, { promises, existsSync, readFileSync } from 'fs';
8
- import { d as distDir, r as rootDir, c as configFiles, a as defaultPort } from './chunk-constants.d3f8437b.mjs';
9
10
  import require$$0, { cpus, hostname } from 'os';
10
11
  import util$2 from 'util';
11
12
  import require$$0$1 from 'stream';
12
13
  import require$$2 from 'events';
13
14
  import { c as commonjsGlobal } from './vendor-_commonjsHelpers.4da45ef5.mjs';
14
- import { p as picocolors } from './vendor-picocolors.807856aa.mjs';
15
- import { c as createBirpc, V as ViteNodeRunner } from './chunk-vite-node-client.d1ead698.mjs';
15
+ import { c as createBirpc, V as ViteNodeRunner } from './chunk-vite-node-client.998e04d0.mjs';
16
+ import { performance } from 'perf_hooks';
16
17
  import createDebug from 'debug';
17
- import { i as isNodeBuiltin, a as isValidNodeImport, s as slash$1, t as toArray, b as toFilePath, w as withInlineSourcemap } from './chunk-vite-node-utils.d8e5ff7b.mjs';
18
+ import { i as isNodeBuiltin, a as isValidNodeImport, s as slash$1, t as toArray, b as toFilePath, w as withInlineSourcemap } from './chunk-vite-node-utils.8a9b3014.mjs';
18
19
  import { MessageChannel } from 'worker_threads';
19
20
  import { Tinypool } from 'tinypool';
20
- import { performance } from 'perf_hooks';
21
- import { c as stripAnsi, d as cliTruncate, p as parseStacktrace, e as stringWidth, h as ansiStyles, i as sliceAnsi, j as interpretSourcePos, s as stringify$5, u as unifiedDiff, b as posToNumber, l as lineSplitRE } from './chunk-utils-source-map.2a082ffd.mjs';
21
+ import { c as stripAnsi, d as cliTruncate, p as parseStacktrace, i as interpretSourcePos, e as stringWidth, h as ansiStyles, j as sliceAnsi, s as stringify$5, u as unifiedDiff, b as posToNumber, l as lineSplitRE } from './chunk-utils-source-map.a1647f5f.mjs';
22
22
  import { b as safeSetInterval, c as safeClearInterval, s as safeSetTimeout, a as safeClearTimeout } from './chunk-utils-timers.b48455ed.mjs';
23
23
  import { resolveModule } from 'local-pkg';
24
24
  import { createHash } from 'crypto';
25
- import { o as onetime } from './vendor-index.9d9196cc.mjs';
26
- import { s as signalExit } from './vendor-index.29636037.mjs';
27
- import MagicString from './chunk-magic-string.efe26975.mjs';
25
+ import { o as onetime } from './vendor-index.13e3bda3.mjs';
26
+ import { s as signalExit } from './vendor-index.731a22f2.mjs';
27
+ import MagicString from './chunk-magic-string.56b2b543.mjs';
28
+ import { stripLiteral } from 'strip-literal';
28
29
  import require$$0$2 from 'readline';
29
30
  import { p as prompts } from './vendor-index.ae96af6e.mjs';
30
31
 
31
- var version$1 = "0.22.0";
32
+ var version$1 = "0.23.1";
32
33
 
33
34
  class EndError extends Error {
34
35
  constructor(value) {
@@ -83,14 +84,14 @@ const typeMappings = {
83
84
  };
84
85
 
85
86
  function checkType(type) {
86
- if (type in typeMappings) {
87
+ if (Object.hasOwnProperty.call(typeMappings, type)) {
87
88
  return;
88
89
  }
89
90
 
90
91
  throw new Error(`Invalid type specified: ${type}`);
91
92
  }
92
93
 
93
- const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
94
+ const matchType = (type, stat) => stat[typeMappings[type]]();
94
95
 
95
96
  const toPath$1 = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
96
97
 
@@ -6852,7 +6853,7 @@ class ViteNodeServer {
6852
6853
  }, options.debug ?? {});
6853
6854
  }
6854
6855
  if (options.debug)
6855
- import('./chunk-vite-node-debug.ff1d2a9f.mjs').then((r) => this.debugger = new r.Debugger(server.config.root, options.debug));
6856
+ import('./chunk-vite-node-debug.2d8a1dc3.mjs').then((r) => this.debugger = new r.Debugger(server.config.root, options.debug));
6856
6857
  }
6857
6858
  shouldExternalize(id) {
6858
6859
  return shouldExternalize(id, this.options.deps, this.externalizeCache);
@@ -6865,19 +6866,25 @@ class ViteNodeServer {
6865
6866
  }
6866
6867
  async fetchModule(id) {
6867
6868
  if (!this.fetchPromiseMap.has(id)) {
6868
- this.fetchPromiseMap.set(id, this._fetchModule(id).then((r) => {
6869
- return this.options.sourcemap !== true ? { ...r, map: void 0 } : r;
6870
- }).finally(() => {
6871
- this.fetchPromiseMap.delete(id);
6872
- }));
6869
+ this.fetchPromiseMap.set(
6870
+ id,
6871
+ this._fetchModule(id).then((r) => {
6872
+ return this.options.sourcemap !== true ? { ...r, map: void 0 } : r;
6873
+ }).finally(() => {
6874
+ this.fetchPromiseMap.delete(id);
6875
+ })
6876
+ );
6873
6877
  }
6874
6878
  return this.fetchPromiseMap.get(id);
6875
6879
  }
6876
6880
  async transformRequest(id) {
6877
6881
  if (!this.transformPromiseMap.has(id)) {
6878
- this.transformPromiseMap.set(id, this._transformRequest(id).finally(() => {
6879
- this.transformPromiseMap.delete(id);
6880
- }));
6882
+ this.transformPromiseMap.set(
6883
+ id,
6884
+ this._transformRequest(id).finally(() => {
6885
+ this.transformPromiseMap.delete(id);
6886
+ })
6887
+ );
6881
6888
  }
6882
6889
  return this.transformPromiseMap.get(id);
6883
6890
  }
@@ -6902,14 +6909,18 @@ class ViteNodeServer {
6902
6909
  if (timestamp && cache && cache.timestamp >= timestamp)
6903
6910
  return cache.result;
6904
6911
  const externalize = await this.shouldExternalize(filePath);
6912
+ let duration;
6905
6913
  if (externalize) {
6906
6914
  result = { externalize };
6907
6915
  (_a = this.debugger) == null ? void 0 : _a.recordExternalize(id, externalize);
6908
6916
  } else {
6917
+ const start = performance.now();
6909
6918
  const r = await this._transformRequest(id);
6919
+ duration = performance.now() - start;
6910
6920
  result = { code: r == null ? void 0 : r.code, map: r == null ? void 0 : r.map };
6911
6921
  }
6912
6922
  this.fetchCache.set(filePath, {
6923
+ duration,
6913
6924
  timestamp,
6914
6925
  result
6915
6926
  });
@@ -6955,7 +6966,13 @@ class SnapshotManager {
6955
6966
  }
6956
6967
  resolvePath(testPath) {
6957
6968
  const resolver = this.options.resolveSnapshotPath || (() => {
6958
- return join(join(dirname(testPath), "__snapshots__"), `${basename(testPath)}${this.extension}`);
6969
+ return join(
6970
+ join(
6971
+ dirname(testPath),
6972
+ "__snapshots__"
6973
+ ),
6974
+ `${basename(testPath)}${this.extension}`
6975
+ );
6959
6976
  });
6960
6977
  return resolver(testPath, this.extension);
6961
6978
  }
@@ -7010,7 +7027,7 @@ function createPool(ctx) {
7010
7027
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(cpus().length / 2), 1) : Math.max(cpus().length - 1, 1);
7011
7028
  const maxThreads = ctx.config.maxThreads ?? threadsCount;
7012
7029
  const minThreads = ctx.config.minThreads ?? threadsCount;
7013
- const conditions = (_a = ctx.server.config.resolve.conditions) == null ? void 0 : _a.flatMap((c) => ["-C", c]);
7030
+ const conditions = ((_a = ctx.server.config.resolve.conditions) == null ? void 0 : _a.flatMap((c) => ["-C", c])) || [];
7014
7031
  const options = {
7015
7032
  filename: workerPath,
7016
7033
  useAtomics: false,
@@ -7021,8 +7038,8 @@ function createPool(ctx) {
7021
7038
  suppressLoaderWarningsPath,
7022
7039
  "--experimental-loader",
7023
7040
  loaderPath,
7024
- ...conditions || []
7025
- ] : []
7041
+ ...conditions
7042
+ ] : conditions
7026
7043
  };
7027
7044
  if (ctx.config.isolate) {
7028
7045
  options.isolateWorkers = true;
@@ -7090,65 +7107,68 @@ function createChannel(ctx) {
7090
7107
  const channel = new MessageChannel();
7091
7108
  const port = channel.port2;
7092
7109
  const workerPort = channel.port1;
7093
- createBirpc({
7094
- onWorkerExit(code) {
7095
- process.exit(code || 1);
7096
- },
7097
- snapshotSaved(snapshot) {
7098
- ctx.snapshot.add(snapshot);
7099
- },
7100
- resolveSnapshotPath(testPath) {
7101
- return ctx.snapshot.resolvePath(testPath);
7102
- },
7103
- async getSourceMap(id, force) {
7104
- if (force) {
7105
- const mod = ctx.server.moduleGraph.getModuleById(id);
7106
- if (mod)
7107
- ctx.server.moduleGraph.invalidateModule(mod);
7108
- }
7109
- const r = await ctx.vitenode.transformRequest(id);
7110
- return r == null ? void 0 : r.map;
7111
- },
7112
- fetch(id) {
7113
- return ctx.vitenode.fetchModule(id);
7114
- },
7115
- resolveId(id, importer) {
7116
- return ctx.vitenode.resolveId(id, importer);
7117
- },
7118
- onPathsCollected(paths) {
7119
- ctx.state.collectPaths(paths);
7120
- ctx.report("onPathsCollected", paths);
7121
- },
7122
- onCollected(files) {
7123
- ctx.state.collectFiles(files);
7124
- ctx.report("onCollected", files);
7125
- },
7126
- onAfterSuiteRun(meta) {
7127
- var _a;
7128
- (_a = ctx.coverageProvider) == null ? void 0 : _a.onAfterSuiteRun(meta);
7129
- },
7130
- onTaskUpdate(packs) {
7131
- ctx.state.updateTasks(packs);
7132
- ctx.report("onTaskUpdate", packs);
7133
- },
7134
- onUserConsoleLog(log) {
7135
- ctx.state.updateUserLog(log);
7136
- ctx.report("onUserConsoleLog", log);
7137
- },
7138
- onUnhandledRejection(err) {
7139
- ctx.state.catchError(err, "Unhandled Rejection");
7140
- },
7141
- onFinished(files) {
7142
- ctx.report("onFinished", files, ctx.state.getUnhandledErrors());
7143
- }
7144
- }, {
7145
- post(v) {
7146
- port.postMessage(v);
7110
+ createBirpc(
7111
+ {
7112
+ onWorkerExit(code) {
7113
+ process.exit(code || 1);
7114
+ },
7115
+ snapshotSaved(snapshot) {
7116
+ ctx.snapshot.add(snapshot);
7117
+ },
7118
+ resolveSnapshotPath(testPath) {
7119
+ return ctx.snapshot.resolvePath(testPath);
7120
+ },
7121
+ async getSourceMap(id, force) {
7122
+ if (force) {
7123
+ const mod = ctx.server.moduleGraph.getModuleById(id);
7124
+ if (mod)
7125
+ ctx.server.moduleGraph.invalidateModule(mod);
7126
+ }
7127
+ const r = await ctx.vitenode.transformRequest(id);
7128
+ return r == null ? void 0 : r.map;
7129
+ },
7130
+ fetch(id) {
7131
+ return ctx.vitenode.fetchModule(id);
7132
+ },
7133
+ resolveId(id, importer) {
7134
+ return ctx.vitenode.resolveId(id, importer);
7135
+ },
7136
+ onPathsCollected(paths) {
7137
+ ctx.state.collectPaths(paths);
7138
+ ctx.report("onPathsCollected", paths);
7139
+ },
7140
+ onCollected(files) {
7141
+ ctx.state.collectFiles(files);
7142
+ ctx.report("onCollected", files);
7143
+ },
7144
+ onAfterSuiteRun(meta) {
7145
+ var _a;
7146
+ (_a = ctx.coverageProvider) == null ? void 0 : _a.onAfterSuiteRun(meta);
7147
+ },
7148
+ onTaskUpdate(packs) {
7149
+ ctx.state.updateTasks(packs);
7150
+ ctx.report("onTaskUpdate", packs);
7151
+ },
7152
+ onUserConsoleLog(log) {
7153
+ ctx.state.updateUserLog(log);
7154
+ ctx.report("onUserConsoleLog", log);
7155
+ },
7156
+ onUnhandledRejection(err) {
7157
+ ctx.state.catchError(err, "Unhandled Rejection");
7158
+ },
7159
+ onFinished(files) {
7160
+ ctx.report("onFinished", files, ctx.state.getUnhandledErrors());
7161
+ }
7147
7162
  },
7148
- on(fn) {
7149
- port.on("message", fn);
7163
+ {
7164
+ post(v) {
7165
+ port.postMessage(v);
7166
+ },
7167
+ on(fn) {
7168
+ port.on("message", fn);
7169
+ }
7150
7170
  }
7151
- });
7171
+ );
7152
7172
  return { workerPort, port };
7153
7173
  }
7154
7174
 
@@ -7265,8 +7285,9 @@ function getStateSymbol(task) {
7265
7285
  }
7266
7286
  return picocolors.exports.yellow(spinner());
7267
7287
  }
7268
- if (task.result.state === "pass")
7269
- return picocolors.exports.green(F_CHECK);
7288
+ if (task.result.state === "pass") {
7289
+ return task.type === "benchmark" ? picocolors.exports.green(F_DOT) : picocolors.exports.green(F_CHECK);
7290
+ }
7270
7291
  if (task.result.state === "fail") {
7271
7292
  return task.type === "suite" ? pointer : picocolors.exports.red(F_CROSS);
7272
7293
  }
@@ -7400,13 +7421,16 @@ class BaseReporter {
7400
7421
  ];
7401
7422
  this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]);
7402
7423
  this._lastRunTimeout = 0;
7403
- this._lastRunTimer = safeSetInterval(() => {
7404
- this._lastRunTimeout += 1;
7405
- if (this._lastRunTimeout >= LAST_RUN_TEXTS.length)
7406
- this.resetLastRunLog();
7407
- else
7408
- this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]);
7409
- }, LAST_RUN_LOG_TIMEOUT / LAST_RUN_TEXTS.length);
7424
+ this._lastRunTimer = safeSetInterval(
7425
+ () => {
7426
+ this._lastRunTimeout += 1;
7427
+ if (this._lastRunTimeout >= LAST_RUN_TEXTS.length)
7428
+ this.resetLastRunLog();
7429
+ else
7430
+ this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]);
7431
+ },
7432
+ LAST_RUN_LOG_TIMEOUT / LAST_RUN_TEXTS.length
7433
+ );
7410
7434
  }
7411
7435
  }
7412
7436
  resetLastRunLog() {
@@ -7455,8 +7479,10 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7455
7479
  return shouldIgnore;
7456
7480
  return true;
7457
7481
  }
7458
- onServerRestart() {
7459
- this.ctx.logger.log(picocolors.exports.cyan("Restarted due to config changes..."));
7482
+ onServerRestart(reason) {
7483
+ this.ctx.logger.log(picocolors.exports.bold(picocolors.exports.magenta(
7484
+ reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest..."
7485
+ )));
7460
7486
  }
7461
7487
  async reportSummary(files) {
7462
7488
  const logger = this.ctx.logger;
@@ -7491,6 +7517,7 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7491
7517
  var _a2;
7492
7518
  return acc + Math.max(0, ((_a2 = test.result) == null ? void 0 : _a2.duration) || 0);
7493
7519
  }, 0);
7520
+ const transformTime = Array.from(this.ctx.vitenode.fetchCache.values()).reduce((a, b) => a + ((b == null ? void 0 : b.duration) || 0), 0);
7494
7521
  const threadTime = collectTime + testsTime + setupTime;
7495
7522
  const padTitle = (str) => picocolors.exports.dim(`${str.padStart(10)} `);
7496
7523
  const time = (time2) => {
@@ -7500,7 +7527,9 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7500
7527
  };
7501
7528
  const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
7502
7529
  if (snapshotOutput.length) {
7503
- logger.log(snapshotOutput.map((t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`).join("\n"));
7530
+ logger.log(snapshotOutput.map(
7531
+ (t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`
7532
+ ).join("\n"));
7504
7533
  if (snapshotOutput.length > 1)
7505
7534
  logger.log();
7506
7535
  }
@@ -7510,7 +7539,7 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7510
7539
  if (this.watchFilters)
7511
7540
  logger.log(padTitle("Duration"), time(threadTime));
7512
7541
  else
7513
- logger.log(padTitle("Duration"), time(executionTime) + picocolors.exports.gray(` (setup ${time(setupTime)}, collect ${time(collectTime)}, tests ${time(testsTime)})`));
7542
+ logger.log(padTitle("Duration"), time(executionTime) + picocolors.exports.dim(` (transform ${time(transformTime)}, setup ${time(setupTime)}, collect ${time(collectTime)}, tests ${time(testsTime)})`));
7514
7543
  logger.log();
7515
7544
  }
7516
7545
  async printTaskErrors(tasks, errorDivider) {
@@ -7561,6 +7590,10 @@ function formatFilepath(path) {
7561
7590
  firstDot += lastSlash;
7562
7591
  return picocolors.exports.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + picocolors.exports.dim(path.slice(firstDot));
7563
7592
  }
7593
+ function formatNumber(number) {
7594
+ const res = String(number.toFixed(number < 100 ? 4 : 2)).split(".");
7595
+ return res[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ",") + (res[1] ? `.${res[1]}` : "");
7596
+ }
7564
7597
  function renderHookState(task, hookName, level = 0) {
7565
7598
  var _a, _b;
7566
7599
  const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
@@ -7568,27 +7601,65 @@ function renderHookState(task, hookName, level = 0) {
7568
7601
  return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${picocolors.exports.dim(`[ ${hookName} ]`)}`;
7569
7602
  return "";
7570
7603
  }
7604
+ function renderBenchmarkItems(result) {
7605
+ return [
7606
+ result.name,
7607
+ formatNumber(result.hz || 0),
7608
+ formatNumber(result.p99 || 0),
7609
+ `\xB1${result.rme.toFixed(2)}%`,
7610
+ result.samples.length.toString()
7611
+ ];
7612
+ }
7613
+ function renderBenchmark(task, tasks) {
7614
+ var _a;
7615
+ const result = (_a = task.result) == null ? void 0 : _a.benchmark;
7616
+ if (!result)
7617
+ return task.name;
7618
+ const benchs = tasks.map((i) => {
7619
+ var _a2;
7620
+ return i.type === "benchmark" ? (_a2 = i.result) == null ? void 0 : _a2.benchmark : void 0;
7621
+ }).filter(notNullish);
7622
+ const allItems = benchs.map(renderBenchmarkItems);
7623
+ const items = renderBenchmarkItems(result);
7624
+ const padded = items.map((i, idx) => {
7625
+ const width = Math.max(...allItems.map((i2) => i2[idx].length));
7626
+ return idx ? i.padStart(width, " ") : i.padEnd(width, " ");
7627
+ });
7628
+ return [
7629
+ padded[0],
7630
+ picocolors.exports.dim(" "),
7631
+ picocolors.exports.blue(padded[1]),
7632
+ picocolors.exports.dim(" ops/sec "),
7633
+ picocolors.exports.cyan(padded[3]),
7634
+ picocolors.exports.dim(` (${padded[4]} samples)`),
7635
+ result.rank === 1 ? picocolors.exports.bold(picocolors.exports.green(" fastest")) : result.rank === benchs.length && benchs.length > 2 ? picocolors.exports.bold(picocolors.exports.gray(" slowest")) : ""
7636
+ ].join("");
7637
+ }
7571
7638
  function renderTree(tasks, options, level = 0) {
7572
- var _a, _b, _c, _d, _e;
7639
+ var _a, _b, _c, _d, _e, _f;
7573
7640
  let output = [];
7574
7641
  for (const task of tasks) {
7575
7642
  let suffix = "";
7576
7643
  const prefix = ` ${getStateSymbol(task)} `;
7644
+ if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.retryCount) && task.result.retryCount > 1)
7645
+ suffix += picocolors.exports.yellow(` (retry x${task.result.retryCount})`);
7577
7646
  if (task.type === "suite")
7578
7647
  suffix += picocolors.exports.dim(` (${getTests(task).length})`);
7579
7648
  if (task.mode === "skip" || task.mode === "todo")
7580
7649
  suffix += ` ${picocolors.exports.dim(picocolors.exports.gray("[skipped]"))}`;
7581
- if (((_a = task.result) == null ? void 0 : _a.duration) != null) {
7650
+ if (((_b = task.result) == null ? void 0 : _b.duration) != null) {
7582
7651
  if (task.result.duration > DURATION_LONG)
7583
7652
  suffix += picocolors.exports.yellow(` ${Math.round(task.result.duration)}${picocolors.exports.dim("ms")}`);
7584
7653
  }
7585
- if (options.showHeap && ((_b = task.result) == null ? void 0 : _b.heap) != null)
7654
+ if (options.showHeap && ((_c = task.result) == null ? void 0 : _c.heap) != null)
7586
7655
  suffix += picocolors.exports.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
7587
7656
  let name = task.name;
7588
7657
  if (level === 0)
7589
7658
  name = formatFilepath(name);
7590
- output.push(" ".repeat(level) + prefix + name + suffix);
7591
- if (((_c = task.result) == null ? void 0 : _c.state) !== "pass" && outputMap.get(task) != null) {
7659
+ const padding = " ".repeat(level);
7660
+ const body = task.type === "benchmark" ? renderBenchmark(task, tasks) : name;
7661
+ output.push(padding + prefix + body + suffix);
7662
+ if (((_d = task.result) == null ? void 0 : _d.state) !== "pass" && outputMap.get(task) != null) {
7592
7663
  let data = outputMap.get(task);
7593
7664
  if (typeof data === "string") {
7594
7665
  data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
@@ -7603,7 +7674,7 @@ function renderTree(tasks, options, level = 0) {
7603
7674
  output = output.concat(renderHookState(task, "beforeAll", level + 1));
7604
7675
  output = output.concat(renderHookState(task, "beforeEach", level + 1));
7605
7676
  if (task.type === "suite" && task.tasks.length > 0) {
7606
- if (((_d = task.result) == null ? void 0 : _d.state) === "fail" || ((_e = task.result) == null ? void 0 : _e.state) === "run" || options.renderSucceed)
7677
+ if (((_e = task.result) == null ? void 0 : _e.state) === "fail" || ((_f = task.result) == null ? void 0 : _f.state) === "run" || options.renderSucceed)
7607
7678
  output = output.concat(renderTree(task.tasks, options, level + 1));
7608
7679
  }
7609
7680
  output = output.concat(renderHookState(task, "afterAll", level + 1));
@@ -7804,7 +7875,7 @@ const StatusMap = {
7804
7875
  skip: "skipped",
7805
7876
  todo: "todo"
7806
7877
  };
7807
- class JsonReporter {
7878
+ class JsonReporter$1 {
7808
7879
  constructor() {
7809
7880
  this.start = 0;
7810
7881
  }
@@ -7851,7 +7922,7 @@ class JsonReporter {
7851
7922
  var _a2, _b2;
7852
7923
  return Math.max(prev, (((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? 0) + (((_b2 = next.result) == null ? void 0 : _b2.duration) ?? 0));
7853
7924
  }, startTime);
7854
- const assertionResults = tests2.map((t) => {
7925
+ const assertionResults = await Promise.all(tests2.map(async (t) => {
7855
7926
  var _a2, _b2, _c, _d;
7856
7927
  const ancestorTitles = [];
7857
7928
  let iter = t.suite;
@@ -7867,9 +7938,9 @@ class JsonReporter {
7867
7938
  title: t.name,
7868
7939
  duration: (_b2 = t.result) == null ? void 0 : _b2.duration,
7869
7940
  failureMessages: ((_d = (_c = t.result) == null ? void 0 : _c.error) == null ? void 0 : _d.message) == null ? [] : [t.result.error.message],
7870
- location: this.getFailureLocation(t)
7941
+ location: await this.getFailureLocation(t)
7871
7942
  };
7872
- });
7943
+ }));
7873
7944
  if (tests2.some((t) => {
7874
7945
  var _a2;
7875
7946
  return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
@@ -7920,12 +7991,13 @@ class JsonReporter {
7920
7991
  this.ctx.logger.log(report);
7921
7992
  }
7922
7993
  }
7923
- getFailureLocation(test) {
7994
+ async getFailureLocation(test) {
7924
7995
  var _a;
7925
7996
  const error = (_a = test.result) == null ? void 0 : _a.error;
7926
7997
  if (!error)
7927
7998
  return;
7928
7999
  const stack = parseStacktrace(error);
8000
+ await interpretSourcePos(stack, this.ctx);
7929
8001
  const frame = stack[stack.length - 1];
7930
8002
  if (!frame)
7931
8003
  return;
@@ -8060,13 +8132,19 @@ function removeInvalidXMLCharacters(value, removeDiscouragedChars) {
8060
8132
  let regex = /((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/g;
8061
8133
  value = String(value || "").replace(regex, "");
8062
8134
  if (removeDiscouragedChars) {
8063
- regex = new RegExp("([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDFFE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uDFFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))", "g");
8135
+ regex = new RegExp(
8136
+ "([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDFFE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uDFFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))",
8137
+ "g"
8138
+ );
8064
8139
  value = value.replace(regex, "");
8065
8140
  }
8066
8141
  return value;
8067
8142
  }
8068
8143
  function escapeXML(value) {
8069
- return removeInvalidXMLCharacters(String(value).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&apos;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), true);
8144
+ return removeInvalidXMLCharacters(
8145
+ String(value).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&apos;").replace(/</g, "&lt;").replace(/>/g, "&gt;"),
8146
+ true
8147
+ );
8070
8148
  }
8071
8149
  function getDuration(task) {
8072
8150
  var _a;
@@ -8106,7 +8184,8 @@ class JUnitReporter {
8106
8184
  }
8107
8185
  async writeErrorDetails(error) {
8108
8186
  const errorName = error.name ?? error.nameStr ?? "Unknown Error";
8109
- await this.baseLog(`${errorName}: ${error.message}`);
8187
+ const errorDetails = `${errorName}: ${error.message}`;
8188
+ await this.baseLog(escapeXML(errorDetails));
8110
8189
  const stack = parseStacktrace(error);
8111
8190
  for (const frame of stack) {
8112
8191
  const pos = frame.sourcePos ?? frame;
@@ -8158,18 +8237,21 @@ class JUnitReporter {
8158
8237
  await this.logger.log('<?xml version="1.0" encoding="UTF-8" ?>');
8159
8238
  const transformed = files.map((file) => {
8160
8239
  const tasks = file.tasks.flatMap((task) => flattenTasks$1(task));
8161
- const stats = tasks.reduce((stats2, task) => {
8162
- var _a, _b;
8163
- return {
8164
- passed: stats2.passed + Number(((_a = task.result) == null ? void 0 : _a.state) === "pass"),
8165
- failures: stats2.failures + Number(((_b = task.result) == null ? void 0 : _b.state) === "fail"),
8166
- skipped: stats2.skipped + Number(task.mode === "skip" || task.mode === "todo")
8167
- };
8168
- }, {
8169
- passed: 0,
8170
- failures: 0,
8171
- skipped: 0
8172
- });
8240
+ const stats = tasks.reduce(
8241
+ (stats2, task) => {
8242
+ var _a, _b;
8243
+ return {
8244
+ passed: stats2.passed + Number(((_a = task.result) == null ? void 0 : _a.state) === "pass"),
8245
+ failures: stats2.failures + Number(((_b = task.result) == null ? void 0 : _b.state) === "fail"),
8246
+ skipped: stats2.skipped + Number(task.mode === "skip" || task.mode === "todo")
8247
+ };
8248
+ },
8249
+ {
8250
+ passed: 0,
8251
+ failures: 0,
8252
+ skipped: 0
8253
+ }
8254
+ );
8173
8255
  return {
8174
8256
  ...file,
8175
8257
  tasks,
@@ -8219,11 +8301,70 @@ class TapFlatReporter extends TapReporter {
8219
8301
  }
8220
8302
  }
8221
8303
 
8304
+ class JsonReporter {
8305
+ constructor() {
8306
+ this.start = 0;
8307
+ }
8308
+ onInit(ctx) {
8309
+ this.ctx = ctx;
8310
+ }
8311
+ async logTasks(files) {
8312
+ const suites = getSuites(files);
8313
+ const numTotalTestSuites = suites.length;
8314
+ const tests = getTests(files);
8315
+ const numTotalTests = tests.length;
8316
+ const testResults = {};
8317
+ const outputFile = getOutputFile(this.ctx, "json");
8318
+ for (const file of files) {
8319
+ const tests2 = getTests([file]);
8320
+ for (const test of tests2) {
8321
+ const res = test.result.benchmark;
8322
+ if (!outputFile)
8323
+ res.samples = "ignore on terminal";
8324
+ testResults[test.suite.name] = (testResults[test.suite.name] || []).concat(res);
8325
+ }
8326
+ if (tests2.some((t) => {
8327
+ var _a;
8328
+ return ((_a = t.result) == null ? void 0 : _a.state) === "run";
8329
+ })) {
8330
+ this.ctx.logger.warn("WARNING: Some tests are still running when generating the markdown report.This is likely an internal bug in Vitest.Please report it to https://github.com/vitest-dev/vitest/issues");
8331
+ }
8332
+ }
8333
+ const result = {
8334
+ numTotalTestSuites,
8335
+ numTotalTests,
8336
+ testResults
8337
+ };
8338
+ await this.writeReport(JSON.stringify(result, null, 2));
8339
+ }
8340
+ async onFinished(files = this.ctx.state.getFiles()) {
8341
+ await this.logTasks(files);
8342
+ }
8343
+ async writeReport(report) {
8344
+ const outputFile = getOutputFile(this.ctx, "json");
8345
+ if (outputFile) {
8346
+ const reportFile = resolve(this.ctx.config.root, outputFile);
8347
+ const outputDirectory = dirname(reportFile);
8348
+ if (!existsSync(outputDirectory))
8349
+ await promises.mkdir(outputDirectory, { recursive: true });
8350
+ await promises.writeFile(reportFile, report, "utf-8");
8351
+ this.ctx.logger.log(`markdown report written to ${reportFile}`);
8352
+ } else {
8353
+ this.ctx.logger.log(report);
8354
+ }
8355
+ }
8356
+ }
8357
+
8358
+ const BenchmarkReportsMap = {
8359
+ default: VerboseReporter,
8360
+ json: JsonReporter
8361
+ };
8362
+
8222
8363
  const ReportersMap = {
8223
8364
  "default": DefaultReporter,
8224
8365
  "verbose": VerboseReporter,
8225
8366
  "dot": DotReporter,
8226
- "json": JsonReporter,
8367
+ "json": JsonReporter$1,
8227
8368
  "tap": TapReporter,
8228
8369
  "tap-flat": TapFlatReporter,
8229
8370
  "junit": JUnitReporter
@@ -8255,6 +8396,21 @@ function createReporters(reporterReferences, runner) {
8255
8396
  });
8256
8397
  return Promise.all(promisedReporters);
8257
8398
  }
8399
+ function createBenchmarkReporters(reporterReferences, runner) {
8400
+ const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
8401
+ if (typeof referenceOrInstance === "string") {
8402
+ if (referenceOrInstance in BenchmarkReportsMap) {
8403
+ const BuiltinReporter = BenchmarkReportsMap[referenceOrInstance];
8404
+ return new BuiltinReporter();
8405
+ } else {
8406
+ const CustomReporter = await loadCustomReporterModule(referenceOrInstance, runner);
8407
+ return new CustomReporter();
8408
+ }
8409
+ }
8410
+ return referenceOrInstance;
8411
+ });
8412
+ return Promise.all(promisedReporters);
8413
+ }
8258
8414
 
8259
8415
  const isAggregateError = (err) => {
8260
8416
  if (typeof AggregateError !== "undefined" && err instanceof AggregateError)
@@ -8357,6 +8513,12 @@ class StateManager {
8357
8513
 
8358
8514
  const defaultInclude = ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"];
8359
8515
  const defaultExclude = ["**/node_modules/**", "**/dist/**", "**/cypress/**", "**/.{idea,git,cache,output,temp}/**"];
8516
+ const benchmarkConfigDefaults = {
8517
+ include: ["**/*.{bench,benchmark}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
8518
+ exclude: defaultExclude,
8519
+ includeSource: [],
8520
+ reporters: ["default"]
8521
+ };
8360
8522
  const defaultCoverageExcludes = [
8361
8523
  "coverage/**",
8362
8524
  "dist/**",
@@ -8379,7 +8541,7 @@ const coverageConfigDefaults = {
8379
8541
  reportsDirectory: "./coverage",
8380
8542
  excludeNodeModules: true,
8381
8543
  exclude: defaultCoverageExcludes,
8382
- reporter: ["text", "html", "clover"],
8544
+ reporter: ["text", "html", "clover", "json"],
8383
8545
  allowExternal: false,
8384
8546
  extension: [".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx", ".vue", ".svelte"]
8385
8547
  };
@@ -8425,7 +8587,7 @@ const config = {
8425
8587
  uiBase: "/__vitest__/",
8426
8588
  open: true,
8427
8589
  css: {
8428
- include: [/\.module\./]
8590
+ include: []
8429
8591
  },
8430
8592
  coverage: coverageConfigDefaults,
8431
8593
  fakeTimers: fakeTimersDefaults,
@@ -8627,18 +8789,23 @@ function resolveApiConfig(options) {
8627
8789
  }
8628
8790
  return api;
8629
8791
  }
8630
- function resolveConfig(options, viteConfig) {
8631
- var _a, _b, _c, _d, _e;
8792
+ function resolveConfig(mode, options, viteConfig) {
8793
+ var _a, _b, _c, _d, _e, _f;
8632
8794
  if (options.dom) {
8633
8795
  if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
8634
- console.warn(picocolors.exports.yellow(`${picocolors.exports.inverse(picocolors.exports.yellow(" Vitest "))} Your config.test.environment ("${viteConfig.test.environment}") conflicts with --dom flag ("happy-dom"), ignoring "${viteConfig.test.environment}"`));
8796
+ console.warn(
8797
+ picocolors.exports.yellow(
8798
+ `${picocolors.exports.inverse(picocolors.exports.yellow(" Vitest "))} Your config.test.environment ("${viteConfig.test.environment}") conflicts with --dom flag ("happy-dom"), ignoring "${viteConfig.test.environment}"`
8799
+ )
8800
+ );
8635
8801
  }
8636
8802
  options.environment = "happy-dom";
8637
8803
  }
8638
8804
  const resolved = {
8639
8805
  ...configDefaults,
8640
8806
  ...options,
8641
- root: viteConfig.root
8807
+ root: viteConfig.root,
8808
+ mode
8642
8809
  };
8643
8810
  if (viteConfig.base !== "/")
8644
8811
  resolved.base = viteConfig.base;
@@ -8679,7 +8846,21 @@ function resolveConfig(options, viteConfig) {
8679
8846
  resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS);
8680
8847
  if (process.env.VITEST_MIN_THREADS)
8681
8848
  resolved.minThreads = parseInt(process.env.VITEST_MIN_THREADS);
8682
- resolved.setupFiles = toArray$1(resolved.setupFiles || []).map((file) => normalize(resolveModule(file, { paths: [resolved.root] }) ?? resolve(resolved.root, file)));
8849
+ if (mode === "benchmark") {
8850
+ resolved.benchmark = {
8851
+ ...benchmarkConfigDefaults,
8852
+ ...resolved.benchmark
8853
+ };
8854
+ resolved.coverage.enabled = false;
8855
+ resolved.include = resolved.benchmark.include;
8856
+ resolved.exclude = resolved.benchmark.exclude;
8857
+ resolved.includeSource = resolved.benchmark.includeSource;
8858
+ }
8859
+ resolved.setupFiles = toArray$1(resolved.setupFiles || []).map(
8860
+ (file) => normalize(
8861
+ resolveModule(file, { paths: [resolved.root] }) ?? resolve(resolved.root, file)
8862
+ )
8863
+ );
8683
8864
  resolved.api = resolveApiConfig(options);
8684
8865
  if (options.related)
8685
8866
  resolved.related = toArray$1(options.related).map((file) => resolve(resolved.root, file));
@@ -8692,12 +8873,14 @@ function resolveConfig(options, viteConfig) {
8692
8873
  if (resolved.changed)
8693
8874
  resolved.passWithNoTests ?? (resolved.passWithNoTests = true);
8694
8875
  resolved.css ?? (resolved.css = {});
8695
- if (typeof resolved.css === "object")
8696
- (_d = resolved.css).include ?? (_d.include = [/\.module\./]);
8876
+ if (typeof resolved.css === "object") {
8877
+ (_d = resolved.css).modules ?? (_d.modules = {});
8878
+ (_e = resolved.css.modules).classNameStrategy ?? (_e.classNameStrategy = "stable");
8879
+ }
8697
8880
  resolved.cache ?? (resolved.cache = { dir: "" });
8698
8881
  if (resolved.cache)
8699
8882
  resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir);
8700
- if (!((_e = resolved.sequence) == null ? void 0 : _e.sequencer)) {
8883
+ if (!((_f = resolved.sequence) == null ? void 0 : _f.sequencer)) {
8701
8884
  resolved.sequence ?? (resolved.sequence = {});
8702
8885
  resolved.sequence.sequencer = resolved.sequence.shuffle ? RandomSequencer : BaseSequencer;
8703
8886
  }
@@ -9190,7 +9373,7 @@ createLogUpdate(process$1.stdout);
9190
9373
 
9191
9374
  createLogUpdate(process$1.stderr);
9192
9375
 
9193
- var version = "0.22.0";
9376
+ var version = "0.23.1";
9194
9377
 
9195
9378
  function fileFromParsedStack(stack) {
9196
9379
  var _a, _b;
@@ -9209,7 +9392,9 @@ async function printError(error, ctx, options = {}) {
9209
9392
  }
9210
9393
  const stacks = parseStacktrace(e, fullStack);
9211
9394
  await interpretSourcePos(stacks, ctx);
9212
- const nearest = stacks.find((stack) => ctx.server.moduleGraph.getModuleById(stack.file) && existsSync(stack.file));
9395
+ const nearest = stacks.find(
9396
+ (stack) => ctx.server.moduleGraph.getModuleById(stack.file) && existsSync(stack.file)
9397
+ );
9213
9398
  const errorProperties = getErrorProperties(e);
9214
9399
  if (type)
9215
9400
  printErrorType(type, ctx);
@@ -9223,12 +9408,12 @@ async function printError(error, ctx, options = {}) {
9223
9408
  }
9224
9409
  }
9225
9410
  });
9226
- if (e.cause) {
9411
+ if (e.cause && "name" in e.cause) {
9227
9412
  e.cause.name = `Caused by: ${e.cause.name}`;
9228
9413
  await printError(e.cause, ctx, { fullStack, showCodeFrame: false });
9229
9414
  }
9230
9415
  handleImportOutsideModuleError(e.stack || e.stackStr || "", ctx);
9231
- if (e.showDiff) {
9416
+ if (e.showDiff || e.showDiff === void 0 && e.actual && e.expected) {
9232
9417
  displayDiff(stringify$5(e.actual), stringify$5(e.expected), ctx.logger.console, {
9233
9418
  outputTruncateLength: ctx.config.outputTruncateLength,
9234
9419
  outputDiffLines: ctx.config.outputDiffLines
@@ -9277,7 +9462,8 @@ function handleImportOutsideModuleError(stack, ctx) {
9277
9462
  name = name.split("/").slice(0, 2).join("/");
9278
9463
  else
9279
9464
  name = name.split("/")[0];
9280
- ctx.logger.error(picocolors.exports.yellow(`Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${picocolors.exports.bold(`"${name}"`)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
9465
+ ctx.logger.error(picocolors.exports.yellow(
9466
+ `Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${picocolors.exports.bold(`"${name}"`)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
9281
9467
 
9282
9468
  As a temporary workaround you can try to inline the package by updating your config:
9283
9469
 
@@ -9290,7 +9476,8 @@ As a temporary workaround you can try to inline the package by updating your con
9290
9476
  }
9291
9477
  }
9292
9478
  }
9293
- `)));
9479
+ `)
9480
+ ));
9294
9481
  }
9295
9482
  function displayDiff(actual, expected, console, options) {
9296
9483
  console.error(picocolors.exports.gray(unifiedDiff(actual, expected, options)) + "\n");
@@ -9417,9 +9604,11 @@ class Logger {
9417
9604
  if (config.watchExclude)
9418
9605
  this.console.error(picocolors.exports.dim("watch exclude: ") + picocolors.exports.yellow(config.watchExclude.join(comma)));
9419
9606
  if (config.passWithNoTests)
9420
- this.log("No test files found, exiting with code 0\n");
9607
+ this.log(`No ${config.mode} files found, exiting with code 0
9608
+ `);
9421
9609
  else
9422
- this.error(picocolors.exports.red("\nNo test files found, exiting with code 1"));
9610
+ this.error(picocolors.exports.red(`
9611
+ No ${config.mode} files found, exiting with code 1`));
9423
9612
  }
9424
9613
  printBanner() {
9425
9614
  var _a, _b, _c;
@@ -9438,9 +9627,11 @@ class Logger {
9438
9627
  this.log();
9439
9628
  }
9440
9629
  async printUnhandledErrors(errors) {
9441
- const errorMessage = picocolors.exports.red(picocolors.exports.bold(`
9630
+ const errorMessage = picocolors.exports.red(picocolors.exports.bold(
9631
+ `
9442
9632
  Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
9443
- This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`));
9633
+ This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
9634
+ ));
9444
9635
  this.log(picocolors.exports.red(divider(picocolors.exports.bold(picocolors.exports.inverse(" Unhandled Errors ")))));
9445
9636
  this.log(errorMessage);
9446
9637
  await Promise.all(errors.map(async (err) => {
@@ -9452,7 +9643,8 @@ This might cause false positive tests. Resolve unhandled errors to make sure you
9452
9643
 
9453
9644
  const WATCHER_DEBOUNCE = 100;
9454
9645
  class Vitest {
9455
- constructor() {
9646
+ constructor(mode) {
9647
+ this.mode = mode;
9456
9648
  this.config = void 0;
9457
9649
  this.server = void 0;
9458
9650
  this.state = void 0;
@@ -9476,7 +9668,7 @@ class Vitest {
9476
9668
  this.restartsCount += 1;
9477
9669
  (_b = this.pool) == null ? void 0 : _b.close();
9478
9670
  this.pool = void 0;
9479
- const resolved = resolveConfig(options, server.config);
9671
+ const resolved = resolveConfig(this.mode, options, server.config);
9480
9672
  this.server = server;
9481
9673
  this.config = resolved;
9482
9674
  this.state = new StateManager();
@@ -9496,10 +9688,23 @@ class Vitest {
9496
9688
  return node.resolveId(id, importer);
9497
9689
  }
9498
9690
  });
9499
- this.reporters = await createReporters(resolved.reporters, this.runner);
9691
+ if (this.config.watch) {
9692
+ const serverRestart = server.restart;
9693
+ server.restart = async (...args) => {
9694
+ await Promise.all(this._onRestartListeners.map((fn) => fn()));
9695
+ return await serverRestart(...args);
9696
+ };
9697
+ server.watcher.on("change", async (file) => {
9698
+ file = normalizePath(file);
9699
+ const isConfig = file === server.config.configFile;
9700
+ if (isConfig) {
9701
+ await Promise.all(this._onRestartListeners.map((fn) => fn("config")));
9702
+ await serverRestart();
9703
+ }
9704
+ });
9705
+ }
9706
+ this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray$1((_c = resolved.benchmark) == null ? void 0 : _c.reporters), this.runner) : await createReporters(resolved.reporters, this.runner);
9500
9707
  this.runningPromise = void 0;
9501
- this._onRestartListeners.forEach((fn) => fn());
9502
- await ((_c = this.coverageProvider) == null ? void 0 : _c.clean(this.config.coverage.clean));
9503
9708
  this.cache.results.setConfig(resolved.root, resolved.cache);
9504
9709
  try {
9505
9710
  await this.cache.results.readFromCache();
@@ -9518,29 +9723,36 @@ class Vitest {
9518
9723
  return this.coverageProvider;
9519
9724
  }
9520
9725
  getSerializableConfig() {
9521
- return deepMerge({
9522
- ...this.config,
9523
- reporters: [],
9524
- snapshotOptions: {
9525
- ...this.config.snapshotOptions,
9526
- resolveSnapshotPath: void 0
9726
+ return deepMerge(
9727
+ {
9728
+ ...this.config,
9729
+ reporters: [],
9730
+ snapshotOptions: {
9731
+ ...this.config.snapshotOptions,
9732
+ resolveSnapshotPath: void 0
9733
+ },
9734
+ onConsoleLog: void 0,
9735
+ sequence: {
9736
+ ...this.config.sequence,
9737
+ sequencer: void 0
9738
+ }
9527
9739
  },
9528
- onConsoleLog: void 0,
9529
- sequence: {
9530
- ...this.config.sequence,
9531
- sequencer: void 0
9532
- }
9533
- }, this.configOverride || {});
9740
+ this.configOverride || {}
9741
+ );
9534
9742
  }
9535
9743
  async start(filters) {
9744
+ var _a;
9536
9745
  try {
9537
9746
  await this.initCoverageProvider();
9747
+ await ((_a = this.coverageProvider) == null ? void 0 : _a.clean(this.config.coverage.clean));
9538
9748
  } catch (e) {
9539
9749
  this.logger.error(e);
9540
9750
  process.exit(1);
9541
9751
  }
9542
9752
  await this.report("onInit", this);
9543
- const files = await this.filterTestsBySource(await this.globTestFiles(filters));
9753
+ const files = await this.filterTestsBySource(
9754
+ await this.globTestFiles(filters)
9755
+ );
9544
9756
  if (!files.length) {
9545
9757
  const exitCode = this.config.passWithNoTests ? 0 : 1;
9546
9758
  this.logger.printNoTestFound(filters);
@@ -9576,7 +9788,7 @@ class Vitest {
9576
9788
  }
9577
9789
  async filterTestsBySource(tests) {
9578
9790
  if (this.config.changed && !this.config.related) {
9579
- const { VitestGit } = await import('./chunk-node-git.71b74da4.mjs');
9791
+ const { VitestGit } = await import('./chunk-node-git.6f289b0a.mjs');
9580
9792
  const vitestGit = new VitestGit(this.config.root);
9581
9793
  const related2 = await vitestGit.findChangedFiles({
9582
9794
  changedSince: this.config.changed
@@ -9595,10 +9807,12 @@ class Vitest {
9595
9807
  return tests;
9596
9808
  if (!related.length)
9597
9809
  return [];
9598
- const testDeps = await Promise.all(tests.map(async (filepath) => {
9599
- const deps = await this.getTestDependencies(filepath);
9600
- return [filepath, deps];
9601
- }));
9810
+ const testDeps = await Promise.all(
9811
+ tests.map(async (filepath) => {
9812
+ const deps = await this.getTestDependencies(filepath);
9813
+ return [filepath, deps];
9814
+ })
9815
+ );
9602
9816
  const runningTests = [];
9603
9817
  for (const [filepath, deps] of testDeps) {
9604
9818
  if (deps.size && related.some((path) => path === filepath || deps.has(path)))
@@ -9644,6 +9858,13 @@ class Vitest {
9644
9858
  this.config.testNamePattern = pattern ? new RegExp(pattern) : void 0;
9645
9859
  await this.rerunFiles(files, trigger);
9646
9860
  }
9861
+ async changeFilenamePattern(pattern) {
9862
+ const files = this.state.getFilepaths();
9863
+ if (!pattern)
9864
+ return await this.rerunFiles(files, "reset filename pattern");
9865
+ const filteredFiles = await this.globTestFiles([pattern]);
9866
+ await this.rerunFiles(filteredFiles, "change filename pattern");
9867
+ }
9647
9868
  async rerunFailed() {
9648
9869
  await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed");
9649
9870
  }
@@ -9782,22 +10003,26 @@ class Vitest {
9782
10003
  async report(name, ...args) {
9783
10004
  await Promise.all(this.reporters.map((r) => {
9784
10005
  var _a;
9785
- return (_a = r[name]) == null ? void 0 : _a.call(r, ...args);
10006
+ return (_a = r[name]) == null ? void 0 : _a.call(
10007
+ r,
10008
+ ...args
10009
+ );
9786
10010
  }));
9787
10011
  }
9788
10012
  async globTestFiles(filters = []) {
10013
+ const { include, exclude, includeSource } = this.config;
9789
10014
  const globOptions = {
9790
10015
  absolute: true,
9791
10016
  cwd: this.config.dir || this.config.root,
9792
- ignore: this.config.exclude
10017
+ ignore: exclude
9793
10018
  };
9794
- let testFiles = await out(this.config.include, globOptions);
10019
+ let testFiles = await out(include, globOptions);
9795
10020
  if (filters.length && process.platform === "win32")
9796
10021
  filters = filters.map((f) => toNamespacedPath(f));
9797
10022
  if (filters.length)
9798
10023
  testFiles = testFiles.filter((i) => filters.some((f) => i.includes(f)));
9799
- if (this.config.includeSource) {
9800
- let files = await out(this.config.includeSource, globOptions);
10024
+ if (includeSource) {
10025
+ let files = await out(includeSource, globOptions);
9801
10026
  if (filters.length)
9802
10027
  files = files.filter((i) => filters.some((f) => i.includes(f)));
9803
10028
  await Promise.all(files.map(async (file) => {
@@ -9828,18 +10053,32 @@ class Vitest {
9828
10053
  isInSourceTestFile(code) {
9829
10054
  return code.includes("import.meta.vitest");
9830
10055
  }
9831
- onServerRestarted(fn) {
10056
+ onServerRestart(fn) {
9832
10057
  this._onRestartListeners.push(fn);
9833
10058
  }
9834
10059
  }
9835
10060
 
10061
+ function generateCssFilenameHash(filepath) {
10062
+ return createHash("md5").update(filepath).digest("hex").slice(0, 6);
10063
+ }
10064
+ function generateScopedClassName(strategy, name, filename) {
10065
+ if (strategy === "scoped")
10066
+ return null;
10067
+ if (strategy === "non-scoped")
10068
+ return name;
10069
+ const hash = generateCssFilenameHash(filename);
10070
+ return `_${name}_${hash}`;
10071
+ }
10072
+
9836
10073
  const EnvReplacerPlugin = () => {
9837
10074
  return {
9838
10075
  name: "vitest:env-replacer",
9839
10076
  enforce: "pre",
9840
10077
  transform(code) {
10078
+ if (!/\bimport\.meta\.env\b/g.test(code))
10079
+ return null;
9841
10080
  let s = null;
9842
- const envs = code.matchAll(/\bimport\.meta\.env\b/g);
10081
+ const envs = stripLiteral(code).matchAll(/\bimport\.meta\.env\b/g);
9843
10082
  for (const env of envs) {
9844
10083
  s || (s = new MagicString(code));
9845
10084
  const startIndex = env.index;
@@ -10036,9 +10275,19 @@ function getIndexStatus(code, from) {
10036
10275
 
10037
10276
  const cssLangs = "\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)";
10038
10277
  const cssLangRE = new RegExp(cssLangs);
10278
+ const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
10039
10279
  const isCSS = (id) => {
10040
10280
  return cssLangRE.test(id);
10041
10281
  };
10282
+ const isCSSModule = (id) => {
10283
+ return cssModuleRE.test(id);
10284
+ };
10285
+ const getCSSModuleProxyReturn = (strategy, filename) => {
10286
+ if (strategy === "non-scoped")
10287
+ return "style";
10288
+ const hash = generateCssFilenameHash(filename);
10289
+ return `\`_\${style}_${hash}\``;
10290
+ };
10042
10291
  function CSSEnablerPlugin(ctx) {
10043
10292
  const shouldProcessCSS = (id) => {
10044
10293
  const { css } = ctx.config;
@@ -10050,16 +10299,38 @@ function CSSEnablerPlugin(ctx) {
10050
10299
  return true;
10051
10300
  return false;
10052
10301
  };
10053
- return {
10054
- name: "vitest:css-enabler",
10055
- enforce: "pre",
10056
- transform(code, id) {
10057
- if (!isCSS(id))
10058
- return;
10059
- if (!shouldProcessCSS(id))
10302
+ return [
10303
+ {
10304
+ name: "vitest:css-disable",
10305
+ enforce: "pre",
10306
+ transform(code, id) {
10307
+ if (!isCSS(id))
10308
+ return;
10309
+ if (!shouldProcessCSS(id))
10310
+ return { code: "" };
10311
+ }
10312
+ },
10313
+ {
10314
+ name: "vitest:css-empty-post",
10315
+ enforce: "post",
10316
+ transform(_, id) {
10317
+ var _a;
10318
+ if (!isCSS(id) || shouldProcessCSS(id))
10319
+ return;
10320
+ if (isCSSModule(id)) {
10321
+ const scopeStrategy = typeof ctx.config.css !== "boolean" && ((_a = ctx.config.css.modules) == null ? void 0 : _a.classNameStrategy) || "stable";
10322
+ const proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id));
10323
+ const code = `export default new Proxy(Object.create(null), {
10324
+ get(_, style) {
10325
+ return ${proxyReturn};
10326
+ },
10327
+ })`;
10328
+ return { code };
10329
+ }
10060
10330
  return { code: "" };
10331
+ }
10061
10332
  }
10062
- };
10333
+ ];
10063
10334
  }
10064
10335
 
10065
10336
  function CoverageTransform(ctx) {
@@ -10072,16 +10343,17 @@ function CoverageTransform(ctx) {
10072
10343
  };
10073
10344
  }
10074
10345
 
10075
- async function VitestPlugin(options = {}, ctx = new Vitest()) {
10076
- let haveStarted = false;
10077
- async function UIPlugin() {
10346
+ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
10347
+ const getRoot = () => {
10078
10348
  var _a;
10079
- await ensurePackageInstalled("@vitest/ui", ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd());
10349
+ return ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd();
10350
+ };
10351
+ async function UIPlugin() {
10352
+ await ensurePackageInstalled("@vitest/ui", getRoot());
10080
10353
  return (await import('@vitest/ui')).default(options.uiBase);
10081
10354
  }
10082
10355
  async function BrowserPlugin() {
10083
- var _a;
10084
- await ensurePackageInstalled("@vitest/browser", ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd());
10356
+ await ensurePackageInstalled("@vitest/browser", getRoot());
10085
10357
  return (await import('@vitest/browser')).default("/");
10086
10358
  }
10087
10359
  return [
@@ -10092,6 +10364,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10092
10364
  this.meta.watchMode = false;
10093
10365
  },
10094
10366
  config(viteConfig) {
10367
+ var _a, _b, _c;
10095
10368
  const preOptions = deepMerge({}, configDefaults, options, viteConfig.test ?? {});
10096
10369
  preOptions.api = resolveApiConfig(preOptions);
10097
10370
  if (viteConfig.define) {
@@ -10141,6 +10414,15 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10141
10414
  preTransformRequests: false
10142
10415
  }
10143
10416
  };
10417
+ const classNameStrategy = preOptions.css && ((_b = (_a = preOptions.css) == null ? void 0 : _a.modules) == null ? void 0 : _b.classNameStrategy);
10418
+ if (classNameStrategy !== "scoped") {
10419
+ config.css ?? (config.css = {});
10420
+ (_c = config.css).modules ?? (_c.modules = {});
10421
+ config.css.modules.generateScopedName = (name, filename) => {
10422
+ const root = getRoot();
10423
+ return generateScopedClassName(classNameStrategy, name, relative(root, filename));
10424
+ };
10425
+ }
10144
10426
  if (!options.browser) {
10145
10427
  Object.assign(config, {
10146
10428
  cacheDir: void 0,
@@ -10159,7 +10441,12 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10159
10441
  viteConfigTest.run = true;
10160
10442
  if ("alias" in viteConfigTest)
10161
10443
  delete viteConfigTest.alias;
10162
- options = deepMerge({}, configDefaults, viteConfigTest, options);
10444
+ options = deepMerge(
10445
+ {},
10446
+ configDefaults,
10447
+ viteConfigTest,
10448
+ options
10449
+ );
10163
10450
  options.api = resolveApiConfig(options);
10164
10451
  const { PROD, DEV, ...envs } = viteConfig.env;
10165
10452
  (_a = process.env).PROD ?? (_a.PROD = PROD ? "1" : "");
@@ -10169,13 +10456,10 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10169
10456
  (_d = process.env)[name] ?? (_d[name] = envs[name]);
10170
10457
  },
10171
10458
  async configureServer(server) {
10172
- if (haveStarted)
10173
- await ctx.report("onServerRestart");
10174
10459
  try {
10175
10460
  await ctx.setServer(options, server);
10176
- haveStarted = true;
10177
10461
  if (options.api && options.watch)
10178
- (await import('./chunk-api-setup.ecd02c18.mjs')).setup(ctx);
10462
+ (await import('./chunk-api-setup.9e83ca0a.mjs')).setup(ctx);
10179
10463
  } catch (err) {
10180
10464
  ctx.logger.printError(err, true);
10181
10465
  process.exit(1);
@@ -10188,21 +10472,21 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10188
10472
  MocksPlugin(),
10189
10473
  GlobalSetupPlugin(ctx),
10190
10474
  ...options.browser ? await BrowserPlugin() : [],
10191
- CSSEnablerPlugin(ctx),
10475
+ ...CSSEnablerPlugin(ctx),
10192
10476
  CoverageTransform(ctx),
10193
10477
  options.ui ? await UIPlugin() : null
10194
10478
  ].filter(notNullish);
10195
10479
  }
10196
10480
 
10197
- async function createVitest(options, viteOverrides = {}) {
10481
+ async function createVitest(mode, options, viteOverrides = {}) {
10198
10482
  var _a;
10199
- const ctx = new Vitest();
10483
+ const ctx = new Vitest(mode);
10200
10484
  const root = resolve(options.root || process.cwd());
10201
10485
  const configPath = options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
10202
10486
  const config = {
10203
10487
  logLevel: "error",
10204
10488
  configFile: configPath,
10205
- mode: options.mode || process.env.NODE_ENV || "test",
10489
+ mode: options.mode || process.env.NODE_ENV || mode,
10206
10490
  plugins: await VitestPlugin(options, ctx)
10207
10491
  };
10208
10492
  const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
@@ -10217,16 +10501,20 @@ const keys = [
10217
10501
  ["a", "rerun all tests"],
10218
10502
  ["f", "rerun only failed tests"],
10219
10503
  ["u", "update snapshot"],
10504
+ ["p", "filter by a filename"],
10220
10505
  ["t", "filter by a test name regex pattern"],
10221
10506
  ["q", "quit"]
10222
10507
  ];
10223
10508
  function printShortcutsHelp() {
10224
- stdout().write(`
10509
+ stdout().write(
10510
+ `
10225
10511
  ${picocolors.exports.bold(" Watch Usage")}
10226
10512
  ${keys.map((i) => picocolors.exports.dim(" press ") + picocolors.exports.reset(picocolors.exports.bold(i[0])) + picocolors.exports.dim(` to ${i[1]}`)).join("\n")}
10227
- `);
10513
+ `
10514
+ );
10228
10515
  }
10229
10516
  function registerConsoleShortcuts(ctx) {
10517
+ let latestFilename = "";
10230
10518
  async function _keypressHandler(str, key) {
10231
10519
  if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c")
10232
10520
  return ctx.exit(true);
@@ -10243,6 +10531,8 @@ function registerConsoleShortcuts(ctx) {
10243
10531
  return ctx.rerunFailed();
10244
10532
  if (name === "t")
10245
10533
  return inputNamePattern();
10534
+ if (name === "p")
10535
+ return inputFilePattern();
10246
10536
  if (name === "q")
10247
10537
  return ctx.exit(true);
10248
10538
  }
@@ -10260,6 +10550,18 @@ function registerConsoleShortcuts(ctx) {
10260
10550
  await ctx.changeNamePattern(filter, void 0, "change pattern");
10261
10551
  on();
10262
10552
  }
10553
+ async function inputFilePattern() {
10554
+ off();
10555
+ const { filter = "" } = await prompts([{
10556
+ name: "filter",
10557
+ type: "text",
10558
+ message: "Input filename pattern",
10559
+ initial: latestFilename
10560
+ }]);
10561
+ latestFilename = filter;
10562
+ await ctx.changeFilenamePattern(filter);
10563
+ on();
10564
+ }
10263
10565
  let rl;
10264
10566
  function on() {
10265
10567
  off();
@@ -10279,7 +10581,7 @@ function registerConsoleShortcuts(ctx) {
10279
10581
  on();
10280
10582
  }
10281
10583
 
10282
- async function startVitest(cliFilters, options, viteOverrides) {
10584
+ async function startVitest(mode, cliFilters, options, viteOverrides) {
10283
10585
  var _a;
10284
10586
  process.env.TEST = "true";
10285
10587
  process.env.VITEST = "true";
@@ -10295,8 +10597,8 @@ async function startVitest(cliFilters, options, viteOverrides) {
10295
10597
  }
10296
10598
  if (typeof options.coverage === "boolean")
10297
10599
  options.coverage = { enabled: options.coverage };
10298
- const ctx = await createVitest(options, viteOverrides);
10299
- if (ctx.config.coverage.enabled) {
10600
+ const ctx = await createVitest(mode, options, viteOverrides);
10601
+ if (mode !== "benchmark" && ctx.config.coverage.enabled) {
10300
10602
  const provider = ctx.config.coverage.provider || "c8";
10301
10603
  if (typeof provider === "string") {
10302
10604
  const requiredPackages = CoverageProviderMap[provider];
@@ -10306,17 +10608,19 @@ async function startVitest(cliFilters, options, viteOverrides) {
10306
10608
  }
10307
10609
  }
10308
10610
  }
10309
- if (ctx.config.environment && ctx.config.environment !== "node") {
10310
- const packageName = envPackageNames[ctx.config.environment];
10311
- if (!await ensurePackageInstalled(packageName, root)) {
10312
- process.exitCode = 1;
10313
- return false;
10314
- }
10611
+ const environmentPackage = getEnvPackageName(ctx.config.environment);
10612
+ if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) {
10613
+ process.exitCode = 1;
10614
+ return false;
10315
10615
  }
10316
10616
  if (process.stdin.isTTY && ctx.config.watch)
10317
10617
  registerConsoleShortcuts(ctx);
10318
- ctx.onServerRestarted(() => {
10319
- ctx.start(cliFilters);
10618
+ ctx.onServerRestart((reason) => {
10619
+ ctx.report("onServerRestart", reason);
10620
+ if (process.env.VITEST_CLI_WRAPPER)
10621
+ process.exit(EXIT_CODE_RESTART);
10622
+ else
10623
+ ctx.start(cliFilters);
10320
10624
  });
10321
10625
  try {
10322
10626
  await ctx.start(cliFilters);