vitest 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE.md +0 -44
  2. package/dist/browser.d.ts +4 -3
  3. package/dist/browser.js +3 -3
  4. package/dist/chunks/{base.bV8rwssx.js → base.DslwPSCy.js} +3 -3
  5. package/dist/chunks/{benchmark.BKUatJGy.js → benchmark.BoF7jW0Q.js} +1 -1
  6. package/dist/chunks/{cac.DK21mt6F.js → cac.BN2e7cE1.js} +8 -8
  7. package/dist/chunks/{cli-api.bwYuoT4p.js → cli-api.Bti1vevt.js} +272 -3521
  8. package/dist/chunks/{config.d.DevWltVl.d.ts → config.d.UqE-KR0o.d.ts} +2 -2
  9. package/dist/chunks/{console.D6t261w0.js → console.K1NMVOSc.js} +1 -1
  10. package/dist/chunks/{coverage.SfnlalVs.js → coverage.87S59-Sl.js} +18 -16
  11. package/dist/chunks/{defaults.DmfNPoe5.js → defaults.DSxsTG0h.js} +1 -1
  12. package/dist/chunks/{environment.d.C8UItCbf.d.ts → environment.d.Dmw5ulng.d.ts} +5 -58
  13. package/dist/chunks/{execute.CwmnH2oH.js → execute.BpmIjFTD.js} +22 -12
  14. package/dist/chunks/{global.d.Cg2sEPIm.d.ts → global.d.CXRAxnWc.d.ts} +1 -1
  15. package/dist/chunks/{globals.DCbUWjip.js → globals.CZAEe_Gf.js} +5 -5
  16. package/dist/chunks/{index.BDobFbcz.js → index.B0uVAVvx.js} +3 -3
  17. package/dist/chunks/{index.68735LiX.js → index.CJ0plNrh.js} +37 -8
  18. package/dist/chunks/{index.VfYQ6MXY.js → index.Cu2UlluP.js} +4 -4
  19. package/dist/chunks/{index.CwHmn5H5.js → index.De2FqGmR.js} +33 -21
  20. package/dist/chunks/{node.IqGoMrm4.js → node.3xsWotC9.js} +1 -1
  21. package/dist/chunks/{reporters.d.CfRkRKN2.d.ts → reporters.d.DG9VKi4m.d.ts} +22 -9
  22. package/dist/chunks/{rpc.DGgL5dw7.js → rpc.D9_013TY.js} +2 -2
  23. package/dist/chunks/{run-once.I7PpBOk1.js → run-once.Dimr7O9f.js} +1 -1
  24. package/dist/chunks/{runBaseTests.CqmKSG99.js → runBaseTests.BV8m0B-u.js} +10 -10
  25. package/dist/chunks/{setup-common.DEGDGBiA.js → setup-common.AQcDs321.js} +2 -2
  26. package/dist/chunks/{typechecker.CG0zmr19.js → typechecker.DYQbn8uK.js} +2 -2
  27. package/dist/chunks/{utils.Lot3J_8U.js → utils.Cc45eY3L.js} +10 -4
  28. package/dist/chunks/{utils.CtocqOoE.js → utils.CgTj3MsC.js} +1 -1
  29. package/dist/chunks/{vi.B-PuvDzu.js → vi.ClIskdbk.js} +1 -1
  30. package/dist/chunks/{vite.d.4pkSbgmp.d.ts → vite.d.D3ndlJcw.d.ts} +1 -1
  31. package/dist/chunks/{vm.Lp7mPCVW.js → vm.CuLHT1BG.js} +17 -9
  32. package/dist/chunks/{worker.d.CSFlSYJg.d.ts → worker.d.C-KN07Ls.d.ts} +1 -1
  33. package/dist/chunks/{worker.d.C58isfFm.d.ts → worker.d.CHGSOG0s.d.ts} +21 -4
  34. package/dist/cli.js +1 -1
  35. package/dist/config.cjs +1 -1
  36. package/dist/config.d.ts +9 -7
  37. package/dist/config.js +1 -1
  38. package/dist/coverage.d.ts +6 -4
  39. package/dist/coverage.js +4 -4
  40. package/dist/environments.d.ts +3 -2
  41. package/dist/execute.d.ts +4 -3
  42. package/dist/execute.js +1 -1
  43. package/dist/index.d.ts +12 -10
  44. package/dist/index.js +5 -5
  45. package/dist/node.d.ts +10 -8
  46. package/dist/node.js +12 -11
  47. package/dist/reporters.d.ts +6 -4
  48. package/dist/reporters.js +3 -3
  49. package/dist/runners.d.ts +1 -1
  50. package/dist/runners.js +6 -6
  51. package/dist/snapshot.js +2 -2
  52. package/dist/suite.js +2 -2
  53. package/dist/worker.js +3 -3
  54. package/dist/workers/forks.js +3 -3
  55. package/dist/workers/runVmTests.js +9 -9
  56. package/dist/workers/threads.js +3 -3
  57. package/dist/workers/vmForks.js +4 -4
  58. package/dist/workers/vmThreads.js +4 -4
  59. package/dist/workers.d.ts +5 -4
  60. package/dist/workers.js +7 -7
  61. package/globals.d.ts +1 -0
  62. package/optional-types.d.ts +7 -0
  63. package/package.json +17 -17
@@ -195,9 +195,9 @@ interface SerializedConfig {
195
195
  standalone: boolean;
196
196
  logHeapUsage: boolean | undefined;
197
197
  coverage: SerializedCoverageConfig;
198
- benchmark?: {
198
+ benchmark: {
199
199
  includeSamples: boolean
200
- };
200
+ } | undefined;
201
201
  }
202
202
  interface SerializedCoverageConfig {
203
203
  provider: "istanbul" | "v8" | "custom" | undefined;
@@ -4,7 +4,7 @@ import { Writable } from 'node:stream';
4
4
  import { getSafeTimers } from '@vitest/utils';
5
5
  import c from 'tinyrainbow';
6
6
  import { R as RealDate } from './date.CDOsz-HY.js';
7
- import { g as getWorkerState } from './utils.CtocqOoE.js';
7
+ import { g as getWorkerState } from './utils.CgTj3MsC.js';
8
8
 
9
9
  const UNKNOWN_TEST_ID = "__vitest__unknown_test__";
10
10
  function getTaskIdByStack(root) {
@@ -4,7 +4,7 @@ import require$$0 from 'util';
4
4
  import require$$0$1 from 'path';
5
5
  import { relative, resolve, dirname, isAbsolute, join as join$1, normalize } from 'pathe';
6
6
  import c from 'tinyrainbow';
7
- import { c as configDefaults, e as benchmarkConfigDefaults, a as coverageConfigDefaults } from './defaults.DmfNPoe5.js';
7
+ import { c as configDefaults, e as benchmarkConfigDefaults, a as coverageConfigDefaults } from './defaults.DSxsTG0h.js';
8
8
  import crypto from 'node:crypto';
9
9
  import { slash, createDefer, shuffle, toArray } from '@vitest/utils';
10
10
  import { builtinModules, createRequire } from 'node:module';
@@ -22,9 +22,9 @@ import nodeos__default from 'node:os';
22
22
  import { isatty } from 'node:tty';
23
23
  import { version } from 'vite';
24
24
  import EventEmitter from 'node:events';
25
- import { c as createBirpc } from './index.68735LiX.js';
25
+ import { c as createBirpc } from './index.CJ0plNrh.js';
26
26
  import Tinypool$1, { Tinypool } from 'tinypool';
27
- import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.CG0zmr19.js';
27
+ import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.DYQbn8uK.js';
28
28
  import { MessageChannel } from 'node:worker_threads';
29
29
  import { hasFailed } from '@vitest/runner/utils';
30
30
  import { rootDir } from '../path.js';
@@ -7932,17 +7932,16 @@ function resolveConfig$1(vitest, options, viteConfig) {
7932
7932
  }
7933
7933
  }
7934
7934
  const browser = resolved.browser;
7935
- if (browser.enabled) {
7935
+ if (browser.enabled && viteConfig.test?.browser) {
7936
7936
  if (!browser.name && !browser.instances) {
7937
- browser.enabled = false;
7938
- } else {
7939
- const instances = browser.instances;
7940
- if (browser.name && browser.instances) {
7941
- browser.instances = browser.instances.filter((instance) => instance.browser === browser.name);
7942
- }
7943
- if (browser.instances && !browser.instances.length) {
7944
- throw new Error([`"browser.instances" was set in the config, but the array is empty. Define at least one browser config.`, browser.name && instances?.length ? ` The "browser.name" was set to "${browser.name}" which filtered all configs (${instances.map((c) => c.browser).join(", ")}). Did you mean to use another name?` : ""].join(""));
7945
- }
7937
+ throw new Error(`Vitest Browser Mode requires "browser.name" (deprecated) or "browser.instances" options, none were set.`);
7938
+ }
7939
+ const instances = browser.instances;
7940
+ if (browser.name && browser.instances) {
7941
+ browser.instances = browser.instances.filter((instance) => instance.browser === browser.name);
7942
+ }
7943
+ if (browser.instances && !browser.instances.length) {
7944
+ throw new Error([`"browser.instances" was set in the config, but the array is empty. Define at least one browser config.`, browser.name && instances?.length ? ` The "browser.name" was set to "${browser.name}" which filtered all configs (${instances.map((c) => c.browser).join(", ")}). Did you mean to use another name?` : ""].join(""));
7946
7945
  }
7947
7946
  }
7948
7947
  const playwrightChromiumOnly = isPlaywrightChromiumOnly(vitest, resolved);
@@ -8002,8 +8001,11 @@ function resolveConfig$1(vitest, options, viteConfig) {
8002
8001
  resolved.deps.web.transformGlobPattern ??= [];
8003
8002
  resolved.setupFiles = toArray(resolved.setupFiles || []).map((file) => resolvePath(file, resolved.root));
8004
8003
  resolved.globalSetup = toArray(resolved.globalSetup || []).map((file) => resolvePath(file, resolved.root));
8005
- resolved.coverage.exclude.push(...resolved.setupFiles.map((file) => `${resolved.coverage.allowExternal ? "**/" : ""}${relative(resolved.root, file)}`));
8006
- resolved.coverage.exclude.push(...resolved.include);
8004
+ resolved.coverage.exclude = [
8005
+ ...resolved.coverage.exclude,
8006
+ ...resolved.setupFiles.map((file) => `${resolved.coverage.allowExternal ? "**/" : ""}${relative(resolved.root, file)}`),
8007
+ ...resolved.include
8008
+ ];
8007
8009
  resolved.forceRerunTriggers = [...resolved.forceRerunTriggers, ...resolved.setupFiles];
8008
8010
  resolved.server ??= {};
8009
8011
  resolved.server.deps ??= {};
@@ -8477,7 +8479,7 @@ class BaseCoverageProvider {
8477
8479
  for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
8478
8480
  if (onDebug.enabled) {
8479
8481
  index += chunk.length;
8480
- onDebug("Covered files %d/%d", index, total);
8482
+ onDebug(`Reading coverage results ${index}/${total}`);
8481
8483
  }
8482
8484
  await Promise.all(chunk.map(async (filename) => {
8483
8485
  const contents = await promises$1.readFile(filename, "utf-8");
@@ -76,7 +76,7 @@ const fakeTimersDefaults = {
76
76
  const configDefaults = Object.freeze({
77
77
  allowOnly: !isCI,
78
78
  isolate: true,
79
- watch: !isCI,
79
+ watch: !isCI && process.stdin.isTTY,
80
80
  globals: false,
81
81
  environment: "node",
82
82
  pool: "forks",
@@ -1,3 +1,5 @@
1
+ import { happyDomTypes, jsdomTypes } from 'vitest/optional-types.js';
2
+
1
3
  type Awaitable<T> = T | PromiseLike<T>;
2
4
  type Nullable<T> = T | null | undefined;
3
5
  type Arrayable<T> = T | Array<T>;
@@ -35,31 +37,10 @@ interface ModuleGraphData {
35
37
  }
36
38
  interface ProvidedContext {}
37
39
 
38
- /**
39
- * Happy DOM options.
40
- */
41
- interface HappyDOMOptions {
42
- width?: number;
43
- height?: number;
44
- url?: string;
45
- settings?: {
46
- disableJavaScriptEvaluation?: boolean
47
- disableJavaScriptFileLoading?: boolean
48
- disableCSSFileLoading?: boolean
49
- disableIframePageLoading?: boolean
50
- disableComputedStyleRendering?: boolean
51
- enableFileSystemHttpRequests?: boolean
52
- navigator?: {
53
- userAgent?: string
54
- }
55
- device?: {
56
- prefersColorScheme?: string
57
- mediaType?: string
58
- }
59
- };
60
- }
40
+ type HappyDOMOptions = Omit<NonNullable<ConstructorParameters<typeof happyDomTypes.Window>[0]>, "console">;
61
41
 
62
- interface JSDOMOptions {
42
+ type JSDOMOptions = ConstructorOptionsOverride & Omit<jsdomTypes.ConstructorOptions, keyof ConstructorOptionsOverride>;
43
+ interface ConstructorOptionsOverride {
63
44
  /**
64
45
  * The html content for the test.
65
46
  *
@@ -67,11 +48,6 @@ interface JSDOMOptions {
67
48
  */
68
49
  html?: string | ArrayBufferLike;
69
50
  /**
70
- * referrer just affects the value read from document.referrer.
71
- * It defaults to no referrer (which reflects as the empty string).
72
- */
73
- referrer?: string;
74
- /**
75
51
  * userAgent affects the value read from navigator.userAgent, as well as the User-Agent header sent while fetching subresources.
76
52
  *
77
53
  * @default `Mozilla/5.0 (${process.platform}) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/${jsdomVersion}`
@@ -86,21 +62,6 @@ interface JSDOMOptions {
86
62
  */
87
63
  url?: string;
88
64
  /**
89
- * contentType affects the value read from document.contentType, and how the document is parsed: as HTML or as XML.
90
- * Values that are not "text/html" or an XML mime type will throw.
91
- *
92
- * @default 'text/html'.
93
- */
94
- contentType?: string;
95
- /**
96
- * The maximum size in code units for the separate storage areas used by localStorage and sessionStorage.
97
- * Attempts to store data larger than this limit will cause a DOMException to be thrown. By default, it is set
98
- * to 5,000,000 code units per origin, as inspired by the HTML specification.
99
- *
100
- * @default 5_000_000
101
- */
102
- storageQuota?: number;
103
- /**
104
65
  * Enable console?
105
66
  *
106
67
  * @default false
@@ -117,20 +78,6 @@ interface JSDOMOptions {
117
78
  */
118
79
  pretendToBeVisual?: boolean;
119
80
  /**
120
- * `includeNodeLocations` preserves the location info produced by the HTML parser,
121
- * allowing you to retrieve it with the nodeLocation() method (described below).
122
- *
123
- * It defaults to false to give the best performance,
124
- * and cannot be used with an XML content type since our XML parser does not support location info.
125
- *
126
- * @default false
127
- */
128
- includeNodeLocations?: boolean | undefined;
129
- /**
130
- * @default 'dangerously'
131
- */
132
- runScripts?: "dangerously" | "outside-only";
133
- /**
134
81
  * Enable CookieJar
135
82
  *
136
83
  * @default false
@@ -573,6 +573,25 @@ function listenForErrors(state) {
573
573
  process.off("unhandledRejection", unhandledRejection);
574
574
  });
575
575
  }
576
+ const relativeIds = {};
577
+ function getVitestImport(id, state) {
578
+ if (externalizeMap.has(id)) {
579
+ return { externalize: externalizeMap.get(id) };
580
+ }
581
+ const root = state().config.root;
582
+ const relativeRoot = relativeIds[root] ?? (relativeIds[root] = normalizedDistDir.slice(root.length));
583
+ if (id.includes(distDir) || id.includes(normalizedDistDir) || relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) {
584
+ const { path } = toFilePath(id, root);
585
+ const externalize = pathToFileURL(path).toString();
586
+ externalizeMap.set(id, externalize);
587
+ return { externalize };
588
+ }
589
+ if (bareVitestRegexp.test(id)) {
590
+ externalizeMap.set(id, id);
591
+ return { externalize: id };
592
+ }
593
+ return null;
594
+ }
576
595
  async function startVitestExecutor(options) {
577
596
  const state = () => globalThis.__vitest_worker__ || options.state;
578
597
  const rpc = () => state().rpc;
@@ -585,18 +604,9 @@ async function startVitestExecutor(options) {
585
604
  };
586
605
  return await createVitestExecutor({
587
606
  async fetchModule(id) {
588
- if (externalizeMap.has(id)) {
589
- return { externalize: externalizeMap.get(id) };
590
- }
591
- if (id.includes(distDir) || id.includes(normalizedDistDir)) {
592
- const { path } = toFilePath(id, state().config.root);
593
- const externalize = pathToFileURL(path).toString();
594
- externalizeMap.set(id, externalize);
595
- return { externalize };
596
- }
597
- if (bareVitestRegexp.test(id)) {
598
- externalizeMap.set(id, id);
599
- return { externalize: id };
607
+ const vitest = getVitestImport(id, state);
608
+ if (vitest) {
609
+ return vitest;
600
610
  }
601
611
  const result = await rpc().fetch(id, getTransformMode());
602
612
  if (result.id && !result.externalize) {
@@ -2,7 +2,7 @@ import { PromisifyAssertion, Tester, ExpectStatic } from '@vitest/expect';
2
2
  import { Plugin } from '@vitest/pretty-format';
3
3
  import { SnapshotState } from '@vitest/snapshot';
4
4
  import { B as BenchmarkResult } from './benchmark.d.BwvBVTda.js';
5
- import { U as UserConsoleLog } from './environment.d.C8UItCbf.js';
5
+ import { U as UserConsoleLog } from './environment.d.Dmw5ulng.js';
6
6
 
7
7
  type RawErrsMap = Map<string, TscErrorInfo[]>;
8
8
  interface TscErrorInfo {
@@ -1,11 +1,11 @@
1
1
  import { g as globalApis } from './constants.BZZyIeIE.js';
2
- import { V as VitestIndex } from './index.BDobFbcz.js';
3
- import './vi.B-PuvDzu.js';
2
+ import { V as VitestIndex } from './index.B0uVAVvx.js';
3
+ import './vi.ClIskdbk.js';
4
4
  import '@vitest/expect';
5
5
  import '@vitest/runner';
6
6
  import '@vitest/runner/utils';
7
7
  import 'chai';
8
- import './utils.CtocqOoE.js';
8
+ import './utils.CgTj3MsC.js';
9
9
  import '@vitest/utils';
10
10
  import './_commonjsHelpers.BFTU3MAI.js';
11
11
  import '@vitest/snapshot';
@@ -13,8 +13,8 @@ import '@vitest/utils/error';
13
13
  import '@vitest/spy';
14
14
  import '@vitest/utils/source-map';
15
15
  import './date.CDOsz-HY.js';
16
- import './run-once.I7PpBOk1.js';
17
- import './benchmark.BKUatJGy.js';
16
+ import './run-once.Dimr7O9f.js';
17
+ import './benchmark.BoF7jW0Q.js';
18
18
  import 'expect-type';
19
19
 
20
20
  function registerApiGlobally() {
@@ -1,6 +1,6 @@
1
- import { c as createExpect, a as globalExpect, i as inject, v as vi, b as vitest } from './vi.B-PuvDzu.js';
2
- import { i as isFirstRun, a as runOnce } from './run-once.I7PpBOk1.js';
3
- import { b as bench } from './benchmark.BKUatJGy.js';
1
+ import { c as createExpect, a as globalExpect, i as inject, v as vi, b as vitest } from './vi.ClIskdbk.js';
2
+ import { i as isFirstRun, a as runOnce } from './run-once.Dimr7O9f.js';
3
+ import { b as bench } from './benchmark.BoF7jW0Q.js';
4
4
  import { expectTypeOf } from 'expect-type';
5
5
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
6
6
  import * as chai from 'chai';
@@ -1,3 +1,5 @@
1
+ const TYPE_REQUEST = "q";
2
+ const TYPE_RESPONSE = "s";
1
3
  const DEFAULT_TIMEOUT = 6e4;
2
4
  function defaultSerialize(i) {
3
5
  return i;
@@ -30,7 +32,7 @@ function createBirpc(functions, options) {
30
32
  if (method === "then" && !eventNames.includes("then") && !("then" in functions))
31
33
  return void 0;
32
34
  const sendEvent = (...args) => {
33
- post(serialize({ m: method, a: args, t: "q" }));
35
+ post(serialize({ m: method, a: args, t: TYPE_REQUEST }));
34
36
  };
35
37
  if (eventNames.includes(method)) {
36
38
  sendEvent.asEvent = sendEvent;
@@ -52,8 +54,9 @@ function createBirpc(functions, options) {
52
54
  if (timeout >= 0) {
53
55
  timeoutId = setTimeout(() => {
54
56
  try {
55
- options.onTimeoutError?.(method, args);
56
- throw new Error(`[birpc] timeout on calling "${method}"`);
57
+ const handleResult = options.onTimeoutError?.(method, args);
58
+ if (handleResult !== true)
59
+ throw new Error(`[birpc] timeout on calling "${method}"`);
57
60
  } catch (e) {
58
61
  reject(e);
59
62
  }
@@ -70,17 +73,24 @@ function createBirpc(functions, options) {
70
73
  return sendCall;
71
74
  }
72
75
  });
73
- function close() {
76
+ function close(error) {
74
77
  closed = true;
75
78
  rpcPromiseMap.forEach(({ reject, method }) => {
76
- reject(new Error(`[birpc] rpc is closed, cannot call "${method}"`));
79
+ reject(error || new Error(`[birpc] rpc is closed, cannot call "${method}"`));
77
80
  });
78
81
  rpcPromiseMap.clear();
79
82
  off(onMessage);
80
83
  }
81
84
  async function onMessage(data, ...extra) {
82
- const msg = deserialize(data);
83
- if (msg.t === "q") {
85
+ let msg;
86
+ try {
87
+ msg = deserialize(data);
88
+ } catch (e) {
89
+ if (options.onGeneralError?.(e) !== true)
90
+ throw e;
91
+ return;
92
+ }
93
+ if (msg.t === TYPE_REQUEST) {
84
94
  const { m: method, a: args } = msg;
85
95
  let result, error;
86
96
  const fn = resolver ? resolver(method, functions[method]) : functions[method];
@@ -96,7 +106,26 @@ function createBirpc(functions, options) {
96
106
  if (msg.i) {
97
107
  if (error && options.onError)
98
108
  options.onError(error, method, args);
99
- post(serialize({ t: "s", i: msg.i, r: result, e: error }), ...extra);
109
+ if (error && options.onFunctionError) {
110
+ if (options.onFunctionError(error, method, args) === true)
111
+ return;
112
+ }
113
+ if (!error) {
114
+ try {
115
+ post(serialize({ t: TYPE_RESPONSE, i: msg.i, r: result }), ...extra);
116
+ return;
117
+ } catch (e) {
118
+ error = e;
119
+ if (options.onGeneralError?.(e, method, args) !== true)
120
+ throw e;
121
+ }
122
+ }
123
+ try {
124
+ post(serialize({ t: TYPE_RESPONSE, i: msg.i, e: error }), ...extra);
125
+ } catch (e) {
126
+ if (options.onGeneralError?.(e, method, args) !== true)
127
+ throw e;
128
+ }
100
129
  }
101
130
  } else {
102
131
  const { i: ack, r: result, e: error } = msg;
@@ -1,9 +1,9 @@
1
1
  import * as chai from 'chai';
2
2
  import { resolve } from 'node:path';
3
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.DEGDGBiA.js';
3
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.AQcDs321.js';
4
4
  import { distDir } from '../path.js';
5
- import { r as rpc } from './rpc.DGgL5dw7.js';
6
- import { g as getWorkerState } from './utils.CtocqOoE.js';
5
+ import { r as rpc } from './rpc.D9_013TY.js';
6
+ import { g as getWorkerState } from './utils.CgTj3MsC.js';
7
7
 
8
8
  function setupChaiConfig(config) {
9
9
  Object.assign(chai.config, config);
@@ -11,7 +11,7 @@ function setupChaiConfig(config) {
11
11
 
12
12
  async function resolveSnapshotEnvironment(config, executor) {
13
13
  if (!config.snapshotEnvironment) {
14
- const { VitestNodeSnapshotEnvironment } = await import('./node.IqGoMrm4.js');
14
+ const { VitestNodeSnapshotEnvironment } = await import('./node.3xsWotC9.js');
15
15
  return new VitestNodeSnapshotEnvironment();
16
16
  }
17
17
  const mod = await executor.executeId(config.snapshotEnvironment);
@@ -3,14 +3,14 @@ import { getTestName, hasFailed, getFullName, getTests, getSuites, getTasks } fr
3
3
  import * as pathe from 'pathe';
4
4
  import { relative, normalize, resolve, dirname } from 'pathe';
5
5
  import c from 'tinyrainbow';
6
- import { t as truncateString, d as divider, F as F_POINTER, f as formatTimeString, a as taskFail, b as F_CHECK, g as getStateSymbol, c as formatProjectName, e as F_RIGHT, w as withLabel, r as renderSnapshotSummary, p as padSummaryTitle, h as getStateString$1, i as formatTime, j as countTestErrors, k as F_TREE_NODE_END, l as F_TREE_NODE_MIDDLE } from './utils.Lot3J_8U.js';
6
+ import { t as truncateString, e as errorBanner, F as F_POINTER, d as divider, f as formatTimeString, a as taskFail, b as F_CHECK, g as getStateSymbol, c as formatProjectName, h as F_RIGHT, w as withLabel, r as renderSnapshotSummary, p as padSummaryTitle, i as getStateString$1, j as formatTime, k as countTestErrors, l as F_TREE_NODE_END, m as F_TREE_NODE_MIDDLE } from './utils.Cc45eY3L.js';
7
7
  import { stripVTControlCharacters } from 'node:util';
8
8
  import { positionToOffset, lineSplitRE, isPrimitive, inspect, toArray, notNullish } from '@vitest/utils';
9
9
  import { performance as performance$1 } from 'node:perf_hooks';
10
10
  import { parseErrorStacktrace, parseStacktrace } from '@vitest/utils/source-map';
11
11
  import { i as isTTY } from './env.Dq0hM4Xv.js';
12
- import { T as TypeCheckError, g as getOutputFile, h as hasFailedSnapshot } from './typechecker.CG0zmr19.js';
13
- import { mkdir, writeFile, readdir, stat, readFile } from 'node:fs/promises';
12
+ import { T as TypeCheckError, g as getOutputFile, h as hasFailedSnapshot } from './typechecker.DYQbn8uK.js';
13
+ import { readdir, stat, readFile, mkdir, writeFile } from 'node:fs/promises';
14
14
  import { Console } from 'node:console';
15
15
  import { Writable } from 'node:stream';
16
16
  import { createRequire } from 'node:module';
@@ -252,7 +252,7 @@ function printErrorInner(error, project, options) {
252
252
  return { nearest };
253
253
  }
254
254
  function printErrorType(type, ctx) {
255
- ctx.logger.error(`\n${c.red(divider(c.bold(c.inverse(` ${type} `))))}`);
255
+ ctx.logger.error(`\n${errorBanner(type)}`);
256
256
  }
257
257
  const skipErrorProperties = new Set([
258
258
  "nameStr",
@@ -406,6 +406,7 @@ function lineNo(no = "") {
406
406
  }
407
407
 
408
408
  class BlobReporter {
409
+ start = 0;
409
410
  ctx;
410
411
  options;
411
412
  constructor(options) {
@@ -416,8 +417,10 @@ class BlobReporter {
416
417
  throw new Error("Blob reporter is not supported in watch mode");
417
418
  }
418
419
  this.ctx = ctx;
420
+ this.start = performance.now();
419
421
  }
420
422
  async onFinished(files = [], errors = [], coverage) {
423
+ const executionTime = performance.now() - this.start;
421
424
  let outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "blob");
422
425
  if (!outputFile) {
423
426
  const shard = this.ctx.config.shard;
@@ -435,22 +438,27 @@ class BlobReporter {
435
438
  ];
436
439
  }).filter((x) => x != null)];
437
440
  });
438
- const report = stringify([
441
+ const report = [
439
442
  this.ctx.version,
440
443
  files,
441
444
  errors,
442
445
  modules,
443
- coverage
444
- ]);
446
+ coverage,
447
+ executionTime
448
+ ];
445
449
  const reportFile = resolve(this.ctx.config.root, outputFile);
446
- const dir = dirname(reportFile);
447
- if (!existsSync(dir)) {
448
- await mkdir(dir, { recursive: true });
449
- }
450
- await writeFile(reportFile, report, "utf-8");
450
+ await writeBlob(report, reportFile);
451
451
  this.ctx.logger.log("blob report written to", reportFile);
452
452
  }
453
453
  }
454
+ async function writeBlob(content, filename) {
455
+ const report = stringify(content);
456
+ const dir = dirname(filename);
457
+ if (!existsSync(dir)) {
458
+ await mkdir(dir, { recursive: true });
459
+ }
460
+ await writeFile(filename, report, "utf-8");
461
+ }
454
462
  async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
455
463
  const resolvedDir = resolve(process.cwd(), blobsDirectory);
456
464
  const blobsFiles = await readdir(resolvedDir);
@@ -461,7 +469,7 @@ async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
461
469
  throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file`);
462
470
  }
463
471
  const content = await readFile(fullPath, "utf-8");
464
- const [version, files, errors, moduleKeys, coverage] = parse(content);
472
+ const [version, files, errors, moduleKeys, coverage, executionTime] = parse(content);
465
473
  if (!version) {
466
474
  throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a valid blob file`);
467
475
  }
@@ -471,7 +479,8 @@ async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
471
479
  errors,
472
480
  moduleKeys,
473
481
  coverage,
474
- file: filename
482
+ file: filename,
483
+ executionTime
475
484
  };
476
485
  });
477
486
  const blobs = await Promise.all(promises);
@@ -507,10 +516,12 @@ async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
507
516
  });
508
517
  const errors = blobs.flatMap((blob) => blob.errors);
509
518
  const coverages = blobs.map((blob) => blob.coverage);
519
+ const executionTimes = blobs.map((blob) => blob.executionTime);
510
520
  return {
511
521
  files,
512
522
  errors,
513
- coverages
523
+ coverages,
524
+ executionTimes
514
525
  };
515
526
  }
516
527
 
@@ -829,7 +840,8 @@ class BaseReporter {
829
840
  if (this.watchFilters) {
830
841
  this.log(padSummaryTitle("Duration"), formatTime(collectTime + testsTime + setupTime));
831
842
  } else {
832
- const executionTime = this.end - this.start;
843
+ const blobs = this.ctx.state.blobs;
844
+ const executionTime = blobs?.executionTimes ? sum(blobs.executionTimes, (time) => time) : this.end - this.start;
833
845
  const environmentTime = sum(files, (file) => file.environmentLoad);
834
846
  const prepareTime = sum(files, (file) => file.prepareDuration);
835
847
  const transformTime = sum(this.ctx.projects, (project) => project.vitenode.getTotalDuration());
@@ -844,6 +856,9 @@ class BaseReporter {
844
856
  typecheck && `typecheck ${formatTime(typecheck)}`
845
857
  ].filter(Boolean).join(", ");
846
858
  this.log(padSummaryTitle("Duration"), formatTime(executionTime) + c.dim(` (${timers})`));
859
+ if (blobs?.executionTimes) {
860
+ this.log(padSummaryTitle("Per blob") + blobs.executionTimes.map((time) => ` ${formatTime(time)}`).join(""));
861
+ }
847
862
  }
848
863
  this.log();
849
864
  }
@@ -917,7 +932,7 @@ class BaseReporter {
917
932
  if (filepath) {
918
933
  name += c.dim(` [ ${this.relative(filepath)} ]`);
919
934
  }
920
- this.ctx.logger.error(`${c.red(c.bold(c.inverse(" FAIL ")))} ${formatProjectName(projectName)}${name}`);
935
+ this.ctx.logger.error(`${c.bgRed(c.bold(" FAIL "))} ${formatProjectName(projectName)}${name}`);
921
936
  }
922
937
  const screenshotPaths = tasks.map((t) => t.meta?.failScreenshotPath).filter((screenshot) => screenshot != null);
923
938
  this.ctx.logger.printError(error, {
@@ -930,9 +945,6 @@ class BaseReporter {
930
945
  }
931
946
  }
932
947
  }
933
- function errorBanner(message) {
934
- return c.red(divider(c.bold(c.inverse(` ${message} `))));
935
- }
936
948
  function sum(items, cb) {
937
949
  return items.reduce((total, next) => {
938
950
  return total + Math.max(cb(next) || 0, 0);
@@ -946,7 +958,7 @@ class BasicReporter extends BaseReporter {
946
958
  }
947
959
  onInit(ctx) {
948
960
  super.onInit(ctx);
949
- ctx.logger.log(c.inverse(c.bold(c.yellow(" DEPRECATED "))), c.yellow(`'basic' reporter is deprecated and will be removed in Vitest v3.\n` + `Remove 'basic' from 'reporters' option. To match 'basic' reporter 100%, use configuration:\n${JSON.stringify({ test: { reporters: [["default", { summary: false }]] } }, null, 2)}`));
961
+ ctx.logger.log(c.bold(c.bgYellow(" DEPRECATED ")), c.yellow(`'basic' reporter is deprecated and will be removed in Vitest v3.\n` + `Remove 'basic' from 'reporters' option. To match 'basic' reporter 100%, use configuration:\n${JSON.stringify({ test: { reporters: [["default", { summary: false }]] } }, null, 2)}`));
950
962
  }
951
963
  reportSummary(files, errors) {
952
964
  this.ctx.logger.log();
@@ -1,5 +1,5 @@
1
1
  import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
2
- import { g as getWorkerState } from './utils.CtocqOoE.js';
2
+ import { g as getWorkerState } from './utils.CgTj3MsC.js';
3
3
  import '@vitest/utils';
4
4
 
5
5
  class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {