vitest 2.0.0-beta.9 → 2.0.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.
- package/LICENSE.md +1 -22
- package/dist/browser.d.ts +24 -7
- package/dist/browser.js +5 -19
- package/dist/chunks/browser-creator.DSqYDthP.js +673 -0
- package/dist/chunks/{environments-node.39w4gmlF.js → environments-node.XE5FbRPQ.js} +1 -1
- package/dist/chunks/{integrations-globals.BK0Cn4q1.js → integrations-globals.CzYWb38r.js} +10 -9
- package/dist/chunks/{node-git.CCI8evVZ.js → node-git.ZtkbKc8u.js} +14 -15
- package/dist/chunks/{runtime-console.DiVMr5d4.js → runtime-console.O41g23Zj.js} +26 -11
- package/dist/chunks/{runtime-runBaseTests.C-Bkopka.js → runtime-runBaseTests.DX3h28Mp.js} +47 -34
- package/dist/cli.js +3 -3
- package/dist/config.cjs +48 -23
- package/dist/config.d.ts +2 -1
- package/dist/config.js +48 -24
- package/dist/coverage.d.ts +6 -4
- package/dist/coverage.js +102 -38
- package/dist/environments.d.ts +2 -1
- package/dist/environments.js +1 -1
- package/dist/execute.d.ts +4 -3
- package/dist/execute.js +2 -2
- package/dist/index.d.ts +1437 -7
- package/dist/index.js +10 -9
- package/dist/node.d.ts +34 -7
- package/dist/node.js +31 -20
- package/dist/path.js +4 -1
- package/dist/{reporters-DaDey3o0.d.ts → reporters-DrhyxxXt.d.ts} +213 -206
- package/dist/reporters.d.ts +2 -1
- package/dist/reporters.js +8 -8
- package/dist/runners.d.ts +3 -1
- package/dist/runners.js +100 -61
- package/dist/snapshot.js +2 -2
- package/dist/{suite-BHSUxUib.d.ts → suite-DCPwkk7G.d.ts} +1 -1
- package/dist/suite.d.ts +3 -2
- package/dist/suite.js +3 -3
- package/dist/utils.d.ts +1 -5
- package/dist/utils.js +1 -6
- package/dist/vendor/{base._gnK9Slw.js → base.CTYV4Gnz.js} +24 -17
- package/dist/vendor/{base.D4XK-wRp.js → base.CdA1i5tB.js} +6 -4
- package/dist/vendor/{benchmark.BNLebNi5.js → benchmark.B6pblCp2.js} +13 -14
- package/dist/vendor/{cac.DCg3FnEs.js → cac.5nBDv26-.js} +142 -47
- package/dist/vendor/{cli-api.LMvYagQ5.js → cli-api.BT4NJtxX.js} +4162 -9514
- package/dist/vendor/{constants.TCjCaw2D.js → constants.CsnA4eRy.js} +5 -23
- package/dist/vendor/{coverage.ChSqD-qS.js → coverage.BhYSDdTT.js} +27 -11
- package/dist/vendor/{date.BKM1wewY.js → date.W2xKR2qe.js} +5 -3
- package/dist/vendor/env.2ltrQNq0.js +8 -0
- package/dist/vendor/{execute.BHj6OMh4.js → execute.Dx503nGn.js} +186 -64
- package/dist/vendor/{index.TBU3GqRP.js → index.3x3MdmUV.js} +1075 -526
- package/dist/vendor/{index._7XLd8Kd.js → index.BJmtb_7W.js} +3 -2
- package/dist/vendor/{index.DP-km6lF.js → index.BMmMjLIQ.js} +64 -51
- package/dist/vendor/{index.DHRpy7zp.js → index.CROIsoiT.js} +18 -10
- package/dist/vendor/{index.DeR1hhfY.js → index.D4nqnQWz.js} +71 -74
- package/dist/vendor/index.D6GZqexG.js +6575 -0
- package/dist/vendor/{index.DwR86H5i.js → index.Hqvcg1pf.js} +4 -27
- package/dist/vendor/{rpc.DRDE9Pu1.js → rpc.BGx7q_k2.js} +30 -19
- package/dist/vendor/run-once.Db8Hgq9X.js +28 -0
- package/dist/vendor/{setup-common.BhJvzjns.js → setup-common.yHaxjRhz.js} +30 -15
- package/dist/vendor/spy.Cf_4R5Oe.js +22 -0
- package/dist/vendor/{tasks.WC7M-K-v.js → tasks.DhVtQBtW.js} +3 -1
- package/dist/vendor/{utils.YuQ3LT2a.js → utils.BVMrsl6E.js} +55 -30
- package/dist/vendor/{utils.CUjzkRH7.js → utils.DkxLWvS1.js} +12 -5
- package/dist/vendor/{vi.C6AfDXK6.js → vi.DXACdGTu.js} +269 -136
- package/dist/vendor/{vm.Ow-X2mkS.js → vm.BrDS6p7h.js} +157 -90
- package/dist/worker.js +41 -18
- package/dist/workers/forks.js +12 -6
- package/dist/workers/runVmTests.js +22 -16
- package/dist/workers/threads.js +8 -5
- package/dist/workers/vmForks.js +15 -9
- package/dist/workers/vmThreads.js +11 -8
- package/dist/workers.d.ts +8 -5
- package/dist/workers.js +11 -11
- package/package.json +22 -21
- package/suppress-warnings.cjs +2 -4
- package/dist/index-B0dCycbN.d.ts +0 -1571
- package/dist/vendor/env.bmJgw1qP.js +0 -7
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
const defaultPort = 51204;
|
|
2
2
|
const defaultBrowserPort = 63315;
|
|
3
3
|
const defaultInspectPort = 9229;
|
|
4
|
-
const EXIT_CODE_RESTART = 43;
|
|
5
4
|
const API_PATH = "/__vitest_api__";
|
|
6
|
-
const BROWSER_API_PATH = "/__vitest_browser_api__";
|
|
7
5
|
const extraInlineDeps = [
|
|
8
6
|
/^(?!.*node_modules).*\.mjs$/,
|
|
9
7
|
/^(?!.*node_modules).*\.cjs\.js$/,
|
|
@@ -12,29 +10,13 @@ const extraInlineDeps = [
|
|
|
12
10
|
// Nuxt
|
|
13
11
|
"@nuxt/test-utils"
|
|
14
12
|
];
|
|
15
|
-
const CONFIG_NAMES = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
];
|
|
19
|
-
const WORKSPACES_NAMES = [
|
|
20
|
-
"vitest.workspace",
|
|
21
|
-
"vitest.projects"
|
|
22
|
-
];
|
|
23
|
-
const CONFIG_EXTENSIONS = [
|
|
24
|
-
".ts",
|
|
25
|
-
".mts",
|
|
26
|
-
".cts",
|
|
27
|
-
".js",
|
|
28
|
-
".mjs",
|
|
29
|
-
".cjs"
|
|
30
|
-
];
|
|
13
|
+
const CONFIG_NAMES = ["vitest.config", "vite.config"];
|
|
14
|
+
const WORKSPACES_NAMES = ["vitest.workspace", "vitest.projects"];
|
|
15
|
+
const CONFIG_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
|
|
31
16
|
const configFiles = CONFIG_NAMES.flatMap(
|
|
32
17
|
(name) => CONFIG_EXTENSIONS.map((ext) => name + ext)
|
|
33
18
|
);
|
|
34
|
-
const WORKSPACES_EXTENSIONS = [
|
|
35
|
-
...CONFIG_EXTENSIONS,
|
|
36
|
-
".json"
|
|
37
|
-
];
|
|
19
|
+
const WORKSPACES_EXTENSIONS = [...CONFIG_EXTENSIONS, ".json"];
|
|
38
20
|
const workspacesFiles = WORKSPACES_NAMES.flatMap(
|
|
39
21
|
(name) => WORKSPACES_EXTENSIONS.map((ext) => name + ext)
|
|
40
22
|
);
|
|
@@ -63,4 +45,4 @@ const globalApis = [
|
|
|
63
45
|
"onTestFailed"
|
|
64
46
|
];
|
|
65
47
|
|
|
66
|
-
export { API_PATH as A,
|
|
48
|
+
export { API_PATH as A, CONFIG_NAMES as C, defaultBrowserPort as a, defaultInspectPort as b, configFiles as c, defaultPort as d, extraInlineDeps as e, globalApis as g, workspacesFiles as w };
|
|
@@ -3,50 +3,66 @@ const CoverageProviderMap = {
|
|
|
3
3
|
istanbul: "@vitest/coverage-istanbul"
|
|
4
4
|
};
|
|
5
5
|
async function resolveCoverageProviderModule(options, loader) {
|
|
6
|
-
if (!(options == null ? void 0 : options.enabled) || !options.provider)
|
|
6
|
+
if (!(options == null ? void 0 : options.enabled) || !options.provider) {
|
|
7
7
|
return null;
|
|
8
|
+
}
|
|
8
9
|
const provider = options.provider;
|
|
9
10
|
if (provider === "v8" || provider === "istanbul") {
|
|
10
|
-
const { default: coverageModule } = await loader.executeId(
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const { default: coverageModule } = await loader.executeId(
|
|
12
|
+
CoverageProviderMap[provider]
|
|
13
|
+
);
|
|
14
|
+
if (!coverageModule) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`Failed to load ${CoverageProviderMap[provider]}. Default export is missing.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
13
19
|
return coverageModule;
|
|
14
20
|
}
|
|
15
21
|
let customProviderModule;
|
|
16
22
|
try {
|
|
17
23
|
customProviderModule = await loader.executeId(options.customProviderModule);
|
|
18
24
|
} catch (error) {
|
|
19
|
-
throw new Error(
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Failed to load custom CoverageProviderModule from ${options.customProviderModule}`,
|
|
27
|
+
{ cause: error }
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
if (customProviderModule.default == null) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Custom CoverageProviderModule loaded from ${options.customProviderModule} was not the default export`
|
|
33
|
+
);
|
|
20
34
|
}
|
|
21
|
-
if (customProviderModule.default == null)
|
|
22
|
-
throw new Error(`Custom CoverageProviderModule loaded from ${options.customProviderModule} was not the default export`);
|
|
23
35
|
return customProviderModule.default;
|
|
24
36
|
}
|
|
25
37
|
async function getCoverageProvider(options, loader) {
|
|
26
38
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
27
|
-
if (coverageModule)
|
|
39
|
+
if (coverageModule) {
|
|
28
40
|
return coverageModule.getProvider();
|
|
41
|
+
}
|
|
29
42
|
return null;
|
|
30
43
|
}
|
|
31
44
|
async function startCoverageInsideWorker(options, loader) {
|
|
32
45
|
var _a;
|
|
33
46
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
34
|
-
if (coverageModule)
|
|
47
|
+
if (coverageModule) {
|
|
35
48
|
return (_a = coverageModule.startCoverage) == null ? void 0 : _a.call(coverageModule);
|
|
49
|
+
}
|
|
36
50
|
return null;
|
|
37
51
|
}
|
|
38
52
|
async function takeCoverageInsideWorker(options, loader) {
|
|
39
53
|
var _a;
|
|
40
54
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
41
|
-
if (coverageModule)
|
|
55
|
+
if (coverageModule) {
|
|
42
56
|
return (_a = coverageModule.takeCoverage) == null ? void 0 : _a.call(coverageModule);
|
|
57
|
+
}
|
|
43
58
|
return null;
|
|
44
59
|
}
|
|
45
60
|
async function stopCoverageInsideWorker(options, loader) {
|
|
46
61
|
var _a;
|
|
47
62
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
48
|
-
if (coverageModule)
|
|
63
|
+
if (coverageModule) {
|
|
49
64
|
return (_a = coverageModule.stopCoverage) == null ? void 0 : _a.call(coverageModule);
|
|
65
|
+
}
|
|
50
66
|
return null;
|
|
51
67
|
}
|
|
52
68
|
|
|
@@ -6,10 +6,11 @@ class MockDate extends RealDate {
|
|
|
6
6
|
let date;
|
|
7
7
|
switch (arguments.length) {
|
|
8
8
|
case 0:
|
|
9
|
-
if (now !== null)
|
|
9
|
+
if (now !== null) {
|
|
10
10
|
date = new RealDate(now.valueOf());
|
|
11
|
-
else
|
|
11
|
+
} else {
|
|
12
12
|
date = new RealDate();
|
|
13
|
+
}
|
|
13
14
|
break;
|
|
14
15
|
case 1:
|
|
15
16
|
date = new RealDate(y);
|
|
@@ -39,8 +40,9 @@ MockDate.toString = function() {
|
|
|
39
40
|
};
|
|
40
41
|
function mockDate(date) {
|
|
41
42
|
const dateObj = new RealDate(date.valueOf());
|
|
42
|
-
if (Number.isNaN(dateObj.getTime()))
|
|
43
|
+
if (Number.isNaN(dateObj.getTime())) {
|
|
43
44
|
throw new TypeError(`mockdate: The time set is an invalid date: ${date}`);
|
|
45
|
+
}
|
|
44
46
|
globalThis.Date = MockDate;
|
|
45
47
|
now = dateObj.valueOf();
|
|
46
48
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import 'std-env';
|
|
2
|
+
|
|
3
|
+
var _a, _b;
|
|
4
|
+
const isNode = typeof process < "u" && typeof process.stdout < "u" && !((_a = process.versions) == null ? void 0 : _a.deno) && !globalThis.window;
|
|
5
|
+
const isDeno = typeof process < "u" && typeof process.stdout < "u" && ((_b = process.versions) == null ? void 0 : _b.deno) !== void 0;
|
|
6
|
+
const isWindows = (isNode || isDeno) && process.platform === "win32";
|
|
7
|
+
|
|
8
|
+
export { isDeno as a, isWindows as b, isNode as i };
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import vm from 'node:vm';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
|
-
import
|
|
3
|
+
import fs from 'node:fs';
|
|
4
4
|
import { ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client';
|
|
5
5
|
import { isNodeBuiltin, isInternalRequest, toFilePath, isPrimitive } from 'vite-node/utils';
|
|
6
6
|
import { resolve, isAbsolute, dirname, join, basename, extname, normalize, relative } from 'pathe';
|
|
7
7
|
import { processError } from '@vitest/utils/error';
|
|
8
8
|
import { distDir } from '../path.js';
|
|
9
9
|
import { highlight, getType } from '@vitest/utils';
|
|
10
|
-
import { g as getAllMockableProperties } from './base.
|
|
10
|
+
import { g as getAllMockableProperties } from './base.CTYV4Gnz.js';
|
|
11
11
|
|
|
12
|
+
const { existsSync, readdirSync } = fs;
|
|
12
13
|
const spyModulePath = resolve(distDir, "spy.js");
|
|
13
14
|
class RefTracker {
|
|
14
15
|
idMap = /* @__PURE__ */ new Map();
|
|
@@ -33,12 +34,39 @@ class VitestMocker {
|
|
|
33
34
|
constructor(executor) {
|
|
34
35
|
this.executor = executor;
|
|
35
36
|
const context = this.executor.options.context;
|
|
36
|
-
if (context)
|
|
37
|
-
this.primitives = vm.runInContext(
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if (context) {
|
|
38
|
+
this.primitives = vm.runInContext(
|
|
39
|
+
"({ Object, Error, Function, RegExp, Symbol, Array, Map })",
|
|
40
|
+
context
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
this.primitives = {
|
|
44
|
+
Object,
|
|
45
|
+
Error,
|
|
46
|
+
Function,
|
|
47
|
+
RegExp,
|
|
48
|
+
Symbol: globalThis.Symbol,
|
|
49
|
+
Array,
|
|
50
|
+
Map
|
|
51
|
+
};
|
|
52
|
+
}
|
|
40
53
|
const Symbol2 = this.primitives.Symbol;
|
|
41
|
-
this.filterPublicKeys = [
|
|
54
|
+
this.filterPublicKeys = [
|
|
55
|
+
"__esModule",
|
|
56
|
+
Symbol2.asyncIterator,
|
|
57
|
+
Symbol2.hasInstance,
|
|
58
|
+
Symbol2.isConcatSpreadable,
|
|
59
|
+
Symbol2.iterator,
|
|
60
|
+
Symbol2.match,
|
|
61
|
+
Symbol2.matchAll,
|
|
62
|
+
Symbol2.replace,
|
|
63
|
+
Symbol2.search,
|
|
64
|
+
Symbol2.split,
|
|
65
|
+
Symbol2.species,
|
|
66
|
+
Symbol2.toPrimitive,
|
|
67
|
+
Symbol2.toStringTag,
|
|
68
|
+
Symbol2.unscopables
|
|
69
|
+
];
|
|
42
70
|
}
|
|
43
71
|
static pendingIds = [];
|
|
44
72
|
spyModule;
|
|
@@ -65,8 +93,9 @@ class VitestMocker {
|
|
|
65
93
|
}
|
|
66
94
|
deleteCachedItem(id) {
|
|
67
95
|
const mockId = this.getMockPath(id);
|
|
68
|
-
if (this.moduleCache.has(mockId))
|
|
96
|
+
if (this.moduleCache.has(mockId)) {
|
|
69
97
|
this.moduleCache.delete(mockId);
|
|
98
|
+
}
|
|
70
99
|
}
|
|
71
100
|
isModuleDirectory(path) {
|
|
72
101
|
return this.moduleDirectories.some((dir) => path.includes(dir));
|
|
@@ -111,22 +140,31 @@ class VitestMocker {
|
|
|
111
140
|
};
|
|
112
141
|
}
|
|
113
142
|
async resolveMocks() {
|
|
114
|
-
if (!VitestMocker.pendingIds.length)
|
|
143
|
+
if (!VitestMocker.pendingIds.length) {
|
|
115
144
|
return;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
145
|
+
}
|
|
146
|
+
await Promise.all(
|
|
147
|
+
VitestMocker.pendingIds.map(async (mock) => {
|
|
148
|
+
const { fsPath, external } = await this.resolvePath(
|
|
149
|
+
mock.id,
|
|
150
|
+
mock.importer
|
|
151
|
+
);
|
|
152
|
+
if (mock.type === "unmock") {
|
|
153
|
+
this.unmockPath(fsPath);
|
|
154
|
+
}
|
|
155
|
+
if (mock.type === "mock") {
|
|
156
|
+
this.mockPath(mock.id, fsPath, external, mock.factory);
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
);
|
|
123
160
|
VitestMocker.pendingIds = [];
|
|
124
161
|
}
|
|
125
162
|
async callFunctionMock(dep, mock) {
|
|
126
163
|
var _a, _b;
|
|
127
164
|
const cached = (_a = this.moduleCache.get(dep)) == null ? void 0 : _a.exports;
|
|
128
|
-
if (cached)
|
|
165
|
+
if (cached) {
|
|
129
166
|
return cached;
|
|
167
|
+
}
|
|
130
168
|
let exports;
|
|
131
169
|
try {
|
|
132
170
|
exports = await mock();
|
|
@@ -139,19 +177,26 @@ class VitestMocker {
|
|
|
139
177
|
}
|
|
140
178
|
const filepath = dep.slice(5);
|
|
141
179
|
const mockpath = ((_b = this.resolveCache.get(this.getSuiteFilepath())) == null ? void 0 : _b[filepath]) || filepath;
|
|
142
|
-
if (exports === null || typeof exports !== "object")
|
|
143
|
-
throw this.createError(
|
|
180
|
+
if (exports === null || typeof exports !== "object") {
|
|
181
|
+
throw this.createError(
|
|
182
|
+
`[vitest] vi.mock("${mockpath}", factory?: () => unknown) is not returning an object. Did you mean to return an object with a "default" key?`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
144
185
|
const moduleExports = new Proxy(exports, {
|
|
145
186
|
get: (target, prop) => {
|
|
146
187
|
const val = target[prop];
|
|
147
188
|
if (prop === "then") {
|
|
148
|
-
if (target instanceof Promise)
|
|
189
|
+
if (target instanceof Promise) {
|
|
149
190
|
return target.then.bind(target);
|
|
191
|
+
}
|
|
150
192
|
} else if (!(prop in target)) {
|
|
151
|
-
if (this.filterPublicKeys.includes(prop))
|
|
193
|
+
if (this.filterPublicKeys.includes(prop)) {
|
|
152
194
|
return void 0;
|
|
195
|
+
}
|
|
153
196
|
throw this.createError(
|
|
154
|
-
`[vitest] No "${String(
|
|
197
|
+
`[vitest] No "${String(
|
|
198
|
+
prop
|
|
199
|
+
)}" export is defined on the "${mockpath}" mock. Did you forget to return it from "vi.mock"?
|
|
155
200
|
If you need to partially mock a module, you can use "importOriginal" helper inside:
|
|
156
201
|
`,
|
|
157
202
|
highlight(`vi.mock("${mockpath}", async (importOriginal) => {
|
|
@@ -186,14 +231,16 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
186
231
|
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
|
|
187
232
|
const mockDirname = dirname(path);
|
|
188
233
|
const mockFolder = join(this.root, "__mocks__", mockDirname);
|
|
189
|
-
if (!existsSync(mockFolder))
|
|
234
|
+
if (!existsSync(mockFolder)) {
|
|
190
235
|
return null;
|
|
236
|
+
}
|
|
191
237
|
const files = readdirSync(mockFolder);
|
|
192
238
|
const baseOriginal = basename(path);
|
|
193
239
|
for (const file of files) {
|
|
194
240
|
const baseFile = basename(file, extname(file));
|
|
195
|
-
if (baseFile === baseOriginal)
|
|
241
|
+
if (baseFile === baseOriginal) {
|
|
196
242
|
return resolve(mockFolder, file);
|
|
243
|
+
}
|
|
197
244
|
}
|
|
198
245
|
return null;
|
|
199
246
|
}
|
|
@@ -216,7 +263,11 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
216
263
|
const mockPropertiesOf = (container, newContainer) => {
|
|
217
264
|
const containerType = getType(container);
|
|
218
265
|
const isModule = containerType === "Module" || !!container.__esModule;
|
|
219
|
-
for (const { key: property, descriptor } of getAllMockableProperties(
|
|
266
|
+
for (const { key: property, descriptor } of getAllMockableProperties(
|
|
267
|
+
container,
|
|
268
|
+
isModule,
|
|
269
|
+
this.primitives
|
|
270
|
+
)) {
|
|
220
271
|
if (!isModule && descriptor.get) {
|
|
221
272
|
try {
|
|
222
273
|
Object.defineProperty(newContainer, property, descriptor);
|
|
@@ -224,12 +275,15 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
224
275
|
}
|
|
225
276
|
continue;
|
|
226
277
|
}
|
|
227
|
-
if (isSpecialProp(property, containerType))
|
|
278
|
+
if (isSpecialProp(property, containerType)) {
|
|
228
279
|
continue;
|
|
280
|
+
}
|
|
229
281
|
const value = container[property];
|
|
230
282
|
const refId = refs.getId(value);
|
|
231
283
|
if (refId !== void 0) {
|
|
232
|
-
finalizers.push(
|
|
284
|
+
finalizers.push(
|
|
285
|
+
() => define(newContainer, property, refs.getMockedValue(refId))
|
|
286
|
+
);
|
|
233
287
|
continue;
|
|
234
288
|
}
|
|
235
289
|
const type = getType(value);
|
|
@@ -242,14 +296,20 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
242
296
|
define(newContainer, property, value);
|
|
243
297
|
continue;
|
|
244
298
|
}
|
|
245
|
-
if (!define(newContainer, property, isFunction ? value : {}))
|
|
299
|
+
if (!define(newContainer, property, isFunction ? value : {})) {
|
|
246
300
|
continue;
|
|
301
|
+
}
|
|
247
302
|
if (isFunction) {
|
|
248
303
|
let mockFunction2 = function() {
|
|
249
304
|
if (this instanceof newContainer[property]) {
|
|
250
|
-
for (const { key, descriptor: descriptor2 } of getAllMockableProperties(
|
|
251
|
-
|
|
305
|
+
for (const { key, descriptor: descriptor2 } of getAllMockableProperties(
|
|
306
|
+
this,
|
|
307
|
+
false,
|
|
308
|
+
primitives
|
|
309
|
+
)) {
|
|
310
|
+
if (descriptor2.get) {
|
|
252
311
|
continue;
|
|
312
|
+
}
|
|
253
313
|
const value2 = this[key];
|
|
254
314
|
const type2 = getType(value2);
|
|
255
315
|
const isFunction2 = type2.includes("Function") && typeof value2 === "function";
|
|
@@ -265,8 +325,11 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
265
325
|
}
|
|
266
326
|
}
|
|
267
327
|
};
|
|
268
|
-
if (!this.spyModule)
|
|
269
|
-
throw this.createError(
|
|
328
|
+
if (!this.spyModule) {
|
|
329
|
+
throw this.createError(
|
|
330
|
+
"[vitest] `spyModule` is not defined. This is Vitest error. Please open a new issue with reproduction."
|
|
331
|
+
);
|
|
332
|
+
}
|
|
270
333
|
const spyModule = this.spyModule;
|
|
271
334
|
const primitives = this.primitives;
|
|
272
335
|
const mock = spyModule.spyOn(newContainer, property).mockImplementation(mockFunction2);
|
|
@@ -283,16 +346,18 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
283
346
|
};
|
|
284
347
|
const mockedObject = mockExports;
|
|
285
348
|
mockPropertiesOf(object, mockedObject);
|
|
286
|
-
for (const finalizer of finalizers)
|
|
349
|
+
for (const finalizer of finalizers) {
|
|
287
350
|
finalizer();
|
|
351
|
+
}
|
|
288
352
|
return mockedObject;
|
|
289
353
|
}
|
|
290
354
|
unmockPath(path) {
|
|
291
355
|
const suitefile = this.getSuiteFilepath();
|
|
292
356
|
const id = this.normalizePath(path);
|
|
293
357
|
const mock = this.mockMap.get(suitefile);
|
|
294
|
-
if (mock && id in mock)
|
|
358
|
+
if (mock && id in mock) {
|
|
295
359
|
delete mock[id];
|
|
360
|
+
}
|
|
296
361
|
this.deleteCachedItem(id);
|
|
297
362
|
}
|
|
298
363
|
mockPath(originalId, path, external, factory) {
|
|
@@ -308,21 +373,27 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
308
373
|
}
|
|
309
374
|
async importActual(rawId, importer, callstack) {
|
|
310
375
|
const { id, fsPath } = await this.resolvePath(rawId, importer);
|
|
311
|
-
const result = await this.executor.cachedRequest(
|
|
376
|
+
const result = await this.executor.cachedRequest(
|
|
377
|
+
id,
|
|
378
|
+
fsPath,
|
|
379
|
+
callstack || [importer]
|
|
380
|
+
);
|
|
312
381
|
return result;
|
|
313
382
|
}
|
|
314
383
|
async importMock(rawId, importee) {
|
|
315
384
|
const { id, fsPath, external } = await this.resolvePath(rawId, importee);
|
|
316
385
|
const normalizedId = this.normalizePath(fsPath);
|
|
317
386
|
let mock = this.getDependencyMock(normalizedId);
|
|
318
|
-
if (mock === void 0)
|
|
387
|
+
if (mock === void 0) {
|
|
319
388
|
mock = this.resolveMockPath(fsPath, external);
|
|
389
|
+
}
|
|
320
390
|
if (mock === null) {
|
|
321
391
|
const mod = await this.executor.cachedRequest(id, fsPath, [importee]);
|
|
322
392
|
return this.mockObject(mod);
|
|
323
393
|
}
|
|
324
|
-
if (typeof mock === "function")
|
|
394
|
+
if (typeof mock === "function") {
|
|
325
395
|
return this.callFunctionMock(fsPath, mock);
|
|
396
|
+
}
|
|
326
397
|
return this.executor.dependencyRequest(mock, mock, [importee]);
|
|
327
398
|
}
|
|
328
399
|
async requestWithMock(url, callstack) {
|
|
@@ -331,8 +402,9 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
331
402
|
const mockPath = this.getMockPath(id);
|
|
332
403
|
if (mock === null) {
|
|
333
404
|
const cache = this.moduleCache.get(mockPath);
|
|
334
|
-
if (cache.exports)
|
|
405
|
+
if (cache.exports) {
|
|
335
406
|
return cache.exports;
|
|
407
|
+
}
|
|
336
408
|
const exports = {};
|
|
337
409
|
this.moduleCache.set(mockPath, { exports });
|
|
338
410
|
const mod = await this.executor.directRequest(url, url, callstack);
|
|
@@ -350,17 +422,30 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
350
422
|
callstack.splice(indexMock, 1);
|
|
351
423
|
}
|
|
352
424
|
}
|
|
353
|
-
if (typeof mock === "string" && !callstack.includes(mock))
|
|
425
|
+
if (typeof mock === "string" && !callstack.includes(mock)) {
|
|
354
426
|
return mock;
|
|
427
|
+
}
|
|
355
428
|
}
|
|
356
429
|
queueMock(id, importer, factory, throwIfCached = false) {
|
|
357
|
-
VitestMocker.pendingIds.push({
|
|
430
|
+
VitestMocker.pendingIds.push({
|
|
431
|
+
type: "mock",
|
|
432
|
+
id,
|
|
433
|
+
importer,
|
|
434
|
+
factory,
|
|
435
|
+
throwIfCached
|
|
436
|
+
});
|
|
358
437
|
}
|
|
359
438
|
queueUnmock(id, importer, throwIfCached = false) {
|
|
360
|
-
VitestMocker.pendingIds.push({
|
|
439
|
+
VitestMocker.pendingIds.push({
|
|
440
|
+
type: "unmock",
|
|
441
|
+
id,
|
|
442
|
+
importer,
|
|
443
|
+
throwIfCached
|
|
444
|
+
});
|
|
361
445
|
}
|
|
362
446
|
}
|
|
363
447
|
|
|
448
|
+
const { readFileSync } = fs;
|
|
364
449
|
async function createVitestExecutor(options) {
|
|
365
450
|
const runner = new VitestExecutor(options);
|
|
366
451
|
await runner.executeId("/@vite/env");
|
|
@@ -373,20 +458,27 @@ const dispose = [];
|
|
|
373
458
|
function listenForErrors(state) {
|
|
374
459
|
dispose.forEach((fn) => fn());
|
|
375
460
|
dispose.length = 0;
|
|
376
|
-
function catchError(err, type) {
|
|
461
|
+
function catchError(err, type, event) {
|
|
377
462
|
var _a;
|
|
378
463
|
const worker = state();
|
|
464
|
+
if (worker.current) {
|
|
465
|
+
const listeners = process.listeners(event);
|
|
466
|
+
if (listeners.length > 1) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
379
470
|
const error = processError(err);
|
|
380
471
|
if (!isPrimitive(error)) {
|
|
381
472
|
error.VITEST_TEST_NAME = (_a = worker.current) == null ? void 0 : _a.name;
|
|
382
|
-
if (worker.filepath)
|
|
473
|
+
if (worker.filepath) {
|
|
383
474
|
error.VITEST_TEST_PATH = relative(state().config.root, worker.filepath);
|
|
475
|
+
}
|
|
384
476
|
error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun;
|
|
385
477
|
}
|
|
386
478
|
state().rpc.onUnhandledError(error, type);
|
|
387
479
|
}
|
|
388
|
-
const uncaughtException = (e) => catchError(e, "Uncaught Exception");
|
|
389
|
-
const unhandledRejection = (e) => catchError(e, "Unhandled Rejection");
|
|
480
|
+
const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException");
|
|
481
|
+
const unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
|
|
390
482
|
process.on("uncaughtException", uncaughtException);
|
|
391
483
|
process.on("unhandledRejection", unhandledRejection);
|
|
392
484
|
dispose.push(() => {
|
|
@@ -395,7 +487,10 @@ function listenForErrors(state) {
|
|
|
395
487
|
});
|
|
396
488
|
}
|
|
397
489
|
async function startVitestExecutor(options) {
|
|
398
|
-
const state = () =>
|
|
490
|
+
const state = () => (
|
|
491
|
+
// @ts-expect-error injected untyped global
|
|
492
|
+
globalThis.__vitest_worker__ || options.state
|
|
493
|
+
);
|
|
399
494
|
const rpc = () => state().rpc;
|
|
400
495
|
process.exit = (code = process.exitCode || 0) => {
|
|
401
496
|
throw new Error(`process.exit unexpectedly called with "${code}"`);
|
|
@@ -406,8 +501,9 @@ async function startVitestExecutor(options) {
|
|
|
406
501
|
};
|
|
407
502
|
return await createVitestExecutor({
|
|
408
503
|
async fetchModule(id) {
|
|
409
|
-
if (externalizeMap.has(id))
|
|
504
|
+
if (externalizeMap.has(id)) {
|
|
410
505
|
return { externalize: externalizeMap.get(id) };
|
|
506
|
+
}
|
|
411
507
|
if (id.includes(distDir)) {
|
|
412
508
|
const { path } = toFilePath(id, state().config.root);
|
|
413
509
|
const externalize = pathToFileURL(path).toString();
|
|
@@ -450,8 +546,9 @@ async function startVitestExecutor(options) {
|
|
|
450
546
|
});
|
|
451
547
|
}
|
|
452
548
|
function updateStyle(id, css) {
|
|
453
|
-
if (typeof document === "undefined")
|
|
549
|
+
if (typeof document === "undefined") {
|
|
454
550
|
return;
|
|
551
|
+
}
|
|
455
552
|
const element = document.querySelector(`[data-vite-dev-id="${id}"]`);
|
|
456
553
|
if (element) {
|
|
457
554
|
element.textContent = css;
|
|
@@ -465,15 +562,21 @@ function updateStyle(id, css) {
|
|
|
465
562
|
head == null ? void 0 : head.appendChild(style);
|
|
466
563
|
}
|
|
467
564
|
function removeStyle(id) {
|
|
468
|
-
if (typeof document === "undefined")
|
|
565
|
+
if (typeof document === "undefined") {
|
|
469
566
|
return;
|
|
567
|
+
}
|
|
470
568
|
const sheet = document.querySelector(`[data-vite-dev-id="${id}"]`);
|
|
471
|
-
if (sheet)
|
|
569
|
+
if (sheet) {
|
|
472
570
|
document.head.removeChild(sheet);
|
|
571
|
+
}
|
|
473
572
|
}
|
|
474
573
|
function getDefaultRequestStubs(context) {
|
|
475
574
|
if (!context) {
|
|
476
|
-
const clientStub2 = {
|
|
575
|
+
const clientStub2 = {
|
|
576
|
+
...DEFAULT_REQUEST_STUBS["@vite/client"],
|
|
577
|
+
updateStyle,
|
|
578
|
+
removeStyle
|
|
579
|
+
};
|
|
477
580
|
return {
|
|
478
581
|
"/@vite/client": clientStub2,
|
|
479
582
|
"@vite/client": clientStub2
|
|
@@ -505,10 +608,15 @@ class VitestExecutor extends ViteNodeRunner {
|
|
|
505
608
|
});
|
|
506
609
|
this.primitives = { Object, Reflect, Symbol };
|
|
507
610
|
} else if (options.externalModulesExecutor) {
|
|
508
|
-
this.primitives = vm.runInContext(
|
|
611
|
+
this.primitives = vm.runInContext(
|
|
612
|
+
"({ Object, Reflect, Symbol })",
|
|
613
|
+
options.context
|
|
614
|
+
);
|
|
509
615
|
this.externalModules = options.externalModulesExecutor;
|
|
510
616
|
} else {
|
|
511
|
-
throw new Error(
|
|
617
|
+
throw new Error(
|
|
618
|
+
"When context is provided, externalModulesExecutor must be provided as well."
|
|
619
|
+
);
|
|
512
620
|
}
|
|
513
621
|
}
|
|
514
622
|
mocker;
|
|
@@ -522,8 +630,9 @@ class VitestExecutor extends ViteNodeRunner {
|
|
|
522
630
|
}
|
|
523
631
|
shouldResolveId(id, _importee) {
|
|
524
632
|
var _a;
|
|
525
|
-
if (isInternalRequest(id) || id.startsWith("data:"))
|
|
633
|
+
if (isInternalRequest(id) || id.startsWith("data:")) {
|
|
526
634
|
return false;
|
|
635
|
+
}
|
|
527
636
|
const transformMode = ((_a = this.state.environment) == null ? void 0 : _a.transformMode) ?? "ssr";
|
|
528
637
|
return transformMode === "ssr" ? !isNodeBuiltin(id) : !id.startsWith("node:");
|
|
529
638
|
}
|
|
@@ -531,10 +640,12 @@ class VitestExecutor extends ViteNodeRunner {
|
|
|
531
640
|
return super.resolveUrl(id, importer);
|
|
532
641
|
}
|
|
533
642
|
async resolveUrl(id, importer) {
|
|
534
|
-
if (VitestMocker.pendingIds.length)
|
|
643
|
+
if (VitestMocker.pendingIds.length) {
|
|
535
644
|
await this.mocker.resolveMocks();
|
|
536
|
-
|
|
645
|
+
}
|
|
646
|
+
if (importer && importer.startsWith("mock:")) {
|
|
537
647
|
importer = importer.slice(5);
|
|
648
|
+
}
|
|
538
649
|
try {
|
|
539
650
|
return await super.resolveUrl(id, importer);
|
|
540
651
|
} catch (error) {
|
|
@@ -542,17 +653,21 @@ class VitestExecutor extends ViteNodeRunner {
|
|
|
542
653
|
const { id: id2 } = error[Symbol.for("vitest.error.not_found.data")];
|
|
543
654
|
const path = this.mocker.normalizePath(id2);
|
|
544
655
|
const mock = this.mocker.getDependencyMock(path);
|
|
545
|
-
if (mock !== void 0)
|
|
656
|
+
if (mock !== void 0) {
|
|
546
657
|
return [id2, id2];
|
|
658
|
+
}
|
|
547
659
|
}
|
|
548
660
|
throw error;
|
|
549
661
|
}
|
|
550
662
|
}
|
|
551
663
|
async runModule(context, transformed) {
|
|
552
664
|
const vmContext = this.options.context;
|
|
553
|
-
if (!vmContext || !this.externalModules)
|
|
665
|
+
if (!vmContext || !this.externalModules) {
|
|
554
666
|
return super.runModule(context, transformed);
|
|
555
|
-
|
|
667
|
+
}
|
|
668
|
+
const codeDefinition = `'use strict';async (${Object.keys(context).join(
|
|
669
|
+
","
|
|
670
|
+
)})=>{{`;
|
|
556
671
|
const code = `${codeDefinition}${transformed}
|
|
557
672
|
}}`;
|
|
558
673
|
const options = {
|
|
@@ -568,25 +683,32 @@ class VitestExecutor extends ViteNodeRunner {
|
|
|
568
683
|
await fn(...Object.values(context));
|
|
569
684
|
}
|
|
570
685
|
async importExternalModule(path) {
|
|
571
|
-
if (this.externalModules)
|
|
686
|
+
if (this.externalModules) {
|
|
572
687
|
return this.externalModules.import(path);
|
|
688
|
+
}
|
|
573
689
|
return super.importExternalModule(path);
|
|
574
690
|
}
|
|
575
691
|
async dependencyRequest(id, fsPath, callstack) {
|
|
576
692
|
const mocked = await this.mocker.requestWithMock(fsPath, callstack);
|
|
577
|
-
if (typeof mocked === "string")
|
|
693
|
+
if (typeof mocked === "string") {
|
|
578
694
|
return super.dependencyRequest(mocked, mocked, callstack);
|
|
579
|
-
|
|
695
|
+
}
|
|
696
|
+
if (mocked && typeof mocked === "object") {
|
|
580
697
|
return mocked;
|
|
698
|
+
}
|
|
581
699
|
return super.dependencyRequest(id, fsPath, callstack);
|
|
582
700
|
}
|
|
583
701
|
prepareContext(context) {
|
|
584
702
|
if (this.state.filepath && normalize(this.state.filepath) === normalize(context.__filename)) {
|
|
585
703
|
const globalNamespace = this.options.context || globalThis;
|
|
586
|
-
Object.defineProperty(context.__vite_ssr_import_meta__, "vitest", {
|
|
704
|
+
Object.defineProperty(context.__vite_ssr_import_meta__, "vitest", {
|
|
705
|
+
// @ts-expect-error injected untyped global
|
|
706
|
+
get: () => globalNamespace.__vitest_index__
|
|
707
|
+
});
|
|
587
708
|
}
|
|
588
|
-
if (this.options.context && this.externalModules)
|
|
709
|
+
if (this.options.context && this.externalModules) {
|
|
589
710
|
context.require = this.externalModules.createRequire(context.__filename);
|
|
711
|
+
}
|
|
590
712
|
return context;
|
|
591
713
|
}
|
|
592
714
|
}
|