vitest 4.0.0-beta.18 → 4.0.0-beta.19

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 (52) hide show
  1. package/dist/browser.d.ts +3 -3
  2. package/dist/browser.js +1 -1
  3. package/dist/{worker-base.js → chunks/base.CtHM3ryk.js} +18 -91
  4. package/dist/chunks/{browser.d.CCG7W26I.d.ts → browser.d.B9iJzZyn.d.ts} +3 -2
  5. package/dist/chunks/{cac.DYnuYoJK.js → cac.DCrQhweU.js} +14 -61
  6. package/dist/chunks/{cli-api.xhe4uqTX.js → cli-api.BjHteKX0.js} +1312 -53
  7. package/dist/chunks/{config.d.C4PpNy7v.d.ts → config.d.u2CUDWwS.d.ts} +2 -16
  8. package/dist/chunks/{coverage.Ds84cgzV.js → coverage.FU3w4IrQ.js} +25 -1241
  9. package/dist/chunks/{defaults.CXFFjsi8.js → defaults.BOqNVLsY.js} +0 -1
  10. package/dist/chunks/evaluatedModules.Dg1zASAC.js +17 -0
  11. package/dist/chunks/{global.d.RTA0rbJI.d.ts → global.d.BgJSTpgQ.d.ts} +1 -1
  12. package/dist/chunks/{globals.CwYe1aG7.js → globals.BGT_RUsD.js} +4 -2
  13. package/dist/chunks/{index.eEkl9h8v.js → index.BdSLhLDZ.js} +1 -1
  14. package/dist/chunks/{index.D2gVI9Ck.js → index.CcRZ6fUh.js} +1506 -11
  15. package/dist/chunks/{index.Bcjk8TKX.js → index.RwjEGCQ0.js} +2 -2
  16. package/dist/chunks/init-forks.DSafeltJ.js +54 -0
  17. package/dist/chunks/init-threads.SUtZ-067.js +17 -0
  18. package/dist/chunks/{worker.CdzokOSx.js → init.B2EESLQM.js} +97 -80
  19. package/dist/chunks/{inspector.Br76Q2Mb.js → inspector.DLZxSeU3.js} +1 -2
  20. package/dist/chunks/{moduleRunner.d.aXWuQhZN.d.ts → moduleRunner.d.YtNsMIoJ.d.ts} +1 -1
  21. package/dist/chunks/{plugin.d.XtKKWlOO.d.ts → plugin.d.BB__S31E.d.ts} +1 -1
  22. package/dist/chunks/{reporters.d.BJ_OuJGZ.d.ts → reporters.d.C6nGyY9_.d.ts} +1113 -1152
  23. package/dist/chunks/{resolveSnapshotEnvironment.tw2a5ux8.js → resolveSnapshotEnvironment.DJJKMKxb.js} +1 -1
  24. package/dist/chunks/{setup-common.DgXU7Yho.js → setup-common.DR1sucx6.js} +1 -1
  25. package/dist/chunks/{startModuleRunner.DPBo3mme.js → startModuleRunner.C2tTvmF9.js} +3 -1
  26. package/dist/{worker-vm.js → chunks/vm.DBeOXrP9.js} +6 -66
  27. package/dist/chunks/{worker.d.DSgBAZPX.d.ts → worker.d.BFk-vvBU.d.ts} +79 -4
  28. package/dist/cli.js +8 -9
  29. package/dist/config.cjs +0 -1
  30. package/dist/config.d.ts +6 -7
  31. package/dist/config.js +1 -1
  32. package/dist/coverage.d.ts +4 -4
  33. package/dist/coverage.js +2 -13
  34. package/dist/index.d.ts +13 -9
  35. package/dist/index.js +4 -2
  36. package/dist/module-evaluator.d.ts +3 -3
  37. package/dist/module-runner.js +1 -1
  38. package/dist/node.d.ts +79 -15
  39. package/dist/node.js +25 -26
  40. package/dist/reporters.d.ts +4 -4
  41. package/dist/reporters.js +9 -10
  42. package/dist/runners.d.ts +1 -1
  43. package/dist/worker.d.ts +26 -0
  44. package/dist/worker.js +46 -0
  45. package/dist/workers/forks.js +50 -0
  46. package/dist/workers/runVmTests.js +6 -5
  47. package/dist/workers/threads.js +50 -0
  48. package/dist/workers/vmForks.js +35 -0
  49. package/dist/workers/vmThreads.js +35 -0
  50. package/package.json +16 -13
  51. package/worker.d.ts +1 -0
  52. package/dist/chunks/typechecker.DsKAhua5.js +0 -1522
@@ -1,15 +1,15 @@
1
1
  import { b as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, d as vitest } from './vi.BZvkKVkM.js';
2
2
  import { b as bench } from './benchmark.DHKMYAts.js';
3
+ import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
3
4
  import { expectTypeOf } from 'expect-type';
4
5
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
5
- import { EvaluatedModules } from 'vite/module-runner';
6
6
  import { chai } from '@vitest/expect';
7
7
 
8
8
  const assertType = function assertType() {};
9
9
 
10
10
  var index = /*#__PURE__*/Object.freeze({
11
11
  __proto__: null,
12
- EvaluatedModules: EvaluatedModules,
12
+ EvaluatedModules: VitestEvaluatedModules,
13
13
  afterAll: afterAll,
14
14
  afterEach: afterEach,
15
15
  assert: assert,
@@ -0,0 +1,54 @@
1
+ import v8 from 'node:v8';
2
+ import { i as init } from './init.B2EESLQM.js';
3
+
4
+ if (!process.send) throw new Error("Expected worker to be run in node:child_process");
5
+ // Store globals in case tests overwrite them
6
+ const processExit = process.exit.bind(process), processSend = process.send.bind(process), processOn = process.on.bind(process), processOff = process.off.bind(process), processRemoveAllListeners = process.removeAllListeners.bind(process);
7
+ // Work-around for nodejs/node#55094
8
+ if (process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir"))) processOn("SIGTERM", () => processExit());
9
+ function workerInit(options) {
10
+ const { runTests } = options;
11
+ init({
12
+ post: (v) => processSend(v),
13
+ on: (cb) => processOn("message", cb),
14
+ off: (cb) => processOff("message", cb),
15
+ teardown: () => processRemoveAllListeners("message"),
16
+ serialize: v8.serialize,
17
+ deserialize: (v) => v8.deserialize(Buffer.from(v)),
18
+ runTests: (state) => executeTests("run", state),
19
+ collectTests: (state) => executeTests("collect", state)
20
+ });
21
+ async function executeTests(method, state) {
22
+ state.ctx.config = unwrapSerializableConfig(state.ctx.config);
23
+ try {
24
+ await runTests(method, state);
25
+ } finally {
26
+ process.exit = processExit;
27
+ }
28
+ }
29
+ }
30
+ /**
31
+ * Reverts the wrapping done by `wrapSerializableConfig` in {@link file://./../../node/pool/runtimes/forks.ts}
32
+ */
33
+ function unwrapSerializableConfig(config) {
34
+ if (config.testNamePattern && typeof config.testNamePattern === "string") {
35
+ const testNamePattern = config.testNamePattern;
36
+ if (testNamePattern.startsWith("$$vitest:")) config.testNamePattern = parseRegexp(testNamePattern.slice(9));
37
+ }
38
+ if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) {
39
+ const { keys, original } = config.defines, defines = {};
40
+ // Apply all keys from the original. Entries which had undefined value are missing from original now
41
+ for (const key of keys) defines[key] = original[key];
42
+ config.defines = defines;
43
+ }
44
+ return config;
45
+ }
46
+ function parseRegexp(input) {
47
+ // Parse input
48
+ // eslint-disable-next-line regexp/no-misleading-capturing-group
49
+ const m = input.match(/(\/?)(.+)\1([a-z]*)/i);
50
+ // Create the regular expression
51
+ return m ? m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3]) ? new RegExp(input) : new RegExp(m[2], m[3]) : /$^/;
52
+ }
53
+
54
+ export { workerInit as w };
@@ -0,0 +1,17 @@
1
+ import { isMainThread, parentPort } from 'node:worker_threads';
2
+ import { i as init } from './init.B2EESLQM.js';
3
+
4
+ if (isMainThread || !parentPort) throw new Error("Expected worker to be run in node:worker_threads");
5
+ function workerInit(options) {
6
+ const { runTests } = options;
7
+ init({
8
+ post: (response) => parentPort.postMessage(response),
9
+ on: (callback) => parentPort.on("message", callback),
10
+ off: (callback) => parentPort.off("message", callback),
11
+ teardown: () => parentPort.removeAllListeners("message"),
12
+ runTests: async (state) => runTests("run", state),
13
+ collectTests: async (state) => runTests("collect", state)
14
+ });
15
+ }
16
+
17
+ export { workerInit as w };
@@ -1,14 +1,15 @@
1
+ import { serializeError } from '@vitest/utils/error';
1
2
  import { createStackString, parseStacktrace } from '@vitest/utils/source-map';
2
- import { ModuleRunner, EvaluatedModules } from 'vite/module-runner';
3
3
  import { readFileSync } from 'node:fs';
4
4
  import { isBuiltin } from 'node:module';
5
5
  import { pathToFileURL } from 'node:url';
6
6
  import { resolve } from 'pathe';
7
- import { b as VitestTransport } from './startModuleRunner.DPBo3mme.js';
7
+ import { ModuleRunner } from 'vite/module-runner';
8
+ import { b as VitestTransport } from './startModuleRunner.C2tTvmF9.js';
8
9
  import { e as environments } from './index.CbWINfS7.js';
9
- import { s as setupInspect } from './inspector.Br76Q2Mb.js';
10
+ import { s as setupInspect } from './inspector.DLZxSeU3.js';
11
+ import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
10
12
  import { c as createRuntimeRpc, a as rpcDone } from './rpc.cD77ENhU.js';
11
- import { i as isChildProcess } from './utils.CG9h5ccR.js';
12
13
 
13
14
  function isBuiltinEnvironment(env) {
14
15
  return env in environments;
@@ -59,82 +60,13 @@ async function loadEnvironment(ctx, rpc) {
59
60
  };
60
61
  }
61
62
 
62
- const REGEXP_WRAP_PREFIX = "$$vitest:", processSend = process.send?.bind(process), processOn = process.on?.bind(process), processOff = process.off?.bind(process), dispose = [];
63
- function createThreadsRpcOptions({ port }) {
64
- return {
65
- post: (v) => {
66
- port.postMessage(v);
67
- },
68
- on: (fn) => {
69
- port.addListener("message", fn);
70
- }
71
- };
72
- }
73
- function disposeInternalListeners() {
74
- for (const fn of dispose) try {
75
- fn();
76
- } catch {}
77
- dispose.length = 0;
78
- }
79
- function createForksRpcOptions(nodeV8) {
80
- return {
81
- serialize: nodeV8.serialize,
82
- deserialize: (v) => nodeV8.deserialize(Buffer.from(v)),
83
- post(v) {
84
- processSend(v);
85
- },
86
- on(fn) {
87
- const handler = (message, ...extras) => {
88
- if (!message?.__tinypool_worker_message__) return fn(message, ...extras);
89
- };
90
- processOn("message", handler), dispose.push(() => processOff("message", handler));
91
- }
92
- };
93
- }
94
- /**
95
- * Reverts the wrapping done by `utils/config-helpers.ts`'s `wrapSerializableConfig`
96
- */
97
- function unwrapSerializableConfig(config) {
98
- if (config.testNamePattern && typeof config.testNamePattern === "string") {
99
- const testNamePattern = config.testNamePattern;
100
- if (testNamePattern.startsWith(REGEXP_WRAP_PREFIX)) config.testNamePattern = parseRegexp(testNamePattern.slice(9));
101
- }
102
- if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) {
103
- const { keys, original } = config.defines, defines = {};
104
- // Apply all keys from the original. Entries which had undefined value are missing from original now
105
- for (const key of keys) defines[key] = original[key];
106
- config.defines = defines;
107
- }
108
- return config;
109
- }
110
- function parseRegexp(input) {
111
- // Parse input
112
- // eslint-disable-next-line regexp/no-misleading-capturing-group
113
- const m = input.match(/(\/?)(.+)\1([a-z]*)/i);
114
- // Create the regular expression
115
- return m ? m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3]) ? new RegExp(input) : new RegExp(m[2], m[3]) : /$^/;
116
- }
117
-
118
- if (isChildProcess()) {
119
- if (process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")))
120
- // Work-around for nodejs/node#55094
121
- process.on("SIGTERM", () => {
122
- process.exit();
123
- });
124
- }
125
63
  const resolvingModules = /* @__PURE__ */ new Set(), globalListeners = /* @__PURE__ */ new Set();
126
- // this is what every pool executes when running tests
127
64
  async function execute(method, ctx, worker) {
128
- disposeInternalListeners();
129
65
  const prepareStart = performance.now(), cleanups = [setupInspect(ctx)];
130
- process.env.VITEST_WORKER_ID = String(ctx.workerId);
131
- const poolId = process.__tinypool_state__?.workerId;
132
- process.env.VITEST_POOL_ID = String(poolId);
133
66
  let environmentLoader;
67
+ // RPC is used to communicate between worker (be it a thread worker or child process or a custom implementation) and the main thread
68
+ const { rpc, onCancel } = createRuntimeRpc(worker);
134
69
  try {
135
- if (!worker.getRpcOptions || typeof worker.getRpcOptions !== "function") throw new TypeError(`Test worker should expose "getRpcOptions" method. Received "${typeof worker.getRpcOptions}".`);
136
- // RPC is used to communicate between worker (be it a thread worker or child process or a custom implementation) and the main thread
137
- const { rpc, onCancel } = createRuntimeRpc(worker.getRpcOptions(ctx));
138
70
  // do not close the RPC channel so that we can get the error messages sent to the main thread
139
71
  cleanups.push(async () => {
140
72
  await Promise.all(rpc.$rejectPendingCalls(({ method, reject }) => {
@@ -145,7 +77,7 @@ async function execute(method, ctx, worker) {
145
77
  environmentLoader = loader;
146
78
  const state = {
147
79
  ctx,
148
- evaluatedModules: new EvaluatedModules(),
80
+ evaluatedModules: new VitestEvaluatedModules(),
149
81
  resolvingModules,
150
82
  moduleExecutionInfo: /* @__PURE__ */ new Map(),
151
83
  config: ctx.config,
@@ -166,12 +98,17 @@ async function execute(method, ctx, worker) {
166
98
  if (!worker[methodName] || typeof worker[methodName] !== "function") throw new TypeError(`Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`);
167
99
  await worker[methodName](state);
168
100
  } finally {
169
- await Promise.all(cleanups.map((fn) => fn())), await rpcDone().catch(() => {}), environmentLoader?.close();
101
+ await Promise.all(cleanups.map((fn) => fn())), await rpcDone().catch(() => {}), await environmentLoader?.close(), rpc.$close();
170
102
  }
171
103
  }
104
+ function run(ctx, worker) {
105
+ return execute("run", ctx, worker);
106
+ }
107
+ function collect(ctx, worker) {
108
+ return execute("collect", ctx, worker);
109
+ }
172
110
  async function teardown() {
173
- const promises = [...globalListeners].map((l) => l());
174
- await Promise.all(promises);
111
+ await Promise.all([...globalListeners].map((l) => l()));
175
112
  }
176
113
  function createImportMetaEnvProxy() {
177
114
  // packages/vitest/src/node/plugins/index.ts:146
@@ -193,4 +130,84 @@ function createImportMetaEnvProxy() {
193
130
  });
194
131
  }
195
132
 
196
- export { createThreadsRpcOptions as a, createForksRpcOptions as c, execute as e, teardown as t, unwrapSerializableConfig as u };
133
+ const __vitest_worker_response__ = true, memoryUsage = process.memoryUsage.bind(process);
134
+ let reportMemory = false;
135
+ /** @experimental */
136
+ function init(worker) {
137
+ worker.on(onMessage);
138
+ let runPromise, isRunning = false;
139
+ function send(response) {
140
+ worker.post(worker.serialize ? worker.serialize(response) : response);
141
+ }
142
+ async function onMessage(rawMessage) {
143
+ const message = worker.deserialize ? worker.deserialize(rawMessage) : rawMessage;
144
+ if (message?.__vitest_worker_request__ === true) switch (message.type) {
145
+ case "start":
146
+ reportMemory = message.options.reportMemory, send({
147
+ type: "started",
148
+ __vitest_worker_response__
149
+ });
150
+ break;
151
+ case "run":
152
+ // Prevent concurrent execution if worker is already running
153
+ if (isRunning) {
154
+ send({
155
+ type: "testfileFinished",
156
+ __vitest_worker_response__,
157
+ error: serializeError(/* @__PURE__ */ new Error("[vitest-worker]: Worker is already running tests"))
158
+ });
159
+ return;
160
+ }
161
+ isRunning = true, process.env.VITEST_POOL_ID = String(message.poolId), process.env.VITEST_WORKER_ID = String(message.context.workerId);
162
+ try {
163
+ runPromise = run(message.context, worker).catch((error) => serializeError(error));
164
+ const error = await runPromise;
165
+ send({
166
+ type: "testfileFinished",
167
+ __vitest_worker_response__,
168
+ error,
169
+ usedMemory: reportMemory ? memoryUsage().heapUsed : void 0
170
+ });
171
+ } finally {
172
+ runPromise = void 0, isRunning = false;
173
+ }
174
+ break;
175
+ case "collect":
176
+ // Prevent concurrent execution if worker is already running
177
+ if (isRunning) {
178
+ send({
179
+ type: "testfileFinished",
180
+ __vitest_worker_response__,
181
+ error: serializeError(/* @__PURE__ */ new Error("[vitest-worker]: Worker is already running tests"))
182
+ });
183
+ return;
184
+ }
185
+ isRunning = true, process.env.VITEST_POOL_ID = String(message.poolId), process.env.VITEST_WORKER_ID = String(message.context.workerId);
186
+ try {
187
+ runPromise = collect(message.context, worker).catch((error) => serializeError(error));
188
+ const error = await runPromise;
189
+ send({
190
+ type: "testfileFinished",
191
+ __vitest_worker_response__,
192
+ error,
193
+ usedMemory: reportMemory ? memoryUsage().heapUsed : void 0
194
+ });
195
+ } finally {
196
+ runPromise = void 0, isRunning = false;
197
+ }
198
+ break;
199
+ case "stop": {
200
+ await runPromise;
201
+ const error = await teardown().catch((error) => serializeError(error));
202
+ send({
203
+ type: "stopped",
204
+ error,
205
+ __vitest_worker_response__
206
+ }), worker.teardown?.();
207
+ break;
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ export { init as i };
@@ -32,8 +32,7 @@ function closeInspector(config) {
32
32
  }
33
33
  function shouldKeepOpen(config) {
34
34
  // In watch mode the inspector can persist re-runs if isolation is disabled and a single worker is used
35
- const isIsolatedSingleThread = config.pool === "threads" && config.poolOptions?.threads?.isolate === false && config.poolOptions?.threads?.singleThread, isIsolatedSingleFork = config.pool === "forks" && config.poolOptions?.forks?.isolate === false && config.poolOptions?.forks?.singleFork;
36
- return config.watch && (isIsolatedSingleFork || isIsolatedSingleThread);
35
+ return config.watch && config.isolate === false && config.maxWorkers === 1;
37
36
  }
38
37
 
39
38
  export { closeInspector as c, setupInspect as s };
@@ -2,7 +2,7 @@ import * as _vitest_spy from '@vitest/spy';
2
2
  import vm from 'node:vm';
3
3
  import * as viteModuleRunner from 'vite/module-runner';
4
4
  import { ModuleEvaluator, ModuleRunnerImportMeta, ModuleRunnerContext, EvaluatedModuleNode, FetchFunction, EvaluatedModules } from 'vite/module-runner';
5
- import { a as RuntimeRPC, c as ResolveFunctionResult, W as WorkerGlobalState } from './worker.d.DSgBAZPX.js';
5
+ import { R as RuntimeRPC, d as ResolveFunctionResult, W as WorkerGlobalState } from './worker.d.BFk-vvBU.js';
6
6
  import { MockedModule, MockedModuleType } from '@vitest/mocker';
7
7
  import { P as PendingSuiteMock, b as MockFactory, a as MockOptions } from './mocker.d.BE_2ls6u.js';
8
8
 
@@ -1,4 +1,4 @@
1
- import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.BJ_OuJGZ.js';
1
+ import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.C6nGyY9_.js';
2
2
 
3
3
  interface VitestPluginContext {
4
4
  vitest: Vitest;