@voidzero-dev/vite-plus-test 0.1.8 → 0.1.10
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 +181 -1
- package/dist/@vitest/browser/client/.vite/manifest.json +6 -6
- package/dist/@vitest/browser/client/__vitest__/assets/index-Da0hb3oU.css +1 -0
- package/dist/@vitest/browser/client/__vitest__/assets/index-Di71CKDo.js +63 -0
- package/dist/@vitest/browser/client/__vitest__/favicon.ico +0 -0
- package/dist/@vitest/browser/client/__vitest__/favicon.svg +49 -4
- package/dist/@vitest/browser/client/__vitest__/index.html +2 -2
- package/dist/@vitest/browser/client/__vitest_browser__/{orchestrator-S_3e_uzt.js → orchestrator-CXs6qrFe.js} +70 -28
- package/dist/@vitest/browser/client/__vitest_browser__/{tester-k74mgIRa.js → tester-K5NNxh1O.js} +167 -58
- package/dist/@vitest/browser/client/__vitest_browser__/{utils-uxqdqUz8.js → utils-C2ISqq1C.js} +2 -2
- package/dist/@vitest/browser/client/favicon.svg +49 -4
- package/dist/@vitest/browser/client/orchestrator.html +2 -2
- package/dist/@vitest/browser/client/tester/tester.html +2 -2
- package/dist/@vitest/browser/client.js +20 -13
- package/dist/@vitest/browser/context.d.ts +160 -10
- package/dist/@vitest/browser/context.js +108 -22
- package/dist/@vitest/browser/expect-element.js +23 -28
- package/dist/@vitest/browser/index-5Pe7X7sp.js +7 -0
- package/dist/@vitest/browser/index.d.ts +20 -2
- package/dist/@vitest/browser/index.js +5706 -159
- package/dist/@vitest/browser/locators.d.ts +14 -3
- package/dist/@vitest/browser/locators.js +1 -1
- package/dist/@vitest/browser-playwright/index.d.ts +22 -5
- package/dist/@vitest/browser-playwright/index.js +169 -61
- package/dist/@vitest/browser-preview/index.d.ts +14 -1
- package/dist/@vitest/browser-preview/locators.js +31 -18
- package/dist/@vitest/browser-webdriverio/index.d.ts +17 -3
- package/dist/@vitest/browser-webdriverio/index.js +22 -2
- package/dist/@vitest/browser-webdriverio/locators.js +84 -7
- package/dist/@vitest/expect/index.d.ts +172 -54
- package/dist/@vitest/expect/index.js +124 -67
- package/dist/@vitest/mocker/auto-register.js +1 -0
- package/dist/@vitest/mocker/automock.d.ts +1 -0
- package/dist/@vitest/mocker/automock.js +5 -0
- package/dist/@vitest/mocker/browser.d.ts +4 -4
- package/dist/@vitest/mocker/browser.js +1 -0
- package/dist/@vitest/mocker/chunk-automock.js +182 -14
- package/dist/@vitest/mocker/chunk-helpers.js +44 -0
- package/dist/@vitest/mocker/chunk-hoistMocks.js +659 -0
- package/dist/@vitest/mocker/chunk-mocker.js +41 -30
- package/dist/@vitest/mocker/chunk-registry.js +21 -7
- package/dist/@vitest/mocker/chunk-utils.js +18 -7
- package/dist/@vitest/mocker/hoistMocks.d-w2ILr1dG.d.ts +739 -0
- package/dist/@vitest/mocker/{index.d-C-sLYZi-.d.ts → index.d-B41z0AuW.d.ts} +1 -1
- package/dist/@vitest/mocker/index.d.ts +2 -2
- package/dist/@vitest/mocker/index.js +18 -3
- package/dist/@vitest/mocker/{mocker.d-TnKRhz7N.d.ts → mocker.d-QEntlm6J.d.ts} +10 -5
- package/dist/@vitest/mocker/node.d.ts +5 -734
- package/dist/@vitest/mocker/node.js +29 -587
- package/dist/@vitest/mocker/redirect.js +4 -4
- package/dist/@vitest/mocker/register.d.ts +3 -3
- package/dist/@vitest/mocker/register.js +1 -0
- package/dist/@vitest/mocker/transforms.d.ts +6 -0
- package/dist/@vitest/mocker/transforms.js +8 -0
- package/dist/@vitest/mocker/{types.d-B8CCKmHt.d.ts → types.d-BjI5eAwu.d.ts} +23 -7
- package/dist/@vitest/pretty-format/index.d.ts +11 -1
- package/dist/@vitest/pretty-format/index.js +33 -4
- package/dist/@vitest/runner/chunk-tasks.js +305 -37
- package/dist/@vitest/runner/index.d.ts +5 -6
- package/dist/@vitest/runner/index.js +1146 -455
- package/dist/@vitest/runner/{tasks.d-C7UxawJ9.d.ts → tasks.d-D2GKpdwQ.d.ts} +726 -55
- package/dist/@vitest/runner/types.d.ts +2 -182
- package/dist/@vitest/runner/utils.d.ts +16 -8
- package/dist/@vitest/runner/utils.js +1 -1
- package/dist/@vitest/snapshot/{environment.d-DHdQ1Csl.d.ts → environment.d-DOJxxZV9.d.ts} +2 -7
- package/dist/@vitest/snapshot/environment.d.ts +2 -1
- package/dist/@vitest/snapshot/environment.js +1 -1
- package/dist/@vitest/snapshot/index.d.ts +4 -3
- package/dist/@vitest/snapshot/index.js +21 -550
- package/dist/@vitest/snapshot/manager.d.ts +3 -2
- package/dist/@vitest/snapshot/manager.js +1 -1
- package/dist/@vitest/snapshot/{rawSnapshot.d-lFsMJFUd.d.ts → rawSnapshot.d-U2kJUxDr.d.ts} +1 -1
- package/dist/@vitest/spy/index.d.ts +34 -4
- package/dist/@vitest/spy/index.js +69 -19
- package/dist/@vitest/utils/diff.js +11 -9
- package/dist/@vitest/utils/display.d.ts +2 -1
- package/dist/@vitest/utils/display.js +38 -5
- package/dist/@vitest/utils/error.d.ts +2 -1
- package/dist/@vitest/utils/error.js +1 -2
- package/dist/@vitest/utils/helpers.d.ts +4 -1
- package/dist/@vitest/utils/helpers.js +43 -1
- package/dist/@vitest/utils/resolver.js +1 -2
- package/dist/@vitest/utils/serialize.js +6 -6
- package/dist/@vitest/utils/source-map/node.d.ts +6 -0
- package/dist/@vitest/utils/source-map/node.js +23 -0
- package/dist/@vitest/utils/source-map.js +15 -5
- package/dist/browser.d.ts +3 -2
- package/dist/browser.js +2 -2
- package/dist/chunks/acorn.B2iPLyUM.js +5958 -0
- package/dist/chunks/{base.CJ0Y4ePK.js → base.DM0-RqVb.js} +54 -16
- package/dist/chunks/{benchmark.B3N2zMcH.js → benchmark.D0SlKNbZ.js} +1 -1
- package/dist/chunks/{browser.d.ChKACdzH.d.ts → browser.d.X3SXoOCV.d.ts} +4 -1
- package/dist/chunks/{cac.DVeoLl0M.js → cac.CWGDZnXT.js} +979 -20
- package/dist/chunks/{cli-api.B7PN_QUv.js → cli-api.DuT9iuvY.js} +8764 -7898
- package/dist/chunks/{config.d.Cy95HiCx.d.ts → config.d.EJLVE3es.d.ts} +30 -15
- package/dist/chunks/{console.Cf-YriPC.js → console.3WNpx0tS.js} +3 -2
- package/dist/chunks/{constants.D_Q9UYh-.js → constants.CPYnjOGj.js} +4 -2
- package/dist/chunks/coverage.Bri33R1t.js +1050 -0
- package/dist/chunks/{creator.DAmOKTvJ.js → creator.DgVhQm5q.js} +35 -4
- package/dist/chunks/{defaults.BOqNVLsY.js → defaults.CdU2lD-q.js} +4 -3
- package/dist/chunks/{global.d.B15mdLcR.d.ts → global.d.x-ILCfAE.d.ts} +1 -2
- package/dist/chunks/{globals.DOayXfHP.js → globals.BXNGLnTL.js} +11 -10
- package/dist/chunks/{coverage.AVPTjMgw.js → index.BCY_7LL2.js} +5 -959
- package/dist/chunks/{index.C5r1PdPD.js → index.CEzQDJGb.js} +1 -1
- package/dist/chunks/{index.D3XRDfWc.js → index.CMESou6r.js} +26 -1
- package/dist/chunks/{index.6Qv1eEA6.js → index.DGNSnENe.js} +95 -9
- package/dist/chunks/{index.M8mOzt4Y.js → index.DXMFO5MJ.js} +3279 -2914
- package/dist/chunks/{index.Z5E_ObnR.js → index.DlDSLQD3.js} +7 -3
- package/dist/chunks/{index.CyBMJtT7.js → index.EY6TCHpo.js} +10 -8
- package/dist/chunks/{index.D4KonVSU.js → index.og1WyBLx.js} +18 -3
- package/dist/chunks/{init-forks._y3TW739.js → init-forks.DeArv0jT.js} +1 -1
- package/dist/chunks/{init-threads.DBO2kn-p.js → init-threads.-2OUl4Nn.js} +1 -1
- package/dist/chunks/{init.B6MLFIaN.js → init.DICorXCo.js} +52 -13
- package/dist/chunks/native.DPzPHdi5.js +148 -0
- package/dist/chunks/nativeModuleMocker.DndvSdL6.js +206 -0
- package/dist/chunks/nativeModuleRunner.BIakptoF.js +36 -0
- package/dist/chunks/{node.Ce0vMQM7.js → node.COQbm6gK.js} +1 -1
- package/dist/chunks/{plugin.d.CtqpEehP.d.ts → plugin.d.BuW-flqo.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CWXNI2jG.d.ts → reporters.d.DVUYHHhe.d.ts} +328 -79
- package/dist/chunks/rpc.MzXet3jl.js +144 -0
- package/dist/chunks/{rpc.d.RH3apGEf.d.ts → rpc.d.BFMWpdph.d.ts} +10 -2
- package/dist/chunks/{setup-common.Cm-kSBVi.js → setup-common.B41N_kPE.js} +3 -3
- package/dist/chunks/{startModuleRunner.DEj0jb3e.js → startVitestModuleRunner.C3ZR-4J3.js} +265 -405
- package/dist/chunks/{suite.d.BJWk38HB.d.ts → suite.d.udJtyAgw.d.ts} +1 -1
- package/dist/chunks/{vi.2VT5v0um.js → test.CTcmp4Su.js} +538 -181
- package/dist/chunks/{utils.DvEY5TfP.js → utils.BX5Fg8C4.js} +8 -1
- package/dist/chunks/{vm.D3epNOPZ.js → vm.Dh2rTtmP.js} +48 -8
- package/dist/chunks/{worker.d.Dyxm8DEL.d.ts → worker.d.B84sVRy0.d.ts} +2 -2
- package/dist/cli.js +6 -5
- package/dist/client/.vite/manifest.json +6 -6
- package/dist/client/__vitest__/assets/index-Da0hb3oU.css +1 -0
- package/dist/client/__vitest__/assets/index-Di71CKDo.js +63 -0
- package/dist/client/__vitest__/favicon.ico +0 -0
- package/dist/client/__vitest__/favicon.svg +49 -4
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-S_3e_uzt.js → orchestrator-CXs6qrFe.js} +70 -28
- package/dist/client/__vitest_browser__/{tester-k74mgIRa.js → tester-K5NNxh1O.js} +167 -58
- package/dist/client/__vitest_browser__/{utils-uxqdqUz8.js → utils-C2ISqq1C.js} +2 -2
- package/dist/client/favicon.svg +49 -4
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/tester.html +2 -2
- package/dist/client.js +20 -13
- package/dist/config.cjs +3 -2
- package/dist/config.d.ts +13 -12
- package/dist/config.js +2 -2
- package/dist/context.js +108 -22
- package/dist/coverage.d.ts +12 -8
- package/dist/coverage.js +8 -5
- package/dist/environments.js +3 -1
- package/dist/expect-element.js +23 -23
- package/dist/index-5Pe7X7sp.js +7 -0
- package/dist/index.d.ts +66 -27
- package/dist/index.js +10 -9
- package/dist/locators.d.ts +14 -3
- package/dist/locators.js +1 -1
- package/dist/module-evaluator.d.ts +11 -1
- package/dist/module-evaluator.js +43 -26
- package/dist/node.d.ts +28 -14
- package/dist/node.js +42 -40
- package/dist/nodejs-worker-loader.js +41 -0
- package/dist/plugins/mocker-transforms.mjs +2 -0
- package/dist/plugins/utils-source-map-node.mjs +2 -0
- package/dist/reporters.d.ts +8 -8
- package/dist/reporters.js +7 -5
- package/dist/runners.d.ts +24 -5
- package/dist/runners.js +6 -6
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.js +35 -0
- package/dist/snapshot.js +4 -2
- package/dist/suite.d.ts +1 -1
- package/dist/suite.js +4 -2
- package/dist/vendor/blazediff_core.d.mts +1 -0
- package/dist/vendor/blazediff_core.mjs +117 -0
- package/dist/vendor/chai.mjs +4 -249
- package/dist/vendor/convert-source-map.d.mts +1 -0
- package/dist/vendor/convert-source-map.mjs +150 -0
- package/dist/vendor/expect-type.d.mts +14 -7
- package/dist/vendor/expect-type.mjs +5 -5
- package/dist/vendor/std-env.d.mts +131 -40
- package/dist/vendor/std-env.mjs +114 -117
- package/dist/worker.d.ts +6 -6
- package/dist/worker.js +27 -21
- package/dist/workers/forks.js +23 -17
- package/dist/workers/runVmTests.js +18 -16
- package/dist/workers/threads.js +23 -17
- package/dist/workers/vmForks.js +15 -12
- package/dist/workers/vmThreads.js +15 -12
- package/globals.d.ts +2 -0
- package/package.json +36 -27
- package/suppress-warnings.cjs +1 -0
- package/dist/@vitest/browser/client/__vitest__/assets/index-BUCFJtth.js +0 -57
- package/dist/@vitest/browser/client/__vitest__/assets/index-DlhE0rqZ.css +0 -1
- package/dist/@vitest/browser/index-D6m36C6U.js +0 -11
- package/dist/@vitest/utils/chunk-_commonjsHelpers.js +0 -5
- package/dist/@vitest/utils/highlight.d.ts +0 -9
- package/dist/@vitest/utils/highlight.js +0 -538
- package/dist/chunks/date.Bq6ZW5rf.js +0 -73
- package/dist/chunks/rpc.BoxB0q7B.js +0 -76
- package/dist/chunks/test.B8ej_ZHS.js +0 -254
- package/dist/client/__vitest__/assets/index-BUCFJtth.js +0 -57
- package/dist/client/__vitest__/assets/index-DlhE0rqZ.css +0 -1
- package/dist/index-D6m36C6U.js +0 -6
- package/dist/mocker.d.ts +0 -1
- package/dist/mocker.js +0 -1
- package/dist/module-runner.js +0 -17
|
@@ -1,249 +1,29 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { isBareImport } from '../@vitest/utils/helpers.js';
|
|
3
3
|
import { i as isBuiltin, a as isBrowserExternal, t as toBuiltin } from './modules.BJuCwlRJ.js';
|
|
4
|
+
import { E as EnvironmentTeardownError, a as getSafeWorkerState } from './utils.BX5Fg8C4.js';
|
|
4
5
|
import { pathToFileURL } from 'node:url';
|
|
5
|
-
import { normalize
|
|
6
|
+
import { normalize, join } from '../vendor/pathe.mjs';
|
|
6
7
|
import { distDir } from '../path.js';
|
|
7
|
-
import { serializeValue } from '../@vitest/utils/serialize.js';
|
|
8
8
|
import { VitestModuleEvaluator, unwrapId } from '../module-evaluator.js';
|
|
9
|
-
import {
|
|
9
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
10
10
|
import vm from 'node:vm';
|
|
11
11
|
import { MockerRegistry, mockObject, RedirectedModule, AutomockedModule } from '../@vitest/mocker/index.js';
|
|
12
|
-
import
|
|
12
|
+
import { findMockRedirect } from '../@vitest/mocker/redirect.js';
|
|
13
13
|
import * as viteModuleRunner from '@voidzero-dev/vite-plus-core/module-runner';
|
|
14
14
|
import { T as Traces } from './traces.CCmnQaNT.js';
|
|
15
15
|
|
|
16
|
-
class
|
|
17
|
-
constructor(options) {
|
|
18
|
-
this.options = options;
|
|
19
|
-
}
|
|
20
|
-
async invoke(event) {
|
|
21
|
-
if (event.type !== "custom") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support Vite HMR events.`) };
|
|
22
|
-
if (event.event !== "vite:invoke") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support ${event.event} event.`) };
|
|
23
|
-
const { name, data } = event.data;
|
|
24
|
-
if (name === "getBuiltins")
|
|
25
|
-
// we return an empty array here to avoid client-side builtin check,
|
|
26
|
-
// as we need builtins to go through `fetchModule`
|
|
27
|
-
return { result: [] };
|
|
28
|
-
if (name !== "fetchModule") return { error: /* @__PURE__ */ new Error(`Unknown method: ${name}. Expected "fetchModule".`) };
|
|
29
|
-
try {
|
|
30
|
-
return { result: await this.options.fetchModule(...data) };
|
|
31
|
-
} catch (error) {
|
|
32
|
-
return { error };
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
38
|
-
function normalizeWindowsPath(input = "") {
|
|
39
|
-
if (!input) return input;
|
|
40
|
-
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
41
|
-
}
|
|
42
|
-
const _UNC_REGEX = /^[/\\]{2}/;
|
|
43
|
-
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
44
|
-
const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
45
|
-
const _EXTNAME_RE = /.(\.[^./]+|\.)$/;
|
|
46
|
-
const normalize = function(path) {
|
|
47
|
-
if (path.length === 0) return ".";
|
|
48
|
-
path = normalizeWindowsPath(path);
|
|
49
|
-
const isUNCPath = path.match(_UNC_REGEX);
|
|
50
|
-
const isPathAbsolute = isAbsolute(path);
|
|
51
|
-
const trailingSeparator = path[path.length - 1] === "/";
|
|
52
|
-
path = normalizeString(path, !isPathAbsolute);
|
|
53
|
-
if (path.length === 0) {
|
|
54
|
-
if (isPathAbsolute) return "/";
|
|
55
|
-
return trailingSeparator ? "./" : ".";
|
|
56
|
-
}
|
|
57
|
-
if (trailingSeparator) path += "/";
|
|
58
|
-
if (_DRIVE_LETTER_RE.test(path)) path += "/";
|
|
59
|
-
if (isUNCPath) {
|
|
60
|
-
if (!isPathAbsolute) return `//./${path}`;
|
|
61
|
-
return `//${path}`;
|
|
62
|
-
}
|
|
63
|
-
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
|
|
64
|
-
};
|
|
65
|
-
const join = function(...segments) {
|
|
66
|
-
let path = "";
|
|
67
|
-
for (const seg of segments) {
|
|
68
|
-
if (!seg) continue;
|
|
69
|
-
if (path.length > 0) {
|
|
70
|
-
const pathTrailing = path[path.length - 1] === "/";
|
|
71
|
-
const segLeading = seg[0] === "/";
|
|
72
|
-
if (pathTrailing && segLeading) path += seg.slice(1);
|
|
73
|
-
else path += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
74
|
-
} else path += seg;
|
|
75
|
-
}
|
|
76
|
-
return normalize(path);
|
|
77
|
-
};
|
|
78
|
-
function cwd$1() {
|
|
79
|
-
if (typeof process !== "undefined" && typeof process.cwd === "function") return process.cwd().replace(/\\/g, "/");
|
|
80
|
-
return "/";
|
|
81
|
-
}
|
|
82
|
-
const resolve = function(...arguments_) {
|
|
83
|
-
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
84
|
-
let resolvedPath = "";
|
|
85
|
-
let resolvedAbsolute = false;
|
|
86
|
-
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
87
|
-
const path = index >= 0 ? arguments_[index] : cwd$1();
|
|
88
|
-
if (!path || path.length === 0) continue;
|
|
89
|
-
resolvedPath = `${path}/${resolvedPath}`;
|
|
90
|
-
resolvedAbsolute = isAbsolute(path);
|
|
91
|
-
}
|
|
92
|
-
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
93
|
-
if (resolvedAbsolute && !isAbsolute(resolvedPath)) return `/${resolvedPath}`;
|
|
94
|
-
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
95
|
-
};
|
|
96
|
-
function normalizeString(path, allowAboveRoot) {
|
|
97
|
-
let res = "";
|
|
98
|
-
let lastSegmentLength = 0;
|
|
99
|
-
let lastSlash = -1;
|
|
100
|
-
let dots = 0;
|
|
101
|
-
let char = null;
|
|
102
|
-
for (let index = 0; index <= path.length; ++index) {
|
|
103
|
-
if (index < path.length) char = path[index];
|
|
104
|
-
else if (char === "/") break;
|
|
105
|
-
else char = "/";
|
|
106
|
-
if (char === "/") {
|
|
107
|
-
if (lastSlash === index - 1 || dots === 1);
|
|
108
|
-
else if (dots === 2) {
|
|
109
|
-
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
110
|
-
if (res.length > 2) {
|
|
111
|
-
const lastSlashIndex = res.lastIndexOf("/");
|
|
112
|
-
if (lastSlashIndex === -1) {
|
|
113
|
-
res = "";
|
|
114
|
-
lastSegmentLength = 0;
|
|
115
|
-
} else {
|
|
116
|
-
res = res.slice(0, lastSlashIndex);
|
|
117
|
-
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
118
|
-
}
|
|
119
|
-
lastSlash = index;
|
|
120
|
-
dots = 0;
|
|
121
|
-
continue;
|
|
122
|
-
} else if (res.length > 0) {
|
|
123
|
-
res = "";
|
|
124
|
-
lastSegmentLength = 0;
|
|
125
|
-
lastSlash = index;
|
|
126
|
-
dots = 0;
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (allowAboveRoot) {
|
|
131
|
-
res += res.length > 0 ? "/.." : "..";
|
|
132
|
-
lastSegmentLength = 2;
|
|
133
|
-
}
|
|
134
|
-
} else {
|
|
135
|
-
if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`;
|
|
136
|
-
else res = path.slice(lastSlash + 1, index);
|
|
137
|
-
lastSegmentLength = index - lastSlash - 1;
|
|
138
|
-
}
|
|
139
|
-
lastSlash = index;
|
|
140
|
-
dots = 0;
|
|
141
|
-
} else if (char === "." && dots !== -1) ++dots;
|
|
142
|
-
else dots = -1;
|
|
143
|
-
}
|
|
144
|
-
return res;
|
|
145
|
-
}
|
|
146
|
-
const isAbsolute = function(p) {
|
|
147
|
-
return _IS_ABSOLUTE_RE.test(p);
|
|
148
|
-
};
|
|
149
|
-
const extname = function(p) {
|
|
150
|
-
if (p === "..") return "";
|
|
151
|
-
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
|
|
152
|
-
return match && match[1] || "";
|
|
153
|
-
};
|
|
154
|
-
const dirname = function(p) {
|
|
155
|
-
const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
|
|
156
|
-
if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) segments[0] += "/";
|
|
157
|
-
return segments.join("/") || (isAbsolute(p) ? "/" : ".");
|
|
158
|
-
};
|
|
159
|
-
const basename = function(p, extension) {
|
|
160
|
-
const segments = normalizeWindowsPath(p).split("/");
|
|
161
|
-
let lastSegment = "";
|
|
162
|
-
for (let i = segments.length - 1; i >= 0; i--) {
|
|
163
|
-
const val = segments[i];
|
|
164
|
-
if (val) {
|
|
165
|
-
lastSegment = val;
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const { existsSync, readdirSync, statSync } = fs;
|
|
173
|
-
function findMockRedirect(root, mockPath, external) {
|
|
174
|
-
const path = external || mockPath;
|
|
175
|
-
// it's a node_module alias
|
|
176
|
-
// all mocks should be inside <root>/__mocks__
|
|
177
|
-
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
|
|
178
|
-
const mockFolder = join(root, "__mocks__", dirname(path));
|
|
179
|
-
if (!existsSync(mockFolder)) return null;
|
|
180
|
-
const baseOriginal = basename(path);
|
|
181
|
-
function findFile(mockFolder, baseOriginal) {
|
|
182
|
-
const files = readdirSync(mockFolder);
|
|
183
|
-
for (const file of files) if (basename(file, extname(file)) === baseOriginal) {
|
|
184
|
-
const path = resolve(mockFolder, file);
|
|
185
|
-
// if the same name, return the file
|
|
186
|
-
if (statSync(path).isFile()) return path;
|
|
187
|
-
else {
|
|
188
|
-
// find folder/index.{js,ts}
|
|
189
|
-
const indexFile = findFile(path, "index");
|
|
190
|
-
if (indexFile) return indexFile;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
return findFile(mockFolder, baseOriginal);
|
|
196
|
-
}
|
|
197
|
-
const fullPath = resolve(dirname(path), "__mocks__", basename(path));
|
|
198
|
-
return existsSync(fullPath) ? fullPath : null;
|
|
199
|
-
}
|
|
200
|
-
const builtins = new Set([
|
|
201
|
-
...nodeModule.builtinModules,
|
|
202
|
-
"assert/strict",
|
|
203
|
-
"diagnostics_channel",
|
|
204
|
-
"dns/promises",
|
|
205
|
-
"fs/promises",
|
|
206
|
-
"path/posix",
|
|
207
|
-
"path/win32",
|
|
208
|
-
"readline/promises",
|
|
209
|
-
"stream/consumers",
|
|
210
|
-
"stream/promises",
|
|
211
|
-
"stream/web",
|
|
212
|
-
"timers/promises",
|
|
213
|
-
"util/types",
|
|
214
|
-
"wasi"
|
|
215
|
-
]);
|
|
216
|
-
// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix
|
|
217
|
-
const prefixedBuiltins$1 = new Set([
|
|
218
|
-
"node:sea",
|
|
219
|
-
"node:sqlite",
|
|
220
|
-
"node:test",
|
|
221
|
-
"node:test/reporters"
|
|
222
|
-
]);
|
|
223
|
-
const NODE_BUILTIN_NAMESPACE = "node:";
|
|
224
|
-
function isNodeBuiltin(id) {
|
|
225
|
-
// Added in v18.6.0
|
|
226
|
-
if (nodeModule.isBuiltin) return nodeModule.isBuiltin(id);
|
|
227
|
-
if (prefixedBuiltins$1.has(id)) return true;
|
|
228
|
-
return builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(5) : id);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const spyModulePath = resolve$1(distDir, "spy.js");
|
|
232
|
-
class VitestMocker {
|
|
16
|
+
class BareModuleMocker {
|
|
233
17
|
static pendingIds = [];
|
|
234
18
|
spyModule;
|
|
235
19
|
primitives;
|
|
236
|
-
filterPublicKeys;
|
|
237
20
|
registries = /* @__PURE__ */ new Map();
|
|
238
21
|
mockContext = { callstack: null };
|
|
239
22
|
_otel;
|
|
240
|
-
constructor(
|
|
241
|
-
this.moduleRunner = moduleRunner;
|
|
23
|
+
constructor(options) {
|
|
242
24
|
this.options = options;
|
|
243
|
-
const context = this.options.context;
|
|
244
25
|
this._otel = options.traces;
|
|
245
|
-
|
|
246
|
-
else this.primitives = {
|
|
26
|
+
this.primitives = {
|
|
247
27
|
Object,
|
|
248
28
|
Error,
|
|
249
29
|
Function,
|
|
@@ -253,37 +33,13 @@ class VitestMocker {
|
|
|
253
33
|
Map
|
|
254
34
|
};
|
|
255
35
|
if (options.spyModule) this.spyModule = options.spyModule;
|
|
256
|
-
const Symbol = this.primitives.Symbol;
|
|
257
|
-
this.filterPublicKeys = [
|
|
258
|
-
"__esModule",
|
|
259
|
-
Symbol.asyncIterator,
|
|
260
|
-
Symbol.hasInstance,
|
|
261
|
-
Symbol.isConcatSpreadable,
|
|
262
|
-
Symbol.iterator,
|
|
263
|
-
Symbol.match,
|
|
264
|
-
Symbol.matchAll,
|
|
265
|
-
Symbol.replace,
|
|
266
|
-
Symbol.search,
|
|
267
|
-
Symbol.split,
|
|
268
|
-
Symbol.species,
|
|
269
|
-
Symbol.toPrimitive,
|
|
270
|
-
Symbol.toStringTag,
|
|
271
|
-
Symbol.unscopables
|
|
272
|
-
];
|
|
273
36
|
}
|
|
274
37
|
get root() {
|
|
275
38
|
return this.options.root;
|
|
276
39
|
}
|
|
277
|
-
get evaluatedModules() {
|
|
278
|
-
return this.moduleRunner.evaluatedModules;
|
|
279
|
-
}
|
|
280
40
|
get moduleDirectories() {
|
|
281
41
|
return this.options.moduleDirectories || [];
|
|
282
42
|
}
|
|
283
|
-
async initializeSpyModule() {
|
|
284
|
-
if (this.spyModule) return;
|
|
285
|
-
this.spyModule = await this.moduleRunner.import(spyModulePath);
|
|
286
|
-
}
|
|
287
43
|
getMockerRegistry() {
|
|
288
44
|
const suite = this.getSuiteFilepath();
|
|
289
45
|
if (!this.registries.has(suite)) this.registries.set(suite, new MockerRegistry());
|
|
@@ -292,13 +48,8 @@ class VitestMocker {
|
|
|
292
48
|
reset() {
|
|
293
49
|
this.registries.clear();
|
|
294
50
|
}
|
|
295
|
-
invalidateModuleById(
|
|
296
|
-
|
|
297
|
-
const node = this.evaluatedModules.getModuleById(mockId);
|
|
298
|
-
if (node) {
|
|
299
|
-
this.evaluatedModules.invalidateModule(node);
|
|
300
|
-
node.mockedExports = void 0;
|
|
301
|
-
}
|
|
51
|
+
invalidateModuleById(_id) {
|
|
52
|
+
// implemented by mockers that control the module runner
|
|
302
53
|
}
|
|
303
54
|
isModuleDirectory(path) {
|
|
304
55
|
return this.moduleDirectories.some((dir) => path.includes(dir));
|
|
@@ -335,7 +86,7 @@ class VitestMocker {
|
|
|
335
86
|
}
|
|
336
87
|
// external is node_module or unresolved module
|
|
337
88
|
// for example, some people mock "vscode" and don't have it installed
|
|
338
|
-
const external = !isAbsolute
|
|
89
|
+
const external = !isAbsolute(result.file) || this.isModuleDirectory(result.file) ? normalizeModuleId(rawId) : null;
|
|
339
90
|
const id = normalizeModuleId(result.id);
|
|
340
91
|
span.setAttributes({
|
|
341
92
|
"vitest.module.id": id,
|
|
@@ -350,13 +101,188 @@ class VitestMocker {
|
|
|
350
101
|
});
|
|
351
102
|
}
|
|
352
103
|
async resolveMocks() {
|
|
353
|
-
if (!
|
|
354
|
-
await Promise.all(
|
|
104
|
+
if (!BareModuleMocker.pendingIds.length) return;
|
|
105
|
+
await Promise.all(BareModuleMocker.pendingIds.map(async (mock) => {
|
|
355
106
|
const { id, url, external } = await this.resolveId(mock.id, mock.importer);
|
|
356
107
|
if (mock.action === "unmock") this.unmockPath(id);
|
|
357
108
|
if (mock.action === "mock") this.mockPath(mock.id, id, url, external, mock.type, mock.factory);
|
|
358
109
|
}));
|
|
359
|
-
|
|
110
|
+
BareModuleMocker.pendingIds = [];
|
|
111
|
+
}
|
|
112
|
+
// public method to avoid circular dependency
|
|
113
|
+
getMockContext() {
|
|
114
|
+
return this.mockContext;
|
|
115
|
+
}
|
|
116
|
+
// path used to store mocked dependencies
|
|
117
|
+
getMockPath(dep) {
|
|
118
|
+
return `mock:${dep}`;
|
|
119
|
+
}
|
|
120
|
+
getDependencyMock(id) {
|
|
121
|
+
return this.getMockerRegistry().getById(fixLeadingSlashes(id));
|
|
122
|
+
}
|
|
123
|
+
getDependencyMockByUrl(url) {
|
|
124
|
+
return this.getMockerRegistry().get(url);
|
|
125
|
+
}
|
|
126
|
+
findMockRedirect(mockPath, external) {
|
|
127
|
+
return findMockRedirect(this.root, mockPath, external);
|
|
128
|
+
}
|
|
129
|
+
mockObject(object, mockExportsOrModuleType, moduleType) {
|
|
130
|
+
let mockExports;
|
|
131
|
+
if (mockExportsOrModuleType === "automock" || mockExportsOrModuleType === "autospy") {
|
|
132
|
+
moduleType = mockExportsOrModuleType;
|
|
133
|
+
mockExports = void 0;
|
|
134
|
+
} else mockExports = mockExportsOrModuleType;
|
|
135
|
+
moduleType ??= "automock";
|
|
136
|
+
const createMockInstance = this.spyModule?.createMockInstance;
|
|
137
|
+
if (!createMockInstance) throw this.createError("[vitest] `spyModule` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
|
|
138
|
+
return mockObject({
|
|
139
|
+
globalConstructors: this.primitives,
|
|
140
|
+
createMockInstance,
|
|
141
|
+
type: moduleType
|
|
142
|
+
}, object, mockExports);
|
|
143
|
+
}
|
|
144
|
+
unmockPath(id) {
|
|
145
|
+
this.getMockerRegistry().deleteById(id);
|
|
146
|
+
this.invalidateModuleById(id);
|
|
147
|
+
}
|
|
148
|
+
mockPath(originalId, id, url, external, mockType, factory) {
|
|
149
|
+
const registry = this.getMockerRegistry();
|
|
150
|
+
if (mockType === "manual") registry.register("manual", originalId, id, url, factory);
|
|
151
|
+
else if (mockType === "autospy") registry.register("autospy", originalId, id, url);
|
|
152
|
+
else {
|
|
153
|
+
const redirect = this.findMockRedirect(id, external);
|
|
154
|
+
if (redirect) registry.register("redirect", originalId, id, url, redirect);
|
|
155
|
+
else registry.register("automock", originalId, id, url);
|
|
156
|
+
}
|
|
157
|
+
// every time the mock is registered, we remove the previous one from the cache
|
|
158
|
+
this.invalidateModuleById(id);
|
|
159
|
+
}
|
|
160
|
+
async importActual(_rawId, _importer, _callstack) {
|
|
161
|
+
throw new Error(`importActual is not implemented`);
|
|
162
|
+
}
|
|
163
|
+
async importMock(_rawId, _importer, _callstack) {
|
|
164
|
+
throw new Error(`importMock is not implemented`);
|
|
165
|
+
}
|
|
166
|
+
queueMock(id, importer, factoryOrOptions) {
|
|
167
|
+
const mockType = getMockType(factoryOrOptions);
|
|
168
|
+
BareModuleMocker.pendingIds.push({
|
|
169
|
+
action: "mock",
|
|
170
|
+
id,
|
|
171
|
+
importer,
|
|
172
|
+
factory: typeof factoryOrOptions === "function" ? factoryOrOptions : void 0,
|
|
173
|
+
type: mockType
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
queueUnmock(id, importer) {
|
|
177
|
+
BareModuleMocker.pendingIds.push({
|
|
178
|
+
action: "unmock",
|
|
179
|
+
id,
|
|
180
|
+
importer
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function getMockType(factoryOrOptions) {
|
|
185
|
+
if (!factoryOrOptions) return "automock";
|
|
186
|
+
if (typeof factoryOrOptions === "function") return "manual";
|
|
187
|
+
return factoryOrOptions.spy ? "autospy" : "automock";
|
|
188
|
+
}
|
|
189
|
+
// unique id that is not available as "$bare_import" like "test"
|
|
190
|
+
// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix
|
|
191
|
+
const prefixedBuiltins = new Set([
|
|
192
|
+
"node:sea",
|
|
193
|
+
"node:sqlite",
|
|
194
|
+
"node:test",
|
|
195
|
+
"node:test/reporters"
|
|
196
|
+
]);
|
|
197
|
+
const isWindows$1 = process.platform === "win32";
|
|
198
|
+
// transform file url to id
|
|
199
|
+
// virtual:custom -> virtual:custom
|
|
200
|
+
// \0custom -> \0custom
|
|
201
|
+
// /root/id -> /id
|
|
202
|
+
// /root/id.js -> /id.js
|
|
203
|
+
// C:/root/id.js -> /id.js
|
|
204
|
+
// C:\root\id.js -> /id.js
|
|
205
|
+
// TODO: expose this in vite/module-runner
|
|
206
|
+
function normalizeModuleId(file) {
|
|
207
|
+
if (prefixedBuiltins.has(file)) return file;
|
|
208
|
+
// if it's not in the root, keep it as a path, not a URL
|
|
209
|
+
return slash(file).replace(/^\/@fs\//, isWindows$1 ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/").replace(/^file:\//, "/");
|
|
210
|
+
}
|
|
211
|
+
const windowsSlashRE = /\\/g;
|
|
212
|
+
function slash(p) {
|
|
213
|
+
return p.replace(windowsSlashRE, "/");
|
|
214
|
+
}
|
|
215
|
+
const multipleSlashRe = /^\/+/;
|
|
216
|
+
// module-runner incorrectly replaces file:///path with `///path`
|
|
217
|
+
function fixLeadingSlashes(id) {
|
|
218
|
+
if (id.startsWith("//")) return id.replace(multipleSlashRe, "/");
|
|
219
|
+
return id;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// copied from vite/src/shared/utils.ts
|
|
223
|
+
const postfixRE = /[?#].*$/;
|
|
224
|
+
function cleanUrl(url) {
|
|
225
|
+
return url.replace(postfixRE, "");
|
|
226
|
+
}
|
|
227
|
+
function splitFileAndPostfix(path) {
|
|
228
|
+
const file = cleanUrl(path);
|
|
229
|
+
return {
|
|
230
|
+
file,
|
|
231
|
+
postfix: path.slice(file.length)
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function injectQuery(url, queryToInject) {
|
|
235
|
+
const { file, postfix } = splitFileAndPostfix(url);
|
|
236
|
+
return `${file}?${queryToInject}${postfix[0] === "?" ? `&${postfix.slice(1)}` : postfix}`;
|
|
237
|
+
}
|
|
238
|
+
function removeQuery(url, queryToRemove) {
|
|
239
|
+
return url.replace(new RegExp(`[?&]${queryToRemove}(?=[&#]|$)`), "").replace(/\?$/, "");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const spyModulePath = resolve(distDir, "spy.js");
|
|
243
|
+
class VitestMocker extends BareModuleMocker {
|
|
244
|
+
filterPublicKeys;
|
|
245
|
+
constructor(moduleRunner, options) {
|
|
246
|
+
super(options);
|
|
247
|
+
this.moduleRunner = moduleRunner;
|
|
248
|
+
this.options = options;
|
|
249
|
+
const context = this.options.context;
|
|
250
|
+
if (context) this.primitives = vm.runInContext("({ Object, Error, Function, RegExp, Symbol, Array, Map })", context);
|
|
251
|
+
const Symbol = this.primitives.Symbol;
|
|
252
|
+
this.filterPublicKeys = [
|
|
253
|
+
"__esModule",
|
|
254
|
+
Symbol.asyncIterator,
|
|
255
|
+
Symbol.hasInstance,
|
|
256
|
+
Symbol.isConcatSpreadable,
|
|
257
|
+
Symbol.iterator,
|
|
258
|
+
Symbol.match,
|
|
259
|
+
Symbol.matchAll,
|
|
260
|
+
Symbol.replace,
|
|
261
|
+
Symbol.search,
|
|
262
|
+
Symbol.split,
|
|
263
|
+
Symbol.species,
|
|
264
|
+
Symbol.toPrimitive,
|
|
265
|
+
Symbol.toStringTag,
|
|
266
|
+
Symbol.unscopables
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
get evaluatedModules() {
|
|
270
|
+
return this.moduleRunner.evaluatedModules;
|
|
271
|
+
}
|
|
272
|
+
async initializeSpyModule() {
|
|
273
|
+
if (this.spyModule) return;
|
|
274
|
+
this.spyModule = await this.moduleRunner.import(spyModulePath);
|
|
275
|
+
}
|
|
276
|
+
reset() {
|
|
277
|
+
this.registries.clear();
|
|
278
|
+
}
|
|
279
|
+
invalidateModuleById(id) {
|
|
280
|
+
const mockId = this.getMockPath(id);
|
|
281
|
+
const node = this.evaluatedModules.getModuleById(mockId);
|
|
282
|
+
if (node) {
|
|
283
|
+
this.evaluatedModules.invalidateModule(node);
|
|
284
|
+
node.mockedExports = void 0;
|
|
285
|
+
}
|
|
360
286
|
}
|
|
361
287
|
ensureModule(id, url) {
|
|
362
288
|
const node = this.evaluatedModules.ensureModule(id, url);
|
|
@@ -396,48 +322,10 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
396
322
|
node.exports = moduleExports;
|
|
397
323
|
return moduleExports;
|
|
398
324
|
}
|
|
399
|
-
// public method to avoid circular dependency
|
|
400
|
-
getMockContext() {
|
|
401
|
-
return this.mockContext;
|
|
402
|
-
}
|
|
403
|
-
// path used to store mocked dependencies
|
|
404
|
-
getMockPath(dep) {
|
|
405
|
-
return `mock:${dep}`;
|
|
406
|
-
}
|
|
407
|
-
getDependencyMock(id) {
|
|
408
|
-
return this.getMockerRegistry().getById(fixLeadingSlashes(id));
|
|
409
|
-
}
|
|
410
|
-
findMockRedirect(mockPath, external) {
|
|
411
|
-
return findMockRedirect(this.root, mockPath, external);
|
|
412
|
-
}
|
|
413
|
-
mockObject(object, mockExports = {}, behavior = "automock") {
|
|
414
|
-
const createMockInstance = this.spyModule?.createMockInstance;
|
|
415
|
-
if (!createMockInstance) throw this.createError("[vitest] `spyModule` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
|
|
416
|
-
return mockObject({
|
|
417
|
-
globalConstructors: this.primitives,
|
|
418
|
-
createMockInstance,
|
|
419
|
-
type: behavior
|
|
420
|
-
}, object, mockExports);
|
|
421
|
-
}
|
|
422
|
-
unmockPath(id) {
|
|
423
|
-
this.getMockerRegistry().deleteById(id);
|
|
424
|
-
this.invalidateModuleById(id);
|
|
425
|
-
}
|
|
426
|
-
mockPath(originalId, id, url, external, mockType, factory) {
|
|
427
|
-
const registry = this.getMockerRegistry();
|
|
428
|
-
if (mockType === "manual") registry.register("manual", originalId, id, url, factory);
|
|
429
|
-
else if (mockType === "autospy") registry.register("autospy", originalId, id, url);
|
|
430
|
-
else {
|
|
431
|
-
const redirect = this.findMockRedirect(id, external);
|
|
432
|
-
if (redirect) registry.register("redirect", originalId, id, url, redirect);
|
|
433
|
-
else registry.register("automock", originalId, id, url);
|
|
434
|
-
}
|
|
435
|
-
// every time the mock is registered, we remove the previous one from the cache
|
|
436
|
-
this.invalidateModuleById(id);
|
|
437
|
-
}
|
|
438
325
|
async importActual(rawId, importer, callstack) {
|
|
439
326
|
const { url } = await this.resolveId(rawId, importer);
|
|
440
|
-
const
|
|
327
|
+
const actualUrl = injectQuery(url, "_vitest_original");
|
|
328
|
+
const node = await this.moduleRunner.fetchModule(actualUrl, importer);
|
|
441
329
|
return await this.moduleRunner.cachedRequest(node.url, node, callstack || [importer], void 0, true);
|
|
442
330
|
}
|
|
443
331
|
async importMock(rawId, importer) {
|
|
@@ -511,61 +399,44 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
511
399
|
if (!mock) return;
|
|
512
400
|
return this.requestWithMockedModule(url, evaluatedNode, callstack, mock);
|
|
513
401
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
type: mockType
|
|
522
|
-
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
class VitestTransport {
|
|
405
|
+
constructor(options, evaluatedModules, callstacks) {
|
|
406
|
+
this.options = options;
|
|
407
|
+
this.evaluatedModules = evaluatedModules;
|
|
408
|
+
this.callstacks = callstacks;
|
|
523
409
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
410
|
+
async invoke(event) {
|
|
411
|
+
if (event.type !== "custom") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support Vite HMR events.`) };
|
|
412
|
+
if (event.event !== "vite:invoke") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support ${event.event} event.`) };
|
|
413
|
+
const { name, data } = event.data;
|
|
414
|
+
if (name === "getBuiltins")
|
|
415
|
+
// we return an empty array here to avoid client-side builtin check,
|
|
416
|
+
// as we need builtins to go through `fetchModule`
|
|
417
|
+
return { result: [] };
|
|
418
|
+
if (name !== "fetchModule") return { error: /* @__PURE__ */ new Error(`Unknown method: ${name}. Expected "fetchModule".`) };
|
|
419
|
+
try {
|
|
420
|
+
return { result: await this.options.fetchModule(...data) };
|
|
421
|
+
} catch (cause) {
|
|
422
|
+
if (cause instanceof EnvironmentTeardownError) {
|
|
423
|
+
const [id, importer] = data;
|
|
424
|
+
let message = `Cannot load '${id}'${importer ? ` imported from ${importer}` : ""} after the environment was torn down. This is not a bug in Vitest.`;
|
|
425
|
+
const moduleNode = importer ? this.evaluatedModules.getModuleById(importer) : void 0;
|
|
426
|
+
const callstack = moduleNode ? this.callstacks.get(moduleNode) : void 0;
|
|
427
|
+
if (callstack) message += ` The last recorded callstack:\n- ${[
|
|
428
|
+
...callstack,
|
|
429
|
+
importer,
|
|
430
|
+
id
|
|
431
|
+
].reverse().join("\n- ")}`;
|
|
432
|
+
const error = new EnvironmentTeardownError(message);
|
|
433
|
+
if (cause.stack) error.stack = cause.stack.replace(cause.message, error.message);
|
|
434
|
+
return { error };
|
|
435
|
+
}
|
|
436
|
+
return { error: cause };
|
|
437
|
+
}
|
|
530
438
|
}
|
|
531
439
|
}
|
|
532
|
-
function getMockType(factoryOrOptions) {
|
|
533
|
-
if (!factoryOrOptions) return "automock";
|
|
534
|
-
if (typeof factoryOrOptions === "function") return "manual";
|
|
535
|
-
return factoryOrOptions.spy ? "autospy" : "automock";
|
|
536
|
-
}
|
|
537
|
-
// unique id that is not available as "$bare_import" like "test"
|
|
538
|
-
// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix
|
|
539
|
-
const prefixedBuiltins = new Set([
|
|
540
|
-
"node:sea",
|
|
541
|
-
"node:sqlite",
|
|
542
|
-
"node:test",
|
|
543
|
-
"node:test/reporters"
|
|
544
|
-
]);
|
|
545
|
-
const isWindows$1 = process.platform === "win32";
|
|
546
|
-
// transform file url to id
|
|
547
|
-
// virtual:custom -> virtual:custom
|
|
548
|
-
// \0custom -> \0custom
|
|
549
|
-
// /root/id -> /id
|
|
550
|
-
// /root/id.js -> /id.js
|
|
551
|
-
// C:/root/id.js -> /id.js
|
|
552
|
-
// C:\root\id.js -> /id.js
|
|
553
|
-
// TODO: expose this in vite/module-runner
|
|
554
|
-
function normalizeModuleId(file) {
|
|
555
|
-
if (prefixedBuiltins.has(file)) return file;
|
|
556
|
-
// if it's not in the root, keep it as a path, not a URL
|
|
557
|
-
return slash(file).replace(/^\/@fs\//, isWindows$1 ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/").replace(/^file:\//, "/");
|
|
558
|
-
}
|
|
559
|
-
const windowsSlashRE = /\\/g;
|
|
560
|
-
function slash(p) {
|
|
561
|
-
return p.replace(windowsSlashRE, "/");
|
|
562
|
-
}
|
|
563
|
-
const multipleSlashRe = /^\/+/;
|
|
564
|
-
// module-runner incorrectly replaces file:///path with `///path`
|
|
565
|
-
function fixLeadingSlashes(id) {
|
|
566
|
-
if (id.startsWith("//")) return id.replace(multipleSlashRe, "/");
|
|
567
|
-
return id;
|
|
568
|
-
}
|
|
569
440
|
|
|
570
441
|
const createNodeImportMeta = (modulePath) => {
|
|
571
442
|
if (!viteModuleRunner.createDefaultImportMeta) throw new Error(`createNodeImportMeta is not supported in this version of Vite.`);
|
|
@@ -589,10 +460,12 @@ class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
|
|
|
589
460
|
mocker;
|
|
590
461
|
moduleExecutionInfo;
|
|
591
462
|
_otel;
|
|
463
|
+
_callstacks;
|
|
592
464
|
constructor(vitestOptions) {
|
|
593
465
|
const options = vitestOptions;
|
|
594
|
-
const transport = new VitestTransport(options.transport);
|
|
595
466
|
const evaluatedModules = options.evaluatedModules;
|
|
467
|
+
const callstacks = /* @__PURE__ */ new WeakMap();
|
|
468
|
+
const transport = new VitestTransport(options.transport, evaluatedModules, callstacks);
|
|
596
469
|
super({
|
|
597
470
|
transport,
|
|
598
471
|
hmr: false,
|
|
@@ -601,6 +474,7 @@ class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
|
|
|
601
474
|
createImportMeta: vitestOptions.createImportMeta
|
|
602
475
|
}, options.evaluator);
|
|
603
476
|
this.vitestOptions = vitestOptions;
|
|
477
|
+
this._callstacks = callstacks;
|
|
604
478
|
this._otel = vitestOptions.traces || new Traces({ enabled: false });
|
|
605
479
|
this.moduleExecutionInfo = options.getWorkerState().moduleExecutionInfo;
|
|
606
480
|
this.mocker = options.mocker || new VitestMocker(this, {
|
|
@@ -658,10 +532,24 @@ class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
|
|
|
658
532
|
* @internal
|
|
659
533
|
*/
|
|
660
534
|
async cachedRequest(url, mod, callstack = [], metadata, ignoreMock = false) {
|
|
535
|
+
// Track for a better error message if dynamic import is not resolved properly
|
|
536
|
+
this._callstacks.set(mod, callstack);
|
|
661
537
|
if (ignoreMock) return this._cachedRequest(url, mod, callstack, metadata);
|
|
662
538
|
let mocked;
|
|
663
|
-
if (mod.meta && "mockedModule" in mod.meta)
|
|
664
|
-
|
|
539
|
+
if (mod.meta && "mockedModule" in mod.meta) {
|
|
540
|
+
const mockedModule = mod.meta.mockedModule;
|
|
541
|
+
const mockId = this.mocker.getMockPath(mod.id);
|
|
542
|
+
// bypass mock and force "importActual" behavior when:
|
|
543
|
+
// - mock was removed by doUnmock (stale mockedModule in meta)
|
|
544
|
+
// - self-import: mock factory/file is importing the module it's mocking
|
|
545
|
+
const isStale = !this.mocker.getDependencyMock(mod.id);
|
|
546
|
+
const isSelfImport = callstack.includes(mockId) || callstack.includes(url) || "redirect" in mockedModule && callstack.includes(mockedModule.redirect);
|
|
547
|
+
if (isStale || isSelfImport) {
|
|
548
|
+
const node = await this.fetchModule(injectQuery(url, "_vitest_original"));
|
|
549
|
+
return this._cachedRequest(node.url, node, callstack, metadata);
|
|
550
|
+
}
|
|
551
|
+
mocked = await this.mocker.requestWithMockedModule(url, mod, callstack, mockedModule);
|
|
552
|
+
} else mocked = await this.mocker.mockedRequest(url, mod, callstack);
|
|
665
553
|
if (typeof mocked === "string") {
|
|
666
554
|
const node = await this.fetchModule(mocked);
|
|
667
555
|
return this._cachedRequest(mocked, node, callstack, metadata);
|
|
@@ -684,7 +572,7 @@ class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
|
|
|
684
572
|
}
|
|
685
573
|
|
|
686
574
|
const bareVitestRegexp = /^@?vitest(?:\/|$)/;
|
|
687
|
-
const normalizedDistDir = normalize
|
|
575
|
+
const normalizedDistDir = normalize(distDir);
|
|
688
576
|
const relativeIds = {};
|
|
689
577
|
const externalizeMap = /* @__PURE__ */ new Map();
|
|
690
578
|
// all Vitest imports always need to be externalized
|
|
@@ -707,7 +595,7 @@ function getCachedVitestImport(id, state) {
|
|
|
707
595
|
};
|
|
708
596
|
}
|
|
709
597
|
if (relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) {
|
|
710
|
-
const externalize = pathToFileURL(join
|
|
598
|
+
const externalize = pathToFileURL(join(root, id)).toString();
|
|
711
599
|
externalizeMap.set(id, externalize);
|
|
712
600
|
return {
|
|
713
601
|
externalize,
|
|
@@ -724,48 +612,14 @@ function getCachedVitestImport(id, state) {
|
|
|
724
612
|
return null;
|
|
725
613
|
}
|
|
726
614
|
|
|
727
|
-
// Store globals in case tests overwrite them
|
|
728
|
-
const processListeners = process.listeners.bind(process);
|
|
729
|
-
const processOn = process.on.bind(process);
|
|
730
|
-
const processOff = process.off.bind(process);
|
|
731
|
-
const dispose = [];
|
|
732
|
-
function listenForErrors(state) {
|
|
733
|
-
dispose.forEach((fn) => fn());
|
|
734
|
-
dispose.length = 0;
|
|
735
|
-
function catchError(err, type, event) {
|
|
736
|
-
const worker = state();
|
|
737
|
-
// if there is another listener, assume that it's handled by user code
|
|
738
|
-
// one is Vitest's own listener
|
|
739
|
-
if (processListeners(event).length > 1) return;
|
|
740
|
-
const error = serializeValue(err);
|
|
741
|
-
if (typeof error === "object" && error != null) {
|
|
742
|
-
error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0;
|
|
743
|
-
if (worker.filepath) error.VITEST_TEST_PATH = worker.filepath;
|
|
744
|
-
}
|
|
745
|
-
state().rpc.onUnhandledError(error, type);
|
|
746
|
-
}
|
|
747
|
-
const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException");
|
|
748
|
-
const unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
|
|
749
|
-
processOn("uncaughtException", uncaughtException);
|
|
750
|
-
processOn("unhandledRejection", unhandledRejection);
|
|
751
|
-
dispose.push(() => {
|
|
752
|
-
processOff("uncaughtException", uncaughtException);
|
|
753
|
-
processOff("unhandledRejection", unhandledRejection);
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
|
|
757
615
|
const { readFileSync } = fs;
|
|
758
616
|
const VITEST_VM_CONTEXT_SYMBOL = "__vitest_vm_context__";
|
|
759
617
|
const cwd = process.cwd();
|
|
760
618
|
const isWindows = process.platform === "win32";
|
|
761
619
|
function startVitestModuleRunner(options) {
|
|
762
620
|
const traces = options.traces;
|
|
763
|
-
const state = () =>
|
|
621
|
+
const state = () => getSafeWorkerState() || options.state;
|
|
764
622
|
const rpc = () => state().rpc;
|
|
765
|
-
process.exit = (code = process.exitCode || 0) => {
|
|
766
|
-
throw new Error(`process.exit unexpectedly called with "${code}"`);
|
|
767
|
-
};
|
|
768
|
-
listenForErrors(state);
|
|
769
623
|
const environment = () => {
|
|
770
624
|
const environment = state().environment;
|
|
771
625
|
return environment.viteEnvironment || environment.name;
|
|
@@ -804,19 +658,25 @@ function startVitestModuleRunner(options) {
|
|
|
804
658
|
}
|
|
805
659
|
const vitest = getCachedVitestImport(id, state);
|
|
806
660
|
if (vitest) return vitest;
|
|
661
|
+
// strip _vitest_original query added by importActual so that
|
|
662
|
+
// the plugin pipeline sees the original import id (e.g. virtual modules's load hook)
|
|
663
|
+
const isImportActual = id.includes("_vitest_original");
|
|
664
|
+
if (isImportActual) id = removeQuery(id, "_vitest_original");
|
|
807
665
|
const rawId = unwrapId(id);
|
|
808
666
|
resolvingModules.add(rawId);
|
|
809
667
|
try {
|
|
810
668
|
if (VitestMocker.pendingIds.length) await moduleRunner.mocker.resolveMocks();
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
669
|
+
if (!isImportActual) {
|
|
670
|
+
const resolvedMock = moduleRunner.mocker.getDependencyMockByUrl(id);
|
|
671
|
+
if (resolvedMock?.type === "manual" || resolvedMock?.type === "redirect") return {
|
|
672
|
+
code: "",
|
|
673
|
+
file: null,
|
|
674
|
+
id: resolvedMock.id,
|
|
675
|
+
url: resolvedMock.url,
|
|
676
|
+
invalidate: false,
|
|
677
|
+
mockedModule: resolvedMock
|
|
678
|
+
};
|
|
679
|
+
}
|
|
820
680
|
if (isBuiltin(rawId)) return {
|
|
821
681
|
externalize: rawId,
|
|
822
682
|
type: "builtin"
|
|
@@ -838,7 +698,7 @@ function startVitestModuleRunner(options) {
|
|
|
838
698
|
} catch (cause) {
|
|
839
699
|
// rethrow vite error if it cannot load the module because it's not resolved
|
|
840
700
|
if (typeof cause === "object" && cause != null && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url") || typeof cause?.message === "string" && cause.message.startsWith("Cannot find module '")) {
|
|
841
|
-
const error = new Error(`Cannot find ${isBareImport(id) ? "package" : "module"} '${id}'${importer ? ` imported from
|
|
701
|
+
const error = new Error(`Cannot find ${isBareImport(id) ? "package" : "module"} '${id}'${importer ? ` imported from ${importer}` : ""}`, { cause });
|
|
842
702
|
error.code = "ERR_MODULE_NOT_FOUND";
|
|
843
703
|
throw error;
|
|
844
704
|
}
|
|
@@ -858,4 +718,4 @@ function startVitestModuleRunner(options) {
|
|
|
858
718
|
return moduleRunner;
|
|
859
719
|
}
|
|
860
720
|
|
|
861
|
-
export {
|
|
721
|
+
export { BareModuleMocker as B, VITEST_VM_CONTEXT_SYMBOL as V, VitestModuleRunner as a, VitestTransport as b, createNodeImportMeta as c, normalizeModuleId as n, startVitestModuleRunner as s };
|