vitest 0.21.1 → 0.23.0

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 (50) hide show
  1. package/LICENSE.md +61 -33
  2. package/dist/browser.d.ts +5 -5
  3. package/dist/browser.mjs +12 -10
  4. package/dist/{chunk-api-setup.7a6ba7fb.mjs → chunk-api-setup.5fc06d1d.mjs} +94 -91
  5. package/dist/chunk-constants.6196597b.mjs +284 -0
  6. package/dist/chunk-env-node.ceb43f1c.mjs +403 -0
  7. package/dist/{chunk-install-pkg.6c6dc0c2.mjs → chunk-install-pkg.e081fc1b.mjs} +2 -1
  8. package/dist/chunk-integrations-coverage.99c020eb.mjs +166 -0
  9. package/dist/{chunk-integrations-globals.44a8f047.mjs → chunk-integrations-globals.ef598c23.mjs} +8 -9
  10. package/dist/{chunk-magic-string.efe26975.mjs → chunk-magic-string.56b2b543.mjs} +30 -10
  11. package/dist/chunk-mock-date.0d86eaa5.mjs +332 -0
  12. package/dist/chunk-node-git.6f289b0a.mjs +84 -0
  13. package/dist/{chunk-runtime-chain.98d42d89.mjs → chunk-runtime-chain.2af36ddf.mjs} +507 -172
  14. package/dist/{chunk-runtime-error.87a2b5a2.mjs → chunk-runtime-error.ed9b4f70.mjs} +208 -76
  15. package/dist/{chunk-runtime-hooks.453f8858.mjs → chunk-runtime-hooks.75ce0575.mjs} +18 -12
  16. package/dist/{chunk-runtime-mocker.23b62bfa.mjs → chunk-runtime-mocker.fc76f21d.mjs} +18 -11
  17. package/dist/{chunk-runtime-rpc.b50ab560.mjs → chunk-runtime-rpc.3fe371e9.mjs} +1 -2
  18. package/dist/{chunk-utils-source-map.94107ee8.mjs → chunk-utils-source-map.70ee97e1.mjs} +11 -4
  19. package/dist/{chunk-vite-node-client.fdd9592c.mjs → chunk-vite-node-client.74ebe3d5.mjs} +97 -31
  20. package/dist/{chunk-vite-node-debug.09afb76f.mjs → chunk-vite-node-debug.2d8a1dc3.mjs} +3 -3
  21. package/dist/{chunk-vite-node-externalize.27aee038.mjs → chunk-vite-node-externalize.41bf722e.mjs} +644 -222
  22. package/dist/{chunk-vite-node-utils.f34df9d3.mjs → chunk-vite-node-utils.68573626.mjs} +60 -42
  23. package/dist/cli-wrapper.mjs +128 -0
  24. package/dist/cli.mjs +29 -20
  25. package/dist/config.cjs +5 -2
  26. package/dist/config.d.ts +8 -4
  27. package/dist/config.mjs +4 -3
  28. package/dist/entry.mjs +20 -15
  29. package/dist/environments.d.ts +23 -0
  30. package/dist/environments.mjs +3 -0
  31. package/dist/{global-60f880c6.d.ts → global-ea084c9f.d.ts} +627 -178
  32. package/dist/{index-4a906fa4.d.ts → index-5f09f4d0.d.ts} +3 -50
  33. package/dist/index.d.ts +6 -6
  34. package/dist/index.mjs +7 -6
  35. package/dist/loader.mjs +3 -3
  36. package/dist/node.d.ts +5 -4
  37. package/dist/node.mjs +19 -16
  38. package/dist/suite.mjs +6 -5
  39. package/dist/vendor-index.0557b03a.mjs +147 -0
  40. package/dist/vendor-index.13e3bda3.mjs +61 -0
  41. package/dist/{chunk-node-git.c2be9c49.mjs → vendor-index.4aeeb598.mjs} +4 -72
  42. package/dist/{vendor-index.61438b77.mjs → vendor-index.731a22f2.mjs} +1 -61
  43. package/dist/worker.mjs +20 -18
  44. package/package.json +19 -16
  45. package/vitest.mjs +1 -1
  46. package/dist/chunk-constants.26dc9f85.mjs +0 -38
  47. package/dist/chunk-defaults.02abff90.mjs +0 -680
  48. package/dist/chunk-mock-date.bc81a3ac.mjs +0 -555
  49. package/dist/chunk-utils-global.fa20c2f6.mjs +0 -5
  50. package/dist/mocker-5e2a8e41.d.ts +0 -3
@@ -1,32 +1,35 @@
1
- import { y as resolve, j as join, z as basename, d as dirname, A as AggregateErrorPonyfill, p as picocolors, B as isAbsolute, C as relative, s as slash$2, l as isNode, o as relativePath, D as getTests, e as getFullName, x as hasFailed, E as hasFailedSnapshot, F as getSuites, v as shuffle, t as toArray$1, G as normalize, n as noop$1, H as deepMerge, I as toNamespacedPath, g as getCallLastIndex, f as notNullish, J as ensurePackageInstalled, K as stdout } from './chunk-mock-date.bc81a3ac.mjs';
2
- import { p as pLimit, c as configDefaults, r as resolveC8Options, a as cleanCoverage, b as reportCoverage, d as envPackageNames } from './chunk-defaults.02abff90.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.0d86eaa5.mjs';
5
+ import { loadConfigFromFile, normalizePath, createServer, mergeConfig } from 'vite';
4
6
  import path$a from 'path';
5
- import _url, { fileURLToPath } from 'url';
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.26dc9f85.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 { c as createBirpc, V as ViteNodeRunner } from './chunk-vite-node-client.fdd9592c.mjs';
15
+ import { c as createBirpc, V as ViteNodeRunner } from './chunk-vite-node-client.74ebe3d5.mjs';
16
+ import { performance } from 'perf_hooks';
15
17
  import createDebug from 'debug';
16
- 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.f34df9d3.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.68573626.mjs';
17
19
  import { MessageChannel } from 'worker_threads';
18
20
  import { Tinypool } from 'tinypool';
19
- import { performance } from 'perf_hooks';
20
- 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.94107ee8.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.70ee97e1.mjs';
21
22
  import { b as safeSetInterval, c as safeClearInterval, s as safeSetTimeout, a as safeClearTimeout } from './chunk-utils-timers.b48455ed.mjs';
22
23
  import { resolveModule } from 'local-pkg';
23
24
  import { createHash } from 'crypto';
24
- import { o as onetime, s as signalExit } from './vendor-index.61438b77.mjs';
25
- 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';
26
29
  import require$$0$2 from 'readline';
27
30
  import { p as prompts } from './vendor-index.ae96af6e.mjs';
28
31
 
29
- var version$1 = "0.21.1";
32
+ var version$1 = "0.23.0";
30
33
 
31
34
  class EndError extends Error {
32
35
  constructor(value) {
@@ -81,14 +84,14 @@ const typeMappings = {
81
84
  };
82
85
 
83
86
  function checkType(type) {
84
- if (type in typeMappings) {
87
+ if (Object.hasOwnProperty.call(typeMappings, type)) {
85
88
  return;
86
89
  }
87
90
 
88
91
  throw new Error(`Invalid type specified: ${type}`);
89
92
  }
90
93
 
91
- const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
94
+ const matchType = (type, stat) => stat[typeMappings[type]]();
92
95
 
93
96
  const toPath$1 = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
94
97
 
@@ -6850,7 +6853,7 @@ class ViteNodeServer {
6850
6853
  }, options.debug ?? {});
6851
6854
  }
6852
6855
  if (options.debug)
6853
- import('./chunk-vite-node-debug.09afb76f.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));
6854
6857
  }
6855
6858
  shouldExternalize(id) {
6856
6859
  return shouldExternalize(id, this.options.deps, this.externalizeCache);
@@ -6863,19 +6866,25 @@ class ViteNodeServer {
6863
6866
  }
6864
6867
  async fetchModule(id) {
6865
6868
  if (!this.fetchPromiseMap.has(id)) {
6866
- this.fetchPromiseMap.set(id, this._fetchModule(id).then((r) => {
6867
- return this.options.sourcemap !== true ? { ...r, map: void 0 } : r;
6868
- }).finally(() => {
6869
- this.fetchPromiseMap.delete(id);
6870
- }));
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
+ );
6871
6877
  }
6872
6878
  return this.fetchPromiseMap.get(id);
6873
6879
  }
6874
6880
  async transformRequest(id) {
6875
6881
  if (!this.transformPromiseMap.has(id)) {
6876
- this.transformPromiseMap.set(id, this._transformRequest(id).finally(() => {
6877
- this.transformPromiseMap.delete(id);
6878
- }));
6882
+ this.transformPromiseMap.set(
6883
+ id,
6884
+ this._transformRequest(id).finally(() => {
6885
+ this.transformPromiseMap.delete(id);
6886
+ })
6887
+ );
6879
6888
  }
6880
6889
  return this.transformPromiseMap.get(id);
6881
6890
  }
@@ -6900,14 +6909,18 @@ class ViteNodeServer {
6900
6909
  if (timestamp && cache && cache.timestamp >= timestamp)
6901
6910
  return cache.result;
6902
6911
  const externalize = await this.shouldExternalize(filePath);
6912
+ let duration;
6903
6913
  if (externalize) {
6904
6914
  result = { externalize };
6905
6915
  (_a = this.debugger) == null ? void 0 : _a.recordExternalize(id, externalize);
6906
6916
  } else {
6917
+ const start = performance.now();
6907
6918
  const r = await this._transformRequest(id);
6919
+ duration = performance.now() - start;
6908
6920
  result = { code: r == null ? void 0 : r.code, map: r == null ? void 0 : r.map };
6909
6921
  }
6910
6922
  this.fetchCache.set(filePath, {
6923
+ duration,
6911
6924
  timestamp,
6912
6925
  result
6913
6926
  });
@@ -6953,7 +6966,13 @@ class SnapshotManager {
6953
6966
  }
6954
6967
  resolvePath(testPath) {
6955
6968
  const resolver = this.options.resolveSnapshotPath || (() => {
6956
- 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
+ );
6957
6976
  });
6958
6977
  return resolver(testPath, this.extension);
6959
6978
  }
@@ -7000,15 +7019,15 @@ function addSnapshotResult(summary, result) {
7000
7019
  summary.total += result.added + result.matched + result.unmatched + result.updated;
7001
7020
  }
7002
7021
 
7003
- const workerPath = _url.pathToFileURL(resolve(distDir, "./worker.mjs")).href;
7004
- const loaderPath = _url.pathToFileURL(resolve(distDir, "./loader.mjs")).href;
7022
+ const workerPath = url.pathToFileURL(resolve(distDir, "./worker.mjs")).href;
7023
+ const loaderPath = url.pathToFileURL(resolve(distDir, "./loader.mjs")).href;
7005
7024
  const suppressLoaderWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
7006
7025
  function createPool(ctx) {
7007
- var _a, _b;
7026
+ var _a, _b, _c;
7008
7027
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(cpus().length / 2), 1) : Math.max(cpus().length - 1, 1);
7009
7028
  const maxThreads = ctx.config.maxThreads ?? threadsCount;
7010
7029
  const minThreads = ctx.config.minThreads ?? threadsCount;
7011
- 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])) || [];
7012
7031
  const options = {
7013
7032
  filename: workerPath,
7014
7033
  useAtomics: false,
@@ -7019,8 +7038,8 @@ function createPool(ctx) {
7019
7038
  suppressLoaderWarningsPath,
7020
7039
  "--experimental-loader",
7021
7040
  loaderPath,
7022
- ...conditions || []
7023
- ] : []
7041
+ ...conditions
7042
+ ] : conditions
7024
7043
  };
7025
7044
  if (ctx.config.isolate) {
7026
7045
  options.isolateWorkers = true;
@@ -7031,8 +7050,7 @@ function createPool(ctx) {
7031
7050
  options.maxThreads = 1;
7032
7051
  options.minThreads = 1;
7033
7052
  }
7034
- if (ctx.config.coverage.enabled)
7035
- (_b = process.env).NODE_V8_COVERAGE || (_b.NODE_V8_COVERAGE = ctx.config.coverage.tempDirectory);
7053
+ (_c = (_b = ctx.coverageProvider) == null ? void 0 : _b.onBeforeFilesRun) == null ? void 0 : _c.call(_b);
7036
7054
  options.env = {
7037
7055
  TEST: "true",
7038
7056
  VITEST: "true",
@@ -7089,61 +7107,68 @@ function createChannel(ctx) {
7089
7107
  const channel = new MessageChannel();
7090
7108
  const port = channel.port2;
7091
7109
  const workerPort = channel.port1;
7092
- createBirpc({
7093
- onWorkerExit(code) {
7094
- process.exit(code || 1);
7095
- },
7096
- snapshotSaved(snapshot) {
7097
- ctx.snapshot.add(snapshot);
7098
- },
7099
- resolveSnapshotPath(testPath) {
7100
- return ctx.snapshot.resolvePath(testPath);
7101
- },
7102
- async getSourceMap(id, force) {
7103
- if (force) {
7104
- const mod = ctx.server.moduleGraph.getModuleById(id);
7105
- if (mod)
7106
- ctx.server.moduleGraph.invalidateModule(mod);
7107
- }
7108
- const r = await ctx.vitenode.transformRequest(id);
7109
- return r == null ? void 0 : r.map;
7110
- },
7111
- fetch(id) {
7112
- return ctx.vitenode.fetchModule(id);
7113
- },
7114
- resolveId(id, importer) {
7115
- return ctx.vitenode.resolveId(id, importer);
7116
- },
7117
- onPathsCollected(paths) {
7118
- ctx.state.collectPaths(paths);
7119
- ctx.report("onPathsCollected", paths);
7120
- },
7121
- onCollected(files) {
7122
- ctx.state.collectFiles(files);
7123
- ctx.report("onCollected", files);
7124
- },
7125
- onTaskUpdate(packs) {
7126
- ctx.state.updateTasks(packs);
7127
- ctx.report("onTaskUpdate", packs);
7128
- },
7129
- onUserConsoleLog(log) {
7130
- ctx.state.updateUserLog(log);
7131
- ctx.report("onUserConsoleLog", log);
7132
- },
7133
- onUnhandledRejection(err) {
7134
- ctx.state.catchError(err, "Unhandled Rejection");
7135
- },
7136
- onFinished(files) {
7137
- ctx.report("onFinished", files, ctx.state.getUnhandledErrors());
7138
- }
7139
- }, {
7140
- post(v) {
7141
- 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
+ }
7142
7162
  },
7143
- on(fn) {
7144
- port.on("message", fn);
7163
+ {
7164
+ post(v) {
7165
+ port.postMessage(v);
7166
+ },
7167
+ on(fn) {
7168
+ port.on("message", fn);
7169
+ }
7145
7170
  }
7146
- });
7171
+ );
7147
7172
  return { workerPort, port };
7148
7173
  }
7149
7174
 
@@ -7260,8 +7285,9 @@ function getStateSymbol(task) {
7260
7285
  }
7261
7286
  return picocolors.exports.yellow(spinner());
7262
7287
  }
7263
- if (task.result.state === "pass")
7264
- 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
+ }
7265
7291
  if (task.result.state === "fail") {
7266
7292
  return task.type === "suite" ? pointer : picocolors.exports.red(F_CROSS);
7267
7293
  }
@@ -7395,13 +7421,16 @@ class BaseReporter {
7395
7421
  ];
7396
7422
  this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]);
7397
7423
  this._lastRunTimeout = 0;
7398
- this._lastRunTimer = safeSetInterval(() => {
7399
- this._lastRunTimeout += 1;
7400
- if (this._lastRunTimeout >= LAST_RUN_TEXTS.length)
7401
- this.resetLastRunLog();
7402
- else
7403
- this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]);
7404
- }, 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
+ );
7405
7434
  }
7406
7435
  }
7407
7436
  resetLastRunLog() {
@@ -7450,8 +7479,10 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7450
7479
  return shouldIgnore;
7451
7480
  return true;
7452
7481
  }
7453
- onServerRestart() {
7454
- 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
+ )));
7455
7486
  }
7456
7487
  async reportSummary(files) {
7457
7488
  const logger = this.ctx.logger;
@@ -7486,6 +7517,7 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7486
7517
  var _a2;
7487
7518
  return acc + Math.max(0, ((_a2 = test.result) == null ? void 0 : _a2.duration) || 0);
7488
7519
  }, 0);
7520
+ const transformTime = Array.from(this.ctx.vitenode.fetchCache.values()).reduce((a, b) => a + ((b == null ? void 0 : b.duration) || 0), 0);
7489
7521
  const threadTime = collectTime + testsTime + setupTime;
7490
7522
  const padTitle = (str) => picocolors.exports.dim(`${str.padStart(10)} `);
7491
7523
  const time = (time2) => {
@@ -7495,7 +7527,9 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7495
7527
  };
7496
7528
  const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
7497
7529
  if (snapshotOutput.length) {
7498
- 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"));
7499
7533
  if (snapshotOutput.length > 1)
7500
7534
  logger.log();
7501
7535
  }
@@ -7505,7 +7539,7 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7505
7539
  if (this.watchFilters)
7506
7540
  logger.log(padTitle("Duration"), time(threadTime));
7507
7541
  else
7508
- 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)})`));
7509
7543
  logger.log();
7510
7544
  }
7511
7545
  async printTaskErrors(tasks, errorDivider) {
@@ -7556,6 +7590,10 @@ function formatFilepath(path) {
7556
7590
  firstDot += lastSlash;
7557
7591
  return picocolors.exports.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + picocolors.exports.dim(path.slice(firstDot));
7558
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
+ }
7559
7597
  function renderHookState(task, hookName, level = 0) {
7560
7598
  var _a, _b;
7561
7599
  const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
@@ -7563,27 +7601,65 @@ function renderHookState(task, hookName, level = 0) {
7563
7601
  return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${picocolors.exports.dim(`[ ${hookName} ]`)}`;
7564
7602
  return "";
7565
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
+ }
7566
7638
  function renderTree(tasks, options, level = 0) {
7567
- var _a, _b, _c, _d, _e;
7639
+ var _a, _b, _c, _d, _e, _f;
7568
7640
  let output = [];
7569
7641
  for (const task of tasks) {
7570
7642
  let suffix = "";
7571
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})`);
7572
7646
  if (task.type === "suite")
7573
7647
  suffix += picocolors.exports.dim(` (${getTests(task).length})`);
7574
7648
  if (task.mode === "skip" || task.mode === "todo")
7575
7649
  suffix += ` ${picocolors.exports.dim(picocolors.exports.gray("[skipped]"))}`;
7576
- if (((_a = task.result) == null ? void 0 : _a.duration) != null) {
7650
+ if (((_b = task.result) == null ? void 0 : _b.duration) != null) {
7577
7651
  if (task.result.duration > DURATION_LONG)
7578
7652
  suffix += picocolors.exports.yellow(` ${Math.round(task.result.duration)}${picocolors.exports.dim("ms")}`);
7579
7653
  }
7580
- 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)
7581
7655
  suffix += picocolors.exports.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
7582
7656
  let name = task.name;
7583
7657
  if (level === 0)
7584
7658
  name = formatFilepath(name);
7585
- output.push(" ".repeat(level) + prefix + name + suffix);
7586
- 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) {
7587
7663
  let data = outputMap.get(task);
7588
7664
  if (typeof data === "string") {
7589
7665
  data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
@@ -7598,7 +7674,7 @@ function renderTree(tasks, options, level = 0) {
7598
7674
  output = output.concat(renderHookState(task, "beforeAll", level + 1));
7599
7675
  output = output.concat(renderHookState(task, "beforeEach", level + 1));
7600
7676
  if (task.type === "suite" && task.tasks.length > 0) {
7601
- 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)
7602
7678
  output = output.concat(renderTree(task.tasks, options, level + 1));
7603
7679
  }
7604
7680
  output = output.concat(renderHookState(task, "afterAll", level + 1));
@@ -7799,7 +7875,7 @@ const StatusMap = {
7799
7875
  skip: "skipped",
7800
7876
  todo: "todo"
7801
7877
  };
7802
- class JsonReporter {
7878
+ class JsonReporter$1 {
7803
7879
  constructor() {
7804
7880
  this.start = 0;
7805
7881
  }
@@ -7846,7 +7922,7 @@ class JsonReporter {
7846
7922
  var _a2, _b2;
7847
7923
  return Math.max(prev, (((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? 0) + (((_b2 = next.result) == null ? void 0 : _b2.duration) ?? 0));
7848
7924
  }, startTime);
7849
- const assertionResults = tests2.map((t) => {
7925
+ const assertionResults = await Promise.all(tests2.map(async (t) => {
7850
7926
  var _a2, _b2, _c, _d;
7851
7927
  const ancestorTitles = [];
7852
7928
  let iter = t.suite;
@@ -7862,9 +7938,9 @@ class JsonReporter {
7862
7938
  title: t.name,
7863
7939
  duration: (_b2 = t.result) == null ? void 0 : _b2.duration,
7864
7940
  failureMessages: ((_d = (_c = t.result) == null ? void 0 : _c.error) == null ? void 0 : _d.message) == null ? [] : [t.result.error.message],
7865
- location: this.getFailureLocation(t)
7941
+ location: await this.getFailureLocation(t)
7866
7942
  };
7867
- });
7943
+ }));
7868
7944
  if (tests2.some((t) => {
7869
7945
  var _a2;
7870
7946
  return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
@@ -7915,12 +7991,13 @@ class JsonReporter {
7915
7991
  this.ctx.logger.log(report);
7916
7992
  }
7917
7993
  }
7918
- getFailureLocation(test) {
7994
+ async getFailureLocation(test) {
7919
7995
  var _a;
7920
7996
  const error = (_a = test.result) == null ? void 0 : _a.error;
7921
7997
  if (!error)
7922
7998
  return;
7923
7999
  const stack = parseStacktrace(error);
8000
+ await interpretSourcePos(stack, this.ctx);
7924
8001
  const frame = stack[stack.length - 1];
7925
8002
  if (!frame)
7926
8003
  return;
@@ -8055,17 +8132,24 @@ function removeInvalidXMLCharacters(value, removeDiscouragedChars) {
8055
8132
  let regex = /((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/g;
8056
8133
  value = String(value || "").replace(regex, "");
8057
8134
  if (removeDiscouragedChars) {
8058
- 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
+ );
8059
8139
  value = value.replace(regex, "");
8060
8140
  }
8061
8141
  return value;
8062
8142
  }
8063
8143
  function escapeXML(value) {
8064
- 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
+ );
8065
8148
  }
8066
8149
  function getDuration(task) {
8067
8150
  var _a;
8068
- return ((_a = task.result) == null ? void 0 : _a.duration) ? (task.result.duration / 1e3).toFixed(10) : void 0;
8151
+ const duration = ((_a = task.result) == null ? void 0 : _a.duration) ?? 0;
8152
+ return (duration / 1e3).toLocaleString(void 0, { useGrouping: false, maximumFractionDigits: 10 });
8069
8153
  }
8070
8154
  class JUnitReporter {
8071
8155
  async onInit(ctx) {
@@ -8100,7 +8184,8 @@ class JUnitReporter {
8100
8184
  }
8101
8185
  async writeErrorDetails(error) {
8102
8186
  const errorName = error.name ?? error.nameStr ?? "Unknown Error";
8103
- await this.baseLog(`${errorName}: ${error.message}`);
8187
+ const errorDetails = `${errorName}: ${error.message}`;
8188
+ await this.baseLog(escapeXML(errorDetails));
8104
8189
  const stack = parseStacktrace(error);
8105
8190
  for (const frame of stack) {
8106
8191
  const pos = frame.sourcePos ?? frame;
@@ -8152,18 +8237,21 @@ class JUnitReporter {
8152
8237
  await this.logger.log('<?xml version="1.0" encoding="UTF-8" ?>');
8153
8238
  const transformed = files.map((file) => {
8154
8239
  const tasks = file.tasks.flatMap((task) => flattenTasks$1(task));
8155
- const stats = tasks.reduce((stats2, task) => {
8156
- var _a, _b;
8157
- return {
8158
- passed: stats2.passed + Number(((_a = task.result) == null ? void 0 : _a.state) === "pass"),
8159
- failures: stats2.failures + Number(((_b = task.result) == null ? void 0 : _b.state) === "fail"),
8160
- skipped: stats2.skipped + Number(task.mode === "skip" || task.mode === "todo")
8161
- };
8162
- }, {
8163
- passed: 0,
8164
- failures: 0,
8165
- skipped: 0
8166
- });
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
+ );
8167
8255
  return {
8168
8256
  ...file,
8169
8257
  tasks,
@@ -8213,11 +8301,70 @@ class TapFlatReporter extends TapReporter {
8213
8301
  }
8214
8302
  }
8215
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
+
8216
8363
  const ReportersMap = {
8217
8364
  "default": DefaultReporter,
8218
8365
  "verbose": VerboseReporter,
8219
8366
  "dot": DotReporter,
8220
- "json": JsonReporter,
8367
+ "json": JsonReporter$1,
8221
8368
  "tap": TapReporter,
8222
8369
  "tap-flat": TapFlatReporter,
8223
8370
  "junit": JUnitReporter
@@ -8249,6 +8396,21 @@ function createReporters(reporterReferences, runner) {
8249
8396
  });
8250
8397
  return Promise.all(promisedReporters);
8251
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
+ }
8252
8414
 
8253
8415
  const isAggregateError = (err) => {
8254
8416
  if (typeof AggregateError !== "undefined" && err instanceof AggregateError)
@@ -8349,6 +8511,91 @@ class StateManager {
8349
8511
  }
8350
8512
  }
8351
8513
 
8514
+ const defaultInclude = ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"];
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
+ };
8522
+ const defaultCoverageExcludes = [
8523
+ "coverage/**",
8524
+ "dist/**",
8525
+ "packages/*/test{,s}/**",
8526
+ "**/*.d.ts",
8527
+ "cypress/**",
8528
+ "test{,s}/**",
8529
+ "test{,-*}.{js,cjs,mjs,ts,tsx,jsx}",
8530
+ "**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx}",
8531
+ "**/*{.,-}spec.{js,cjs,mjs,ts,tsx,jsx}",
8532
+ "**/__tests__/**",
8533
+ "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress}.config.{js,cjs,mjs,ts}",
8534
+ "**/.{eslint,mocha,prettier}rc.{js,cjs,yml}"
8535
+ ];
8536
+ const coverageConfigDefaults = {
8537
+ provider: "c8",
8538
+ enabled: false,
8539
+ clean: true,
8540
+ cleanOnRerun: false,
8541
+ reportsDirectory: "./coverage",
8542
+ excludeNodeModules: true,
8543
+ exclude: defaultCoverageExcludes,
8544
+ reporter: ["text", "html", "clover", "json"],
8545
+ allowExternal: false,
8546
+ extension: [".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx", ".vue", ".svelte"]
8547
+ };
8548
+ const fakeTimersDefaults = {
8549
+ loopLimit: 1e4,
8550
+ shouldClearNativeTimers: true,
8551
+ toFake: [
8552
+ "setTimeout",
8553
+ "clearTimeout",
8554
+ "setInterval",
8555
+ "clearInterval",
8556
+ "setImmediate",
8557
+ "clearImmediate",
8558
+ "Date"
8559
+ ]
8560
+ };
8561
+ const config = {
8562
+ allowOnly: !process.env.CI,
8563
+ watch: !process.env.CI,
8564
+ globals: false,
8565
+ environment: "node",
8566
+ threads: true,
8567
+ clearMocks: false,
8568
+ restoreMocks: false,
8569
+ mockReset: false,
8570
+ include: defaultInclude,
8571
+ exclude: defaultExclude,
8572
+ testTimeout: 5e3,
8573
+ hookTimeout: 1e4,
8574
+ teardownTimeout: 1e3,
8575
+ isolate: true,
8576
+ watchExclude: ["**/node_modules/**", "**/dist/**"],
8577
+ forceRerunTriggers: [
8578
+ "**/package.json/**",
8579
+ "**/vitest.config.*/**",
8580
+ "**/vite.config.*/**"
8581
+ ],
8582
+ update: false,
8583
+ reporters: [],
8584
+ silent: false,
8585
+ api: false,
8586
+ ui: false,
8587
+ uiBase: "/__vitest__/",
8588
+ open: true,
8589
+ css: {
8590
+ include: []
8591
+ },
8592
+ coverage: coverageConfigDefaults,
8593
+ fakeTimers: fakeTimersDefaults,
8594
+ maxConcurrency: 5,
8595
+ dangerouslyIgnoreUnhandledErrors: false
8596
+ };
8597
+ const configDefaults = Object.freeze(config);
8598
+
8352
8599
  class FilesStatsCache {
8353
8600
  constructor() {
8354
8601
  this.cache = /* @__PURE__ */ new Map();
@@ -8542,22 +8789,26 @@ function resolveApiConfig(options) {
8542
8789
  }
8543
8790
  return api;
8544
8791
  }
8545
- function resolveConfig(options, viteConfig) {
8546
- var _a, _b, _c, _d, _e;
8792
+ function resolveConfig(mode, options, viteConfig) {
8793
+ var _a, _b, _c, _d, _e, _f;
8547
8794
  if (options.dom) {
8548
8795
  if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
8549
- 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
+ );
8550
8801
  }
8551
8802
  options.environment = "happy-dom";
8552
8803
  }
8553
8804
  const resolved = {
8554
8805
  ...configDefaults,
8555
8806
  ...options,
8556
- root: viteConfig.root
8807
+ root: viteConfig.root,
8808
+ mode
8557
8809
  };
8558
8810
  if (viteConfig.base !== "/")
8559
8811
  resolved.base = viteConfig.base;
8560
- resolved.coverage = resolveC8Options(options.coverage || {}, resolved.root);
8561
8812
  if (options.shard) {
8562
8813
  if (resolved.watch)
8563
8814
  throw new Error("You cannot use --shard option with enabled watch");
@@ -8595,7 +8846,21 @@ function resolveConfig(options, viteConfig) {
8595
8846
  resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS);
8596
8847
  if (process.env.VITEST_MIN_THREADS)
8597
8848
  resolved.minThreads = parseInt(process.env.VITEST_MIN_THREADS);
8598
- 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
+ );
8599
8864
  resolved.api = resolveApiConfig(options);
8600
8865
  if (options.related)
8601
8866
  resolved.related = toArray$1(options.related).map((file) => resolve(resolved.root, file));
@@ -8608,12 +8873,14 @@ function resolveConfig(options, viteConfig) {
8608
8873
  if (resolved.changed)
8609
8874
  resolved.passWithNoTests ?? (resolved.passWithNoTests = true);
8610
8875
  resolved.css ?? (resolved.css = {});
8611
- if (typeof resolved.css === "object")
8612
- (_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
+ }
8613
8880
  resolved.cache ?? (resolved.cache = { dir: "" });
8614
8881
  if (resolved.cache)
8615
8882
  resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir);
8616
- if (!((_e = resolved.sequence) == null ? void 0 : _e.sequencer)) {
8883
+ if (!((_f = resolved.sequence) == null ? void 0 : _f.sequencer)) {
8617
8884
  resolved.sequence ?? (resolved.sequence = {});
8618
8885
  resolved.sequence.sequencer = resolved.sequence.shuffle ? RandomSequencer : BaseSequencer;
8619
8886
  }
@@ -9106,7 +9373,7 @@ createLogUpdate(process$1.stdout);
9106
9373
 
9107
9374
  createLogUpdate(process$1.stderr);
9108
9375
 
9109
- var version = "0.21.1";
9376
+ var version = "0.23.0";
9110
9377
 
9111
9378
  function fileFromParsedStack(stack) {
9112
9379
  var _a, _b;
@@ -9125,7 +9392,9 @@ async function printError(error, ctx, options = {}) {
9125
9392
  }
9126
9393
  const stacks = parseStacktrace(e, fullStack);
9127
9394
  await interpretSourcePos(stacks, ctx);
9128
- 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
+ );
9129
9398
  const errorProperties = getErrorProperties(e);
9130
9399
  if (type)
9131
9400
  printErrorType(type, ctx);
@@ -9139,7 +9408,7 @@ async function printError(error, ctx, options = {}) {
9139
9408
  }
9140
9409
  }
9141
9410
  });
9142
- if (e.cause) {
9411
+ if (e.cause && "name" in e.cause) {
9143
9412
  e.cause.name = `Caused by: ${e.cause.name}`;
9144
9413
  await printError(e.cause, ctx, { fullStack, showCodeFrame: false });
9145
9414
  }
@@ -9193,7 +9462,8 @@ function handleImportOutsideModuleError(stack, ctx) {
9193
9462
  name = name.split("/").slice(0, 2).join("/");
9194
9463
  else
9195
9464
  name = name.split("/")[0];
9196
- 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.
9197
9467
 
9198
9468
  As a temporary workaround you can try to inline the package by updating your config:
9199
9469
 
@@ -9206,7 +9476,8 @@ As a temporary workaround you can try to inline the package by updating your con
9206
9476
  }
9207
9477
  }
9208
9478
  }
9209
- `)));
9479
+ `)
9480
+ ));
9210
9481
  }
9211
9482
  function displayDiff(actual, expected, console, options) {
9212
9483
  console.error(picocolors.exports.gray(unifiedDiff(actual, expected, options)) + "\n");
@@ -9333,9 +9604,11 @@ class Logger {
9333
9604
  if (config.watchExclude)
9334
9605
  this.console.error(picocolors.exports.dim("watch exclude: ") + picocolors.exports.yellow(config.watchExclude.join(comma)));
9335
9606
  if (config.passWithNoTests)
9336
- this.log("No test files found, exiting with code 0\n");
9607
+ this.log(`No ${config.mode} files found, exiting with code 0
9608
+ `);
9337
9609
  else
9338
- 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`));
9339
9612
  }
9340
9613
  printBanner() {
9341
9614
  var _a, _b, _c;
@@ -9349,12 +9622,16 @@ class Logger {
9349
9622
  this.log(picocolors.exports.dim(picocolors.exports.green(` UI started at http://${((_b = this.ctx.config.api) == null ? void 0 : _b.host) || "localhost"}:${picocolors.exports.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`)));
9350
9623
  else if (this.ctx.config.api)
9351
9624
  this.log(picocolors.exports.dim(picocolors.exports.green(` API started at http://${((_c = this.ctx.config.api) == null ? void 0 : _c.host) || "localhost"}:${picocolors.exports.bold(`${this.ctx.config.api.port}`)}`)));
9625
+ if (this.ctx.coverageProvider)
9626
+ this.log(picocolors.exports.dim(" Coverage enabled with ") + picocolors.exports.yellow(this.ctx.coverageProvider.name));
9352
9627
  this.log();
9353
9628
  }
9354
9629
  async printUnhandledErrors(errors) {
9355
- const errorMessage = picocolors.exports.red(picocolors.exports.bold(`
9356
- Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run. This might cause false positive tests.
9357
- Please, resolve all errors to make sure your tests are not affected.`));
9630
+ const errorMessage = picocolors.exports.red(picocolors.exports.bold(
9631
+ `
9632
+ Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
9633
+ This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
9634
+ ));
9358
9635
  this.log(picocolors.exports.red(divider(picocolors.exports.bold(picocolors.exports.inverse(" Unhandled Errors ")))));
9359
9636
  this.log(errorMessage);
9360
9637
  await Promise.all(errors.map(async (err) => {
@@ -9366,7 +9643,8 @@ Please, resolve all errors to make sure your tests are not affected.`));
9366
9643
 
9367
9644
  const WATCHER_DEBOUNCE = 100;
9368
9645
  class Vitest {
9369
- constructor() {
9646
+ constructor(mode) {
9647
+ this.mode = mode;
9370
9648
  this.config = void 0;
9371
9649
  this.server = void 0;
9372
9650
  this.state = void 0;
@@ -9384,13 +9662,13 @@ class Vitest {
9384
9662
  this.logger = new Logger(this);
9385
9663
  }
9386
9664
  async setServer(options, server) {
9387
- var _a, _b;
9665
+ var _a, _b, _c;
9388
9666
  (_a = this.unregisterWatcher) == null ? void 0 : _a.call(this);
9389
9667
  safeClearTimeout(this._rerunTimer);
9390
9668
  this.restartsCount += 1;
9391
9669
  (_b = this.pool) == null ? void 0 : _b.close();
9392
9670
  this.pool = void 0;
9393
- const resolved = resolveConfig(options, server.config);
9671
+ const resolved = resolveConfig(this.mode, options, server.config);
9394
9672
  this.server = server;
9395
9673
  this.config = resolved;
9396
9674
  this.state = new StateManager();
@@ -9410,11 +9688,23 @@ class Vitest {
9410
9688
  return node.resolveId(id, importer);
9411
9689
  }
9412
9690
  });
9413
- 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);
9414
9707
  this.runningPromise = void 0;
9415
- this._onRestartListeners.forEach((fn) => fn());
9416
- if (resolved.coverage.enabled)
9417
- await cleanCoverage(resolved.coverage, resolved.coverage.clean);
9418
9708
  this.cache.results.setConfig(resolved.root, resolved.cache);
9419
9709
  try {
9420
9710
  await this.cache.results.readFromCache();
@@ -9422,24 +9712,47 @@ class Vitest {
9422
9712
  this.logger.error(`[vitest] Error, while trying to parse cache in ${this.cache.results.getCachePath()}:`, err);
9423
9713
  }
9424
9714
  }
9715
+ async initCoverageProvider() {
9716
+ if (this.coverageProvider !== void 0)
9717
+ return;
9718
+ this.coverageProvider = await getCoverageProvider(this.config.coverage);
9719
+ if (this.coverageProvider) {
9720
+ await this.coverageProvider.initialize(this);
9721
+ this.config.coverage = this.coverageProvider.resolveOptions();
9722
+ }
9723
+ return this.coverageProvider;
9724
+ }
9425
9725
  getSerializableConfig() {
9426
- return deepMerge({
9427
- ...this.config,
9428
- reporters: [],
9429
- snapshotOptions: {
9430
- ...this.config.snapshotOptions,
9431
- 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
+ }
9432
9739
  },
9433
- onConsoleLog: void 0,
9434
- sequence: {
9435
- ...this.config.sequence,
9436
- sequencer: void 0
9437
- }
9438
- }, this.configOverride || {});
9740
+ this.configOverride || {}
9741
+ );
9439
9742
  }
9440
9743
  async start(filters) {
9744
+ var _a;
9745
+ try {
9746
+ await this.initCoverageProvider();
9747
+ await ((_a = this.coverageProvider) == null ? void 0 : _a.clean(this.config.coverage.clean));
9748
+ } catch (e) {
9749
+ this.logger.error(e);
9750
+ process.exit(1);
9751
+ }
9441
9752
  await this.report("onInit", this);
9442
- const files = await this.filterTestsBySource(await this.globTestFiles(filters));
9753
+ const files = await this.filterTestsBySource(
9754
+ await this.globTestFiles(filters)
9755
+ );
9443
9756
  if (!files.length) {
9444
9757
  const exitCode = this.config.passWithNoTests ? 0 : 1;
9445
9758
  this.logger.printNoTestFound(filters);
@@ -9447,8 +9760,10 @@ class Vitest {
9447
9760
  }
9448
9761
  await Promise.all(files.map((file) => this.cache.stats.updateStats(file)));
9449
9762
  await this.runFiles(files);
9450
- if (this.config.coverage.enabled)
9451
- await reportCoverage(this);
9763
+ if (this.coverageProvider) {
9764
+ this.logger.log(picocolors.exports.blue(" % ") + picocolors.exports.dim("Coverage report from ") + picocolors.exports.yellow(this.coverageProvider.name));
9765
+ await this.coverageProvider.reportCoverage();
9766
+ }
9452
9767
  if (this.config.watch && !this.config.browser)
9453
9768
  await this.report("onWatcherStart");
9454
9769
  }
@@ -9473,7 +9788,7 @@ class Vitest {
9473
9788
  }
9474
9789
  async filterTestsBySource(tests) {
9475
9790
  if (this.config.changed && !this.config.related) {
9476
- const { VitestGit } = await import('./chunk-node-git.c2be9c49.mjs');
9791
+ const { VitestGit } = await import('./chunk-node-git.6f289b0a.mjs');
9477
9792
  const vitestGit = new VitestGit(this.config.root);
9478
9793
  const related2 = await vitestGit.findChangedFiles({
9479
9794
  changedSince: this.config.changed
@@ -9492,10 +9807,12 @@ class Vitest {
9492
9807
  return tests;
9493
9808
  if (!related.length)
9494
9809
  return [];
9495
- const testDeps = await Promise.all(tests.map(async (filepath) => {
9496
- const deps = await this.getTestDependencies(filepath);
9497
- return [filepath, deps];
9498
- }));
9810
+ const testDeps = await Promise.all(
9811
+ tests.map(async (filepath) => {
9812
+ const deps = await this.getTestDependencies(filepath);
9813
+ return [filepath, deps];
9814
+ })
9815
+ );
9499
9816
  const runningTests = [];
9500
9817
  for (const [filepath, deps] of testDeps) {
9501
9818
  if (deps.size && related.some((path) => path === filepath || deps.has(path)))
@@ -9541,6 +9858,13 @@ class Vitest {
9541
9858
  this.config.testNamePattern = pattern ? new RegExp(pattern) : void 0;
9542
9859
  await this.rerunFiles(files, trigger);
9543
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
+ }
9544
9868
  async rerunFailed() {
9545
9869
  await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed");
9546
9870
  }
@@ -9568,6 +9892,7 @@ class Vitest {
9568
9892
  if (this.restartsCount !== currentCount)
9569
9893
  return;
9570
9894
  this._rerunTimer = safeSetTimeout(async () => {
9895
+ var _a;
9571
9896
  if (this.changedTests.size === 0) {
9572
9897
  this.invalidates.clear();
9573
9898
  return;
@@ -9578,12 +9903,11 @@ class Vitest {
9578
9903
  this.snapshot.clear();
9579
9904
  const files = Array.from(this.changedTests);
9580
9905
  this.changedTests.clear();
9581
- if (this.config.coverage.enabled && this.config.coverage.cleanOnRerun)
9582
- await cleanCoverage(this.config.coverage);
9906
+ if (this.coverageProvider && this.config.coverage.cleanOnRerun)
9907
+ await this.coverageProvider.clean();
9583
9908
  await this.report("onWatcherRerun", files, triggerId);
9584
9909
  await this.runFiles(files);
9585
- if (this.config.coverage.enabled)
9586
- await reportCoverage(this);
9910
+ await ((_a = this.coverageProvider) == null ? void 0 : _a.reportCoverage());
9587
9911
  if (!this.config.browser)
9588
9912
  await this.report("onWatcherStart");
9589
9913
  }, WATCHER_DEBOUNCE);
@@ -9679,22 +10003,26 @@ class Vitest {
9679
10003
  async report(name, ...args) {
9680
10004
  await Promise.all(this.reporters.map((r) => {
9681
10005
  var _a;
9682
- 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
+ );
9683
10010
  }));
9684
10011
  }
9685
10012
  async globTestFiles(filters = []) {
10013
+ const { include, exclude, includeSource } = this.config;
9686
10014
  const globOptions = {
9687
10015
  absolute: true,
9688
10016
  cwd: this.config.dir || this.config.root,
9689
- ignore: this.config.exclude
10017
+ ignore: exclude
9690
10018
  };
9691
- let testFiles = await out(this.config.include, globOptions);
10019
+ let testFiles = await out(include, globOptions);
9692
10020
  if (filters.length && process.platform === "win32")
9693
10021
  filters = filters.map((f) => toNamespacedPath(f));
9694
10022
  if (filters.length)
9695
10023
  testFiles = testFiles.filter((i) => filters.some((f) => i.includes(f)));
9696
- if (this.config.includeSource) {
9697
- let files = await out(this.config.includeSource, globOptions);
10024
+ if (includeSource) {
10025
+ let files = await out(includeSource, globOptions);
9698
10026
  if (filters.length)
9699
10027
  files = files.filter((i) => filters.some((f) => i.includes(f)));
9700
10028
  await Promise.all(files.map(async (file) => {
@@ -9725,18 +10053,32 @@ class Vitest {
9725
10053
  isInSourceTestFile(code) {
9726
10054
  return code.includes("import.meta.vitest");
9727
10055
  }
9728
- onServerRestarted(fn) {
10056
+ onServerRestart(fn) {
9729
10057
  this._onRestartListeners.push(fn);
9730
10058
  }
9731
10059
  }
9732
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
+
9733
10073
  const EnvReplacerPlugin = () => {
9734
10074
  return {
9735
10075
  name: "vitest:env-replacer",
9736
10076
  enforce: "pre",
9737
10077
  transform(code) {
10078
+ if (!/\bimport\.meta\.env\b/g.test(code))
10079
+ return null;
9738
10080
  let s = null;
9739
- const envs = code.matchAll(/\bimport\.meta\.env\b/g);
10081
+ const envs = stripLiteral(code).matchAll(/\bimport\.meta\.env\b/g);
9740
10082
  for (const env of envs) {
9741
10083
  s || (s = new MagicString(code));
9742
10084
  const startIndex = env.index;
@@ -9933,9 +10275,19 @@ function getIndexStatus(code, from) {
9933
10275
 
9934
10276
  const cssLangs = "\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)";
9935
10277
  const cssLangRE = new RegExp(cssLangs);
10278
+ const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
9936
10279
  const isCSS = (id) => {
9937
10280
  return cssLangRE.test(id);
9938
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
+ };
9939
10291
  function CSSEnablerPlugin(ctx) {
9940
10292
  const shouldProcessCSS = (id) => {
9941
10293
  const { css } = ctx.config;
@@ -9947,28 +10299,61 @@ function CSSEnablerPlugin(ctx) {
9947
10299
  return true;
9948
10300
  return false;
9949
10301
  };
9950
- return {
9951
- name: "vitest:css-enabler",
9952
- enforce: "pre",
9953
- transform(code, id) {
9954
- if (!isCSS(id))
9955
- return;
9956
- 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
+ }
9957
10330
  return { code: "" };
10331
+ }
10332
+ }
10333
+ ];
10334
+ }
10335
+
10336
+ function CoverageTransform(ctx) {
10337
+ return {
10338
+ name: "vitest:coverage-transform",
10339
+ transform(srcCode, id) {
10340
+ var _a, _b;
10341
+ return (_b = (_a = ctx.coverageProvider) == null ? void 0 : _a.onFileTransform) == null ? void 0 : _b.call(_a, srcCode, id, this);
9958
10342
  }
9959
10343
  };
9960
10344
  }
9961
10345
 
9962
- async function VitestPlugin(options = {}, ctx = new Vitest()) {
9963
- let haveStarted = false;
9964
- async function UIPlugin() {
10346
+ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
10347
+ const getRoot = () => {
9965
10348
  var _a;
9966
- 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());
9967
10353
  return (await import('@vitest/ui')).default(options.uiBase);
9968
10354
  }
9969
10355
  async function BrowserPlugin() {
9970
- var _a;
9971
- await ensurePackageInstalled("@vitest/browser", ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd());
10356
+ await ensurePackageInstalled("@vitest/browser", getRoot());
9972
10357
  return (await import('@vitest/browser')).default("/");
9973
10358
  }
9974
10359
  return [
@@ -9979,6 +10364,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
9979
10364
  this.meta.watchMode = false;
9980
10365
  },
9981
10366
  config(viteConfig) {
10367
+ var _a, _b, _c;
9982
10368
  const preOptions = deepMerge({}, configDefaults, options, viteConfig.test ?? {});
9983
10369
  preOptions.api = resolveApiConfig(preOptions);
9984
10370
  if (viteConfig.define) {
@@ -10028,6 +10414,15 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10028
10414
  preTransformRequests: false
10029
10415
  }
10030
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
+ }
10031
10426
  if (!options.browser) {
10032
10427
  Object.assign(config, {
10033
10428
  cacheDir: void 0,
@@ -10046,7 +10441,12 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10046
10441
  viteConfigTest.run = true;
10047
10442
  if ("alias" in viteConfigTest)
10048
10443
  delete viteConfigTest.alias;
10049
- options = deepMerge({}, configDefaults, viteConfigTest, options);
10444
+ options = deepMerge(
10445
+ {},
10446
+ configDefaults,
10447
+ viteConfigTest,
10448
+ options
10449
+ );
10050
10450
  options.api = resolveApiConfig(options);
10051
10451
  const { PROD, DEV, ...envs } = viteConfig.env;
10052
10452
  (_a = process.env).PROD ?? (_a.PROD = PROD ? "1" : "");
@@ -10056,13 +10456,10 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10056
10456
  (_d = process.env)[name] ?? (_d[name] = envs[name]);
10057
10457
  },
10058
10458
  async configureServer(server) {
10059
- if (haveStarted)
10060
- await ctx.report("onServerRestart");
10061
10459
  try {
10062
10460
  await ctx.setServer(options, server);
10063
- haveStarted = true;
10064
10461
  if (options.api && options.watch)
10065
- (await import('./chunk-api-setup.7a6ba7fb.mjs')).setup(ctx);
10462
+ (await import('./chunk-api-setup.5fc06d1d.mjs')).setup(ctx);
10066
10463
  } catch (err) {
10067
10464
  ctx.logger.printError(err, true);
10068
10465
  process.exit(1);
@@ -10075,20 +10472,21 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10075
10472
  MocksPlugin(),
10076
10473
  GlobalSetupPlugin(ctx),
10077
10474
  ...options.browser ? await BrowserPlugin() : [],
10078
- CSSEnablerPlugin(ctx),
10475
+ ...CSSEnablerPlugin(ctx),
10476
+ CoverageTransform(ctx),
10079
10477
  options.ui ? await UIPlugin() : null
10080
10478
  ].filter(notNullish);
10081
10479
  }
10082
10480
 
10083
- async function createVitest(options, viteOverrides = {}) {
10481
+ async function createVitest(mode, options, viteOverrides = {}) {
10084
10482
  var _a;
10085
- const ctx = new Vitest();
10483
+ const ctx = new Vitest(mode);
10086
10484
  const root = resolve(options.root || process.cwd());
10087
10485
  const configPath = options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
10088
10486
  const config = {
10089
10487
  logLevel: "error",
10090
10488
  configFile: configPath,
10091
- mode: options.mode || process.env.NODE_ENV || "test",
10489
+ mode: options.mode || process.env.NODE_ENV || mode,
10092
10490
  plugins: await VitestPlugin(options, ctx)
10093
10491
  };
10094
10492
  const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
@@ -10103,16 +10501,20 @@ const keys = [
10103
10501
  ["a", "rerun all tests"],
10104
10502
  ["f", "rerun only failed tests"],
10105
10503
  ["u", "update snapshot"],
10504
+ ["p", "filter by a filename"],
10106
10505
  ["t", "filter by a test name regex pattern"],
10107
10506
  ["q", "quit"]
10108
10507
  ];
10109
10508
  function printShortcutsHelp() {
10110
- stdout().write(`
10509
+ stdout().write(
10510
+ `
10111
10511
  ${picocolors.exports.bold(" Watch Usage")}
10112
10512
  ${keys.map((i) => picocolors.exports.dim(" press ") + picocolors.exports.reset(picocolors.exports.bold(i[0])) + picocolors.exports.dim(` to ${i[1]}`)).join("\n")}
10113
- `);
10513
+ `
10514
+ );
10114
10515
  }
10115
10516
  function registerConsoleShortcuts(ctx) {
10517
+ let latestFilename = "";
10116
10518
  async function _keypressHandler(str, key) {
10117
10519
  if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c")
10118
10520
  return ctx.exit(true);
@@ -10124,11 +10526,13 @@ function registerConsoleShortcuts(ctx) {
10124
10526
  if (name === "u")
10125
10527
  return ctx.updateSnapshot();
10126
10528
  if (name === "a" || name === "return")
10127
- return ctx.rerunFiles(void 0);
10529
+ return ctx.changeNamePattern("");
10128
10530
  if (name === "f")
10129
10531
  return ctx.rerunFailed();
10130
10532
  if (name === "t")
10131
10533
  return inputNamePattern();
10534
+ if (name === "p")
10535
+ return inputFilePattern();
10132
10536
  if (name === "q")
10133
10537
  return ctx.exit(true);
10134
10538
  }
@@ -10146,6 +10550,18 @@ function registerConsoleShortcuts(ctx) {
10146
10550
  await ctx.changeNamePattern(filter, void 0, "change pattern");
10147
10551
  on();
10148
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
+ }
10149
10565
  let rl;
10150
10566
  function on() {
10151
10567
  off();
@@ -10165,7 +10581,7 @@ function registerConsoleShortcuts(ctx) {
10165
10581
  on();
10166
10582
  }
10167
10583
 
10168
- async function startVitest(cliFilters, options, viteOverrides) {
10584
+ async function startVitest(mode, cliFilters, options, viteOverrides) {
10169
10585
  var _a;
10170
10586
  process.env.TEST = "true";
10171
10587
  process.env.VITEST = "true";
@@ -10181,24 +10597,30 @@ async function startVitest(cliFilters, options, viteOverrides) {
10181
10597
  }
10182
10598
  if (typeof options.coverage === "boolean")
10183
10599
  options.coverage = { enabled: options.coverage };
10184
- const ctx = await createVitest(options, viteOverrides);
10185
- if (ctx.config.coverage.enabled) {
10186
- if (!await ensurePackageInstalled("c8", root)) {
10187
- process.exitCode = 1;
10188
- return false;
10600
+ const ctx = await createVitest(mode, options, viteOverrides);
10601
+ if (mode !== "benchmark" && ctx.config.coverage.enabled) {
10602
+ const provider = ctx.config.coverage.provider || "c8";
10603
+ if (typeof provider === "string") {
10604
+ const requiredPackages = CoverageProviderMap[provider];
10605
+ if (!await ensurePackageInstalled(requiredPackages, root)) {
10606
+ process.exitCode = 1;
10607
+ return false;
10608
+ }
10189
10609
  }
10190
10610
  }
10191
- if (ctx.config.environment && ctx.config.environment !== "node") {
10192
- const packageName = envPackageNames[ctx.config.environment];
10193
- if (!await ensurePackageInstalled(packageName, root)) {
10194
- process.exitCode = 1;
10195
- return false;
10196
- }
10611
+ const environmentPackage = getEnvPackageName(ctx.config.environment);
10612
+ if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) {
10613
+ process.exitCode = 1;
10614
+ return false;
10197
10615
  }
10198
10616
  if (process.stdin.isTTY && ctx.config.watch)
10199
10617
  registerConsoleShortcuts(ctx);
10200
- ctx.onServerRestarted(() => {
10201
- 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);
10202
10624
  });
10203
10625
  try {
10204
10626
  await ctx.start(cliFilters);