vitest 0.22.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 (46) hide show
  1. package/LICENSE.md +29 -29
  2. package/dist/browser.d.ts +5 -4
  3. package/dist/browser.mjs +11 -9
  4. package/dist/{chunk-api-setup.377c28aa.mjs → chunk-api-setup.5fc06d1d.mjs} +90 -87
  5. package/dist/{chunk-constants.71e8a211.mjs → chunk-constants.6196597b.mjs} +0 -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.60af7da3.mjs → chunk-integrations-globals.ef598c23.mjs} +6 -7
  10. package/dist/{chunk-magic-string.efe26975.mjs → chunk-magic-string.56b2b543.mjs} +30 -10
  11. package/dist/{chunk-mock-date.304e29b1.mjs → chunk-mock-date.0d86eaa5.mjs} +26 -5
  12. package/dist/{chunk-node-git.9a7e3153.mjs → chunk-node-git.6f289b0a.mjs} +18 -12
  13. package/dist/{chunk-runtime-chain.be610650.mjs → chunk-runtime-chain.2af36ddf.mjs} +507 -173
  14. package/dist/{chunk-runtime-error.1104e45a.mjs → chunk-runtime-error.ed9b4f70.mjs} +206 -75
  15. package/dist/{chunk-runtime-hooks.5d7073db.mjs → chunk-runtime-hooks.75ce0575.mjs} +18 -12
  16. package/dist/{chunk-runtime-mocker.49d21aa6.mjs → chunk-runtime-mocker.fc76f21d.mjs} +17 -10
  17. package/dist/{chunk-runtime-rpc.57586b73.mjs → chunk-runtime-rpc.3fe371e9.mjs} +1 -2
  18. package/dist/{chunk-utils-source-map.bbf3ad19.mjs → chunk-utils-source-map.70ee97e1.mjs} +11 -5
  19. package/dist/{chunk-vite-node-client.cddda63d.mjs → chunk-vite-node-client.74ebe3d5.mjs} +55 -13
  20. package/dist/{chunk-vite-node-debug.536c4c5b.mjs → chunk-vite-node-debug.2d8a1dc3.mjs} +1 -1
  21. package/dist/{chunk-vite-node-externalize.c843f497.mjs → chunk-vite-node-externalize.41bf722e.mjs} +483 -197
  22. package/dist/{chunk-vite-node-utils.b432150c.mjs → chunk-vite-node-utils.68573626.mjs} +24 -40
  23. package/dist/cli-wrapper.mjs +21 -17
  24. package/dist/cli.mjs +23 -15
  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 +19 -14
  29. package/dist/environments.d.ts +23 -0
  30. package/dist/environments.mjs +3 -0
  31. package/dist/{global-fe52f84b.d.ts → global-ea084c9f.d.ts} +135 -19
  32. package/dist/{index-ea17aa0c.d.ts → index-5f09f4d0.d.ts} +3 -2
  33. package/dist/index.d.ts +6 -5
  34. package/dist/index.mjs +6 -7
  35. package/dist/loader.mjs +3 -4
  36. package/dist/node.d.ts +5 -4
  37. package/dist/node.mjs +14 -12
  38. package/dist/suite.mjs +5 -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 +17 -15
  45. package/package.json +17 -10
  46. package/dist/chunk-utils-global.fa20c2f6.mjs +0 -5
@@ -1,6 +1,7 @@
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.71e8a211.mjs';
2
- import { p as pLimit, g as getCoverageProvider, a as envPackageNames, C as CoverageProviderMap } from './chunk-integrations-coverage.d205bd87.mjs';
3
- import { A as AggregateErrorPonyfill, s as slash$2, j as isNode, k as relativePath, v as getTests, d as getFullName, u as hasFailed, w as hasFailedSnapshot, x as getSuites, o as shuffle, t as toArray$1, n as noop$1, y as deepMerge, g as getCallLastIndex, e as notNullish, z as ensurePackageInstalled, B as stdout } from './chunk-mock-date.304e29b1.mjs';
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';
4
5
  import { loadConfigFromFile, normalizePath, createServer, mergeConfig } from 'vite';
5
6
  import path$a from 'path';
6
7
  import url, { fileURLToPath } from 'url';
@@ -11,23 +12,24 @@ 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.cddda63d.mjs';
15
+ import { c as createBirpc, V as ViteNodeRunner } from './chunk-vite-node-client.74ebe3d5.mjs';
15
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.b432150c.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';
18
19
  import { MessageChannel } from 'worker_threads';
19
20
  import { Tinypool } from 'tinypool';
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.bbf3ad19.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 } from './vendor-index.9d9196cc.mjs';
25
- import { s as signalExit } from './vendor-index.29636037.mjs';
26
- 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';
27
29
  import require$$0$2 from 'readline';
28
30
  import { p as prompts } from './vendor-index.ae96af6e.mjs';
29
31
 
30
- var version$1 = "0.22.1";
32
+ var version$1 = "0.23.0";
31
33
 
32
34
  class EndError extends Error {
33
35
  constructor(value) {
@@ -82,14 +84,14 @@ const typeMappings = {
82
84
  };
83
85
 
84
86
  function checkType(type) {
85
- if (type in typeMappings) {
87
+ if (Object.hasOwnProperty.call(typeMappings, type)) {
86
88
  return;
87
89
  }
88
90
 
89
91
  throw new Error(`Invalid type specified: ${type}`);
90
92
  }
91
93
 
92
- const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
94
+ const matchType = (type, stat) => stat[typeMappings[type]]();
93
95
 
94
96
  const toPath$1 = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
95
97
 
@@ -6851,7 +6853,7 @@ class ViteNodeServer {
6851
6853
  }, options.debug ?? {});
6852
6854
  }
6853
6855
  if (options.debug)
6854
- import('./chunk-vite-node-debug.536c4c5b.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));
6855
6857
  }
6856
6858
  shouldExternalize(id) {
6857
6859
  return shouldExternalize(id, this.options.deps, this.externalizeCache);
@@ -6864,19 +6866,25 @@ class ViteNodeServer {
6864
6866
  }
6865
6867
  async fetchModule(id) {
6866
6868
  if (!this.fetchPromiseMap.has(id)) {
6867
- this.fetchPromiseMap.set(id, this._fetchModule(id).then((r) => {
6868
- return this.options.sourcemap !== true ? { ...r, map: void 0 } : r;
6869
- }).finally(() => {
6870
- this.fetchPromiseMap.delete(id);
6871
- }));
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
+ );
6872
6877
  }
6873
6878
  return this.fetchPromiseMap.get(id);
6874
6879
  }
6875
6880
  async transformRequest(id) {
6876
6881
  if (!this.transformPromiseMap.has(id)) {
6877
- this.transformPromiseMap.set(id, this._transformRequest(id).finally(() => {
6878
- this.transformPromiseMap.delete(id);
6879
- }));
6882
+ this.transformPromiseMap.set(
6883
+ id,
6884
+ this._transformRequest(id).finally(() => {
6885
+ this.transformPromiseMap.delete(id);
6886
+ })
6887
+ );
6880
6888
  }
6881
6889
  return this.transformPromiseMap.get(id);
6882
6890
  }
@@ -6958,7 +6966,13 @@ class SnapshotManager {
6958
6966
  }
6959
6967
  resolvePath(testPath) {
6960
6968
  const resolver = this.options.resolveSnapshotPath || (() => {
6961
- 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
+ );
6962
6976
  });
6963
6977
  return resolver(testPath, this.extension);
6964
6978
  }
@@ -7013,7 +7027,7 @@ function createPool(ctx) {
7013
7027
  const threadsCount = ctx.config.watch ? Math.max(Math.floor(cpus().length / 2), 1) : Math.max(cpus().length - 1, 1);
7014
7028
  const maxThreads = ctx.config.maxThreads ?? threadsCount;
7015
7029
  const minThreads = ctx.config.minThreads ?? threadsCount;
7016
- 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])) || [];
7017
7031
  const options = {
7018
7032
  filename: workerPath,
7019
7033
  useAtomics: false,
@@ -7024,8 +7038,8 @@ function createPool(ctx) {
7024
7038
  suppressLoaderWarningsPath,
7025
7039
  "--experimental-loader",
7026
7040
  loaderPath,
7027
- ...conditions || []
7028
- ] : []
7041
+ ...conditions
7042
+ ] : conditions
7029
7043
  };
7030
7044
  if (ctx.config.isolate) {
7031
7045
  options.isolateWorkers = true;
@@ -7093,65 +7107,68 @@ function createChannel(ctx) {
7093
7107
  const channel = new MessageChannel();
7094
7108
  const port = channel.port2;
7095
7109
  const workerPort = channel.port1;
7096
- createBirpc({
7097
- onWorkerExit(code) {
7098
- process.exit(code || 1);
7099
- },
7100
- snapshotSaved(snapshot) {
7101
- ctx.snapshot.add(snapshot);
7102
- },
7103
- resolveSnapshotPath(testPath) {
7104
- return ctx.snapshot.resolvePath(testPath);
7105
- },
7106
- async getSourceMap(id, force) {
7107
- if (force) {
7108
- const mod = ctx.server.moduleGraph.getModuleById(id);
7109
- if (mod)
7110
- ctx.server.moduleGraph.invalidateModule(mod);
7111
- }
7112
- const r = await ctx.vitenode.transformRequest(id);
7113
- return r == null ? void 0 : r.map;
7114
- },
7115
- fetch(id) {
7116
- return ctx.vitenode.fetchModule(id);
7117
- },
7118
- resolveId(id, importer) {
7119
- return ctx.vitenode.resolveId(id, importer);
7120
- },
7121
- onPathsCollected(paths) {
7122
- ctx.state.collectPaths(paths);
7123
- ctx.report("onPathsCollected", paths);
7124
- },
7125
- onCollected(files) {
7126
- ctx.state.collectFiles(files);
7127
- ctx.report("onCollected", files);
7128
- },
7129
- onAfterSuiteRun(meta) {
7130
- var _a;
7131
- (_a = ctx.coverageProvider) == null ? void 0 : _a.onAfterSuiteRun(meta);
7132
- },
7133
- onTaskUpdate(packs) {
7134
- ctx.state.updateTasks(packs);
7135
- ctx.report("onTaskUpdate", packs);
7136
- },
7137
- onUserConsoleLog(log) {
7138
- ctx.state.updateUserLog(log);
7139
- ctx.report("onUserConsoleLog", log);
7140
- },
7141
- onUnhandledRejection(err) {
7142
- ctx.state.catchError(err, "Unhandled Rejection");
7143
- },
7144
- onFinished(files) {
7145
- ctx.report("onFinished", files, ctx.state.getUnhandledErrors());
7146
- }
7147
- }, {
7148
- post(v) {
7149
- 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
+ }
7150
7162
  },
7151
- on(fn) {
7152
- port.on("message", fn);
7163
+ {
7164
+ post(v) {
7165
+ port.postMessage(v);
7166
+ },
7167
+ on(fn) {
7168
+ port.on("message", fn);
7169
+ }
7153
7170
  }
7154
- });
7171
+ );
7155
7172
  return { workerPort, port };
7156
7173
  }
7157
7174
 
@@ -7268,8 +7285,9 @@ function getStateSymbol(task) {
7268
7285
  }
7269
7286
  return picocolors.exports.yellow(spinner());
7270
7287
  }
7271
- if (task.result.state === "pass")
7272
- 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
+ }
7273
7291
  if (task.result.state === "fail") {
7274
7292
  return task.type === "suite" ? pointer : picocolors.exports.red(F_CROSS);
7275
7293
  }
@@ -7403,13 +7421,16 @@ class BaseReporter {
7403
7421
  ];
7404
7422
  this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]);
7405
7423
  this._lastRunTimeout = 0;
7406
- this._lastRunTimer = safeSetInterval(() => {
7407
- this._lastRunTimeout += 1;
7408
- if (this._lastRunTimeout >= LAST_RUN_TEXTS.length)
7409
- this.resetLastRunLog();
7410
- else
7411
- this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]);
7412
- }, 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
+ );
7413
7434
  }
7414
7435
  }
7415
7436
  resetLastRunLog() {
@@ -7459,7 +7480,9 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7459
7480
  return true;
7460
7481
  }
7461
7482
  onServerRestart(reason) {
7462
- this.ctx.logger.log(picocolors.exports.bold(picocolors.exports.magenta(reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest...")));
7483
+ this.ctx.logger.log(picocolors.exports.bold(picocolors.exports.magenta(
7484
+ reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest..."
7485
+ )));
7463
7486
  }
7464
7487
  async reportSummary(files) {
7465
7488
  const logger = this.ctx.logger;
@@ -7504,7 +7527,9 @@ ${BADGE}${TRIGGER} ${picocolors.exports.blue(`x${rerun}`)}
7504
7527
  };
7505
7528
  const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
7506
7529
  if (snapshotOutput.length) {
7507
- 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"));
7508
7533
  if (snapshotOutput.length > 1)
7509
7534
  logger.log();
7510
7535
  }
@@ -7565,6 +7590,10 @@ function formatFilepath(path) {
7565
7590
  firstDot += lastSlash;
7566
7591
  return picocolors.exports.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + picocolors.exports.dim(path.slice(firstDot));
7567
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
+ }
7568
7597
  function renderHookState(task, hookName, level = 0) {
7569
7598
  var _a, _b;
7570
7599
  const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
@@ -7572,27 +7601,65 @@ function renderHookState(task, hookName, level = 0) {
7572
7601
  return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${picocolors.exports.dim(`[ ${hookName} ]`)}`;
7573
7602
  return "";
7574
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
+ }
7575
7638
  function renderTree(tasks, options, level = 0) {
7576
- var _a, _b, _c, _d, _e;
7639
+ var _a, _b, _c, _d, _e, _f;
7577
7640
  let output = [];
7578
7641
  for (const task of tasks) {
7579
7642
  let suffix = "";
7580
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})`);
7581
7646
  if (task.type === "suite")
7582
7647
  suffix += picocolors.exports.dim(` (${getTests(task).length})`);
7583
7648
  if (task.mode === "skip" || task.mode === "todo")
7584
7649
  suffix += ` ${picocolors.exports.dim(picocolors.exports.gray("[skipped]"))}`;
7585
- if (((_a = task.result) == null ? void 0 : _a.duration) != null) {
7650
+ if (((_b = task.result) == null ? void 0 : _b.duration) != null) {
7586
7651
  if (task.result.duration > DURATION_LONG)
7587
7652
  suffix += picocolors.exports.yellow(` ${Math.round(task.result.duration)}${picocolors.exports.dim("ms")}`);
7588
7653
  }
7589
- 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)
7590
7655
  suffix += picocolors.exports.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
7591
7656
  let name = task.name;
7592
7657
  if (level === 0)
7593
7658
  name = formatFilepath(name);
7594
- output.push(" ".repeat(level) + prefix + name + suffix);
7595
- 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) {
7596
7663
  let data = outputMap.get(task);
7597
7664
  if (typeof data === "string") {
7598
7665
  data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
@@ -7607,7 +7674,7 @@ function renderTree(tasks, options, level = 0) {
7607
7674
  output = output.concat(renderHookState(task, "beforeAll", level + 1));
7608
7675
  output = output.concat(renderHookState(task, "beforeEach", level + 1));
7609
7676
  if (task.type === "suite" && task.tasks.length > 0) {
7610
- 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)
7611
7678
  output = output.concat(renderTree(task.tasks, options, level + 1));
7612
7679
  }
7613
7680
  output = output.concat(renderHookState(task, "afterAll", level + 1));
@@ -7808,7 +7875,7 @@ const StatusMap = {
7808
7875
  skip: "skipped",
7809
7876
  todo: "todo"
7810
7877
  };
7811
- class JsonReporter {
7878
+ class JsonReporter$1 {
7812
7879
  constructor() {
7813
7880
  this.start = 0;
7814
7881
  }
@@ -7855,7 +7922,7 @@ class JsonReporter {
7855
7922
  var _a2, _b2;
7856
7923
  return Math.max(prev, (((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? 0) + (((_b2 = next.result) == null ? void 0 : _b2.duration) ?? 0));
7857
7924
  }, startTime);
7858
- const assertionResults = tests2.map((t) => {
7925
+ const assertionResults = await Promise.all(tests2.map(async (t) => {
7859
7926
  var _a2, _b2, _c, _d;
7860
7927
  const ancestorTitles = [];
7861
7928
  let iter = t.suite;
@@ -7871,9 +7938,9 @@ class JsonReporter {
7871
7938
  title: t.name,
7872
7939
  duration: (_b2 = t.result) == null ? void 0 : _b2.duration,
7873
7940
  failureMessages: ((_d = (_c = t.result) == null ? void 0 : _c.error) == null ? void 0 : _d.message) == null ? [] : [t.result.error.message],
7874
- location: this.getFailureLocation(t)
7941
+ location: await this.getFailureLocation(t)
7875
7942
  };
7876
- });
7943
+ }));
7877
7944
  if (tests2.some((t) => {
7878
7945
  var _a2;
7879
7946
  return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
@@ -7924,12 +7991,13 @@ class JsonReporter {
7924
7991
  this.ctx.logger.log(report);
7925
7992
  }
7926
7993
  }
7927
- getFailureLocation(test) {
7994
+ async getFailureLocation(test) {
7928
7995
  var _a;
7929
7996
  const error = (_a = test.result) == null ? void 0 : _a.error;
7930
7997
  if (!error)
7931
7998
  return;
7932
7999
  const stack = parseStacktrace(error);
8000
+ await interpretSourcePos(stack, this.ctx);
7933
8001
  const frame = stack[stack.length - 1];
7934
8002
  if (!frame)
7935
8003
  return;
@@ -8064,13 +8132,19 @@ function removeInvalidXMLCharacters(value, removeDiscouragedChars) {
8064
8132
  let regex = /((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/g;
8065
8133
  value = String(value || "").replace(regex, "");
8066
8134
  if (removeDiscouragedChars) {
8067
- 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
+ );
8068
8139
  value = value.replace(regex, "");
8069
8140
  }
8070
8141
  return value;
8071
8142
  }
8072
8143
  function escapeXML(value) {
8073
- 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
+ );
8074
8148
  }
8075
8149
  function getDuration(task) {
8076
8150
  var _a;
@@ -8110,7 +8184,8 @@ class JUnitReporter {
8110
8184
  }
8111
8185
  async writeErrorDetails(error) {
8112
8186
  const errorName = error.name ?? error.nameStr ?? "Unknown Error";
8113
- await this.baseLog(`${errorName}: ${error.message}`);
8187
+ const errorDetails = `${errorName}: ${error.message}`;
8188
+ await this.baseLog(escapeXML(errorDetails));
8114
8189
  const stack = parseStacktrace(error);
8115
8190
  for (const frame of stack) {
8116
8191
  const pos = frame.sourcePos ?? frame;
@@ -8162,18 +8237,21 @@ class JUnitReporter {
8162
8237
  await this.logger.log('<?xml version="1.0" encoding="UTF-8" ?>');
8163
8238
  const transformed = files.map((file) => {
8164
8239
  const tasks = file.tasks.flatMap((task) => flattenTasks$1(task));
8165
- const stats = tasks.reduce((stats2, task) => {
8166
- var _a, _b;
8167
- return {
8168
- passed: stats2.passed + Number(((_a = task.result) == null ? void 0 : _a.state) === "pass"),
8169
- failures: stats2.failures + Number(((_b = task.result) == null ? void 0 : _b.state) === "fail"),
8170
- skipped: stats2.skipped + Number(task.mode === "skip" || task.mode === "todo")
8171
- };
8172
- }, {
8173
- passed: 0,
8174
- failures: 0,
8175
- skipped: 0
8176
- });
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
+ );
8177
8255
  return {
8178
8256
  ...file,
8179
8257
  tasks,
@@ -8223,11 +8301,70 @@ class TapFlatReporter extends TapReporter {
8223
8301
  }
8224
8302
  }
8225
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
+
8226
8363
  const ReportersMap = {
8227
8364
  "default": DefaultReporter,
8228
8365
  "verbose": VerboseReporter,
8229
8366
  "dot": DotReporter,
8230
- "json": JsonReporter,
8367
+ "json": JsonReporter$1,
8231
8368
  "tap": TapReporter,
8232
8369
  "tap-flat": TapFlatReporter,
8233
8370
  "junit": JUnitReporter
@@ -8259,6 +8396,21 @@ function createReporters(reporterReferences, runner) {
8259
8396
  });
8260
8397
  return Promise.all(promisedReporters);
8261
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
+ }
8262
8414
 
8263
8415
  const isAggregateError = (err) => {
8264
8416
  if (typeof AggregateError !== "undefined" && err instanceof AggregateError)
@@ -8361,6 +8513,12 @@ class StateManager {
8361
8513
 
8362
8514
  const defaultInclude = ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"];
8363
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
+ };
8364
8522
  const defaultCoverageExcludes = [
8365
8523
  "coverage/**",
8366
8524
  "dist/**",
@@ -8383,7 +8541,7 @@ const coverageConfigDefaults = {
8383
8541
  reportsDirectory: "./coverage",
8384
8542
  excludeNodeModules: true,
8385
8543
  exclude: defaultCoverageExcludes,
8386
- reporter: ["text", "html", "clover"],
8544
+ reporter: ["text", "html", "clover", "json"],
8387
8545
  allowExternal: false,
8388
8546
  extension: [".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx", ".vue", ".svelte"]
8389
8547
  };
@@ -8429,7 +8587,7 @@ const config = {
8429
8587
  uiBase: "/__vitest__/",
8430
8588
  open: true,
8431
8589
  css: {
8432
- include: [/\.module\./]
8590
+ include: []
8433
8591
  },
8434
8592
  coverage: coverageConfigDefaults,
8435
8593
  fakeTimers: fakeTimersDefaults,
@@ -8631,18 +8789,23 @@ function resolveApiConfig(options) {
8631
8789
  }
8632
8790
  return api;
8633
8791
  }
8634
- function resolveConfig(options, viteConfig) {
8635
- var _a, _b, _c, _d, _e;
8792
+ function resolveConfig(mode, options, viteConfig) {
8793
+ var _a, _b, _c, _d, _e, _f;
8636
8794
  if (options.dom) {
8637
8795
  if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
8638
- 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
+ );
8639
8801
  }
8640
8802
  options.environment = "happy-dom";
8641
8803
  }
8642
8804
  const resolved = {
8643
8805
  ...configDefaults,
8644
8806
  ...options,
8645
- root: viteConfig.root
8807
+ root: viteConfig.root,
8808
+ mode
8646
8809
  };
8647
8810
  if (viteConfig.base !== "/")
8648
8811
  resolved.base = viteConfig.base;
@@ -8683,7 +8846,21 @@ function resolveConfig(options, viteConfig) {
8683
8846
  resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS);
8684
8847
  if (process.env.VITEST_MIN_THREADS)
8685
8848
  resolved.minThreads = parseInt(process.env.VITEST_MIN_THREADS);
8686
- 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
+ );
8687
8864
  resolved.api = resolveApiConfig(options);
8688
8865
  if (options.related)
8689
8866
  resolved.related = toArray$1(options.related).map((file) => resolve(resolved.root, file));
@@ -8696,12 +8873,14 @@ function resolveConfig(options, viteConfig) {
8696
8873
  if (resolved.changed)
8697
8874
  resolved.passWithNoTests ?? (resolved.passWithNoTests = true);
8698
8875
  resolved.css ?? (resolved.css = {});
8699
- if (typeof resolved.css === "object")
8700
- (_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
+ }
8701
8880
  resolved.cache ?? (resolved.cache = { dir: "" });
8702
8881
  if (resolved.cache)
8703
8882
  resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir);
8704
- if (!((_e = resolved.sequence) == null ? void 0 : _e.sequencer)) {
8883
+ if (!((_f = resolved.sequence) == null ? void 0 : _f.sequencer)) {
8705
8884
  resolved.sequence ?? (resolved.sequence = {});
8706
8885
  resolved.sequence.sequencer = resolved.sequence.shuffle ? RandomSequencer : BaseSequencer;
8707
8886
  }
@@ -9194,7 +9373,7 @@ createLogUpdate(process$1.stdout);
9194
9373
 
9195
9374
  createLogUpdate(process$1.stderr);
9196
9375
 
9197
- var version = "0.22.1";
9376
+ var version = "0.23.0";
9198
9377
 
9199
9378
  function fileFromParsedStack(stack) {
9200
9379
  var _a, _b;
@@ -9213,7 +9392,9 @@ async function printError(error, ctx, options = {}) {
9213
9392
  }
9214
9393
  const stacks = parseStacktrace(e, fullStack);
9215
9394
  await interpretSourcePos(stacks, ctx);
9216
- 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
+ );
9217
9398
  const errorProperties = getErrorProperties(e);
9218
9399
  if (type)
9219
9400
  printErrorType(type, ctx);
@@ -9227,7 +9408,7 @@ async function printError(error, ctx, options = {}) {
9227
9408
  }
9228
9409
  }
9229
9410
  });
9230
- if (e.cause) {
9411
+ if (e.cause && "name" in e.cause) {
9231
9412
  e.cause.name = `Caused by: ${e.cause.name}`;
9232
9413
  await printError(e.cause, ctx, { fullStack, showCodeFrame: false });
9233
9414
  }
@@ -9281,7 +9462,8 @@ function handleImportOutsideModuleError(stack, ctx) {
9281
9462
  name = name.split("/").slice(0, 2).join("/");
9282
9463
  else
9283
9464
  name = name.split("/")[0];
9284
- 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.
9285
9467
 
9286
9468
  As a temporary workaround you can try to inline the package by updating your config:
9287
9469
 
@@ -9294,7 +9476,8 @@ As a temporary workaround you can try to inline the package by updating your con
9294
9476
  }
9295
9477
  }
9296
9478
  }
9297
- `)));
9479
+ `)
9480
+ ));
9298
9481
  }
9299
9482
  function displayDiff(actual, expected, console, options) {
9300
9483
  console.error(picocolors.exports.gray(unifiedDiff(actual, expected, options)) + "\n");
@@ -9421,9 +9604,11 @@ class Logger {
9421
9604
  if (config.watchExclude)
9422
9605
  this.console.error(picocolors.exports.dim("watch exclude: ") + picocolors.exports.yellow(config.watchExclude.join(comma)));
9423
9606
  if (config.passWithNoTests)
9424
- this.log("No test files found, exiting with code 0\n");
9607
+ this.log(`No ${config.mode} files found, exiting with code 0
9608
+ `);
9425
9609
  else
9426
- 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`));
9427
9612
  }
9428
9613
  printBanner() {
9429
9614
  var _a, _b, _c;
@@ -9442,9 +9627,11 @@ class Logger {
9442
9627
  this.log();
9443
9628
  }
9444
9629
  async printUnhandledErrors(errors) {
9445
- const errorMessage = picocolors.exports.red(picocolors.exports.bold(`
9630
+ const errorMessage = picocolors.exports.red(picocolors.exports.bold(
9631
+ `
9446
9632
  Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
9447
- 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
+ ));
9448
9635
  this.log(picocolors.exports.red(divider(picocolors.exports.bold(picocolors.exports.inverse(" Unhandled Errors ")))));
9449
9636
  this.log(errorMessage);
9450
9637
  await Promise.all(errors.map(async (err) => {
@@ -9456,7 +9643,8 @@ This might cause false positive tests. Resolve unhandled errors to make sure you
9456
9643
 
9457
9644
  const WATCHER_DEBOUNCE = 100;
9458
9645
  class Vitest {
9459
- constructor() {
9646
+ constructor(mode) {
9647
+ this.mode = mode;
9460
9648
  this.config = void 0;
9461
9649
  this.server = void 0;
9462
9650
  this.state = void 0;
@@ -9480,7 +9668,7 @@ class Vitest {
9480
9668
  this.restartsCount += 1;
9481
9669
  (_b = this.pool) == null ? void 0 : _b.close();
9482
9670
  this.pool = void 0;
9483
- const resolved = resolveConfig(options, server.config);
9671
+ const resolved = resolveConfig(this.mode, options, server.config);
9484
9672
  this.server = server;
9485
9673
  this.config = resolved;
9486
9674
  this.state = new StateManager();
@@ -9515,9 +9703,8 @@ class Vitest {
9515
9703
  }
9516
9704
  });
9517
9705
  }
9518
- this.reporters = await createReporters(resolved.reporters, this.runner);
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);
9519
9707
  this.runningPromise = void 0;
9520
- await ((_c = this.coverageProvider) == null ? void 0 : _c.clean(this.config.coverage.clean));
9521
9708
  this.cache.results.setConfig(resolved.root, resolved.cache);
9522
9709
  try {
9523
9710
  await this.cache.results.readFromCache();
@@ -9536,29 +9723,36 @@ class Vitest {
9536
9723
  return this.coverageProvider;
9537
9724
  }
9538
9725
  getSerializableConfig() {
9539
- return deepMerge({
9540
- ...this.config,
9541
- reporters: [],
9542
- snapshotOptions: {
9543
- ...this.config.snapshotOptions,
9544
- 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
+ }
9545
9739
  },
9546
- onConsoleLog: void 0,
9547
- sequence: {
9548
- ...this.config.sequence,
9549
- sequencer: void 0
9550
- }
9551
- }, this.configOverride || {});
9740
+ this.configOverride || {}
9741
+ );
9552
9742
  }
9553
9743
  async start(filters) {
9744
+ var _a;
9554
9745
  try {
9555
9746
  await this.initCoverageProvider();
9747
+ await ((_a = this.coverageProvider) == null ? void 0 : _a.clean(this.config.coverage.clean));
9556
9748
  } catch (e) {
9557
9749
  this.logger.error(e);
9558
9750
  process.exit(1);
9559
9751
  }
9560
9752
  await this.report("onInit", this);
9561
- const files = await this.filterTestsBySource(await this.globTestFiles(filters));
9753
+ const files = await this.filterTestsBySource(
9754
+ await this.globTestFiles(filters)
9755
+ );
9562
9756
  if (!files.length) {
9563
9757
  const exitCode = this.config.passWithNoTests ? 0 : 1;
9564
9758
  this.logger.printNoTestFound(filters);
@@ -9594,7 +9788,7 @@ class Vitest {
9594
9788
  }
9595
9789
  async filterTestsBySource(tests) {
9596
9790
  if (this.config.changed && !this.config.related) {
9597
- const { VitestGit } = await import('./chunk-node-git.9a7e3153.mjs');
9791
+ const { VitestGit } = await import('./chunk-node-git.6f289b0a.mjs');
9598
9792
  const vitestGit = new VitestGit(this.config.root);
9599
9793
  const related2 = await vitestGit.findChangedFiles({
9600
9794
  changedSince: this.config.changed
@@ -9613,10 +9807,12 @@ class Vitest {
9613
9807
  return tests;
9614
9808
  if (!related.length)
9615
9809
  return [];
9616
- const testDeps = await Promise.all(tests.map(async (filepath) => {
9617
- const deps = await this.getTestDependencies(filepath);
9618
- return [filepath, deps];
9619
- }));
9810
+ const testDeps = await Promise.all(
9811
+ tests.map(async (filepath) => {
9812
+ const deps = await this.getTestDependencies(filepath);
9813
+ return [filepath, deps];
9814
+ })
9815
+ );
9620
9816
  const runningTests = [];
9621
9817
  for (const [filepath, deps] of testDeps) {
9622
9818
  if (deps.size && related.some((path) => path === filepath || deps.has(path)))
@@ -9662,6 +9858,13 @@ class Vitest {
9662
9858
  this.config.testNamePattern = pattern ? new RegExp(pattern) : void 0;
9663
9859
  await this.rerunFiles(files, trigger);
9664
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
+ }
9665
9868
  async rerunFailed() {
9666
9869
  await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed");
9667
9870
  }
@@ -9800,22 +10003,26 @@ class Vitest {
9800
10003
  async report(name, ...args) {
9801
10004
  await Promise.all(this.reporters.map((r) => {
9802
10005
  var _a;
9803
- 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
+ );
9804
10010
  }));
9805
10011
  }
9806
10012
  async globTestFiles(filters = []) {
10013
+ const { include, exclude, includeSource } = this.config;
9807
10014
  const globOptions = {
9808
10015
  absolute: true,
9809
10016
  cwd: this.config.dir || this.config.root,
9810
- ignore: this.config.exclude
10017
+ ignore: exclude
9811
10018
  };
9812
- let testFiles = await out(this.config.include, globOptions);
10019
+ let testFiles = await out(include, globOptions);
9813
10020
  if (filters.length && process.platform === "win32")
9814
10021
  filters = filters.map((f) => toNamespacedPath(f));
9815
10022
  if (filters.length)
9816
10023
  testFiles = testFiles.filter((i) => filters.some((f) => i.includes(f)));
9817
- if (this.config.includeSource) {
9818
- let files = await out(this.config.includeSource, globOptions);
10024
+ if (includeSource) {
10025
+ let files = await out(includeSource, globOptions);
9819
10026
  if (filters.length)
9820
10027
  files = files.filter((i) => filters.some((f) => i.includes(f)));
9821
10028
  await Promise.all(files.map(async (file) => {
@@ -9851,13 +10058,27 @@ class Vitest {
9851
10058
  }
9852
10059
  }
9853
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
+
9854
10073
  const EnvReplacerPlugin = () => {
9855
10074
  return {
9856
10075
  name: "vitest:env-replacer",
9857
10076
  enforce: "pre",
9858
10077
  transform(code) {
10078
+ if (!/\bimport\.meta\.env\b/g.test(code))
10079
+ return null;
9859
10080
  let s = null;
9860
- const envs = code.matchAll(/\bimport\.meta\.env\b/g);
10081
+ const envs = stripLiteral(code).matchAll(/\bimport\.meta\.env\b/g);
9861
10082
  for (const env of envs) {
9862
10083
  s || (s = new MagicString(code));
9863
10084
  const startIndex = env.index;
@@ -10054,9 +10275,19 @@ function getIndexStatus(code, from) {
10054
10275
 
10055
10276
  const cssLangs = "\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)";
10056
10277
  const cssLangRE = new RegExp(cssLangs);
10278
+ const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
10057
10279
  const isCSS = (id) => {
10058
10280
  return cssLangRE.test(id);
10059
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
+ };
10060
10291
  function CSSEnablerPlugin(ctx) {
10061
10292
  const shouldProcessCSS = (id) => {
10062
10293
  const { css } = ctx.config;
@@ -10068,16 +10299,38 @@ function CSSEnablerPlugin(ctx) {
10068
10299
  return true;
10069
10300
  return false;
10070
10301
  };
10071
- return {
10072
- name: "vitest:css-enabler",
10073
- enforce: "pre",
10074
- transform(code, id) {
10075
- if (!isCSS(id))
10076
- return;
10077
- 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
+ }
10078
10330
  return { code: "" };
10331
+ }
10079
10332
  }
10080
- };
10333
+ ];
10081
10334
  }
10082
10335
 
10083
10336
  function CoverageTransform(ctx) {
@@ -10090,15 +10343,17 @@ function CoverageTransform(ctx) {
10090
10343
  };
10091
10344
  }
10092
10345
 
10093
- async function VitestPlugin(options = {}, ctx = new Vitest()) {
10094
- async function UIPlugin() {
10346
+ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
10347
+ const getRoot = () => {
10095
10348
  var _a;
10096
- 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());
10097
10353
  return (await import('@vitest/ui')).default(options.uiBase);
10098
10354
  }
10099
10355
  async function BrowserPlugin() {
10100
- var _a;
10101
- await ensurePackageInstalled("@vitest/browser", ((_a = ctx.config) == null ? void 0 : _a.root) || options.root || process.cwd());
10356
+ await ensurePackageInstalled("@vitest/browser", getRoot());
10102
10357
  return (await import('@vitest/browser')).default("/");
10103
10358
  }
10104
10359
  return [
@@ -10109,6 +10364,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10109
10364
  this.meta.watchMode = false;
10110
10365
  },
10111
10366
  config(viteConfig) {
10367
+ var _a, _b, _c;
10112
10368
  const preOptions = deepMerge({}, configDefaults, options, viteConfig.test ?? {});
10113
10369
  preOptions.api = resolveApiConfig(preOptions);
10114
10370
  if (viteConfig.define) {
@@ -10158,6 +10414,15 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10158
10414
  preTransformRequests: false
10159
10415
  }
10160
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
+ }
10161
10426
  if (!options.browser) {
10162
10427
  Object.assign(config, {
10163
10428
  cacheDir: void 0,
@@ -10176,7 +10441,12 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10176
10441
  viteConfigTest.run = true;
10177
10442
  if ("alias" in viteConfigTest)
10178
10443
  delete viteConfigTest.alias;
10179
- options = deepMerge({}, configDefaults, viteConfigTest, options);
10444
+ options = deepMerge(
10445
+ {},
10446
+ configDefaults,
10447
+ viteConfigTest,
10448
+ options
10449
+ );
10180
10450
  options.api = resolveApiConfig(options);
10181
10451
  const { PROD, DEV, ...envs } = viteConfig.env;
10182
10452
  (_a = process.env).PROD ?? (_a.PROD = PROD ? "1" : "");
@@ -10189,7 +10459,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10189
10459
  try {
10190
10460
  await ctx.setServer(options, server);
10191
10461
  if (options.api && options.watch)
10192
- (await import('./chunk-api-setup.377c28aa.mjs')).setup(ctx);
10462
+ (await import('./chunk-api-setup.5fc06d1d.mjs')).setup(ctx);
10193
10463
  } catch (err) {
10194
10464
  ctx.logger.printError(err, true);
10195
10465
  process.exit(1);
@@ -10202,21 +10472,21 @@ async function VitestPlugin(options = {}, ctx = new Vitest()) {
10202
10472
  MocksPlugin(),
10203
10473
  GlobalSetupPlugin(ctx),
10204
10474
  ...options.browser ? await BrowserPlugin() : [],
10205
- CSSEnablerPlugin(ctx),
10475
+ ...CSSEnablerPlugin(ctx),
10206
10476
  CoverageTransform(ctx),
10207
10477
  options.ui ? await UIPlugin() : null
10208
10478
  ].filter(notNullish);
10209
10479
  }
10210
10480
 
10211
- async function createVitest(options, viteOverrides = {}) {
10481
+ async function createVitest(mode, options, viteOverrides = {}) {
10212
10482
  var _a;
10213
- const ctx = new Vitest();
10483
+ const ctx = new Vitest(mode);
10214
10484
  const root = resolve(options.root || process.cwd());
10215
10485
  const configPath = options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
10216
10486
  const config = {
10217
10487
  logLevel: "error",
10218
10488
  configFile: configPath,
10219
- mode: options.mode || process.env.NODE_ENV || "test",
10489
+ mode: options.mode || process.env.NODE_ENV || mode,
10220
10490
  plugins: await VitestPlugin(options, ctx)
10221
10491
  };
10222
10492
  const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
@@ -10231,16 +10501,20 @@ const keys = [
10231
10501
  ["a", "rerun all tests"],
10232
10502
  ["f", "rerun only failed tests"],
10233
10503
  ["u", "update snapshot"],
10504
+ ["p", "filter by a filename"],
10234
10505
  ["t", "filter by a test name regex pattern"],
10235
10506
  ["q", "quit"]
10236
10507
  ];
10237
10508
  function printShortcutsHelp() {
10238
- stdout().write(`
10509
+ stdout().write(
10510
+ `
10239
10511
  ${picocolors.exports.bold(" Watch Usage")}
10240
10512
  ${keys.map((i) => picocolors.exports.dim(" press ") + picocolors.exports.reset(picocolors.exports.bold(i[0])) + picocolors.exports.dim(` to ${i[1]}`)).join("\n")}
10241
- `);
10513
+ `
10514
+ );
10242
10515
  }
10243
10516
  function registerConsoleShortcuts(ctx) {
10517
+ let latestFilename = "";
10244
10518
  async function _keypressHandler(str, key) {
10245
10519
  if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c")
10246
10520
  return ctx.exit(true);
@@ -10257,6 +10531,8 @@ function registerConsoleShortcuts(ctx) {
10257
10531
  return ctx.rerunFailed();
10258
10532
  if (name === "t")
10259
10533
  return inputNamePattern();
10534
+ if (name === "p")
10535
+ return inputFilePattern();
10260
10536
  if (name === "q")
10261
10537
  return ctx.exit(true);
10262
10538
  }
@@ -10274,6 +10550,18 @@ function registerConsoleShortcuts(ctx) {
10274
10550
  await ctx.changeNamePattern(filter, void 0, "change pattern");
10275
10551
  on();
10276
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
+ }
10277
10565
  let rl;
10278
10566
  function on() {
10279
10567
  off();
@@ -10293,7 +10581,7 @@ function registerConsoleShortcuts(ctx) {
10293
10581
  on();
10294
10582
  }
10295
10583
 
10296
- async function startVitest(cliFilters, options, viteOverrides) {
10584
+ async function startVitest(mode, cliFilters, options, viteOverrides) {
10297
10585
  var _a;
10298
10586
  process.env.TEST = "true";
10299
10587
  process.env.VITEST = "true";
@@ -10309,8 +10597,8 @@ async function startVitest(cliFilters, options, viteOverrides) {
10309
10597
  }
10310
10598
  if (typeof options.coverage === "boolean")
10311
10599
  options.coverage = { enabled: options.coverage };
10312
- const ctx = await createVitest(options, viteOverrides);
10313
- if (ctx.config.coverage.enabled) {
10600
+ const ctx = await createVitest(mode, options, viteOverrides);
10601
+ if (mode !== "benchmark" && ctx.config.coverage.enabled) {
10314
10602
  const provider = ctx.config.coverage.provider || "c8";
10315
10603
  if (typeof provider === "string") {
10316
10604
  const requiredPackages = CoverageProviderMap[provider];
@@ -10320,12 +10608,10 @@ async function startVitest(cliFilters, options, viteOverrides) {
10320
10608
  }
10321
10609
  }
10322
10610
  }
10323
- if (ctx.config.environment && ctx.config.environment !== "node") {
10324
- const packageName = envPackageNames[ctx.config.environment];
10325
- if (!await ensurePackageInstalled(packageName, root)) {
10326
- process.exitCode = 1;
10327
- return false;
10328
- }
10611
+ const environmentPackage = getEnvPackageName(ctx.config.environment);
10612
+ if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) {
10613
+ process.exitCode = 1;
10614
+ return false;
10329
10615
  }
10330
10616
  if (process.stdin.isTTY && ctx.config.watch)
10331
10617
  registerConsoleShortcuts(ctx);