elit 3.6.5 → 3.6.7
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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/README.md +6 -0
- package/dist/build.cjs +421 -331
- package/dist/build.d.ts +1 -16
- package/dist/build.js +420 -330
- package/dist/build.mjs +420 -330
- package/dist/chokidar.cjs +219 -182
- package/dist/chokidar.d.ts +25 -10
- package/dist/chokidar.js +217 -182
- package/dist/chokidar.mjs +218 -183
- package/dist/cli.cjs +21608 -20241
- package/dist/cli.d.ts +19 -37
- package/dist/cli.mjs +21262 -19910
- package/dist/config.cjs +357 -350
- package/dist/config.d.ts +19 -240
- package/dist/config.js +520 -515
- package/dist/config.mjs +346 -341
- package/dist/contracts-BeW9k0yZ.d.ts +54 -0
- package/dist/contracts-D7KIS-TK.d.ts +36 -0
- package/dist/coverage.cjs +448 -485
- package/dist/coverage.d.ts +13 -59
- package/dist/coverage.js +447 -484
- package/dist/coverage.mjs +447 -484
- package/dist/database.cjs +819 -828
- package/dist/database.d.ts +8 -24
- package/dist/database.js +818 -829
- package/dist/database.mjs +818 -829
- package/dist/desktop-auto-render.cjs +1700 -1522
- package/dist/desktop-auto-render.d.ts +4 -9
- package/dist/desktop-auto-render.js +1695 -1517
- package/dist/desktop-auto-render.mjs +1696 -1518
- package/dist/desktop.cjs +3 -1
- package/dist/desktop.d.ts +4 -1
- package/dist/desktop.js +1 -1
- package/dist/desktop.mjs +1 -1
- package/dist/dev-build.cjs +830 -0
- package/dist/dev-build.d.ts +53 -0
- package/dist/dev-build.js +3318 -0
- package/dist/dev-build.mjs +797 -0
- package/dist/dom.cjs +717 -590
- package/dist/dom.d.ts +2 -15
- package/dist/dom.js +714 -587
- package/dist/dom.mjs +716 -589
- package/dist/el.cjs +62 -52
- package/dist/el.d.ts +5 -10
- package/dist/el.js +60 -52
- package/dist/el.mjs +60 -52
- package/dist/fs.cjs +72 -63
- package/dist/fs.d.ts +22 -19
- package/dist/fs.js +71 -62
- package/dist/fs.mjs +71 -62
- package/dist/hmr.cjs +40 -14
- package/dist/hmr.d.ts +11 -23
- package/dist/hmr.js +38 -14
- package/dist/hmr.mjs +38 -14
- package/dist/http.cjs +251 -99
- package/dist/http.d.ts +38 -104
- package/dist/http.js +249 -99
- package/dist/http.mjs +249 -99
- package/dist/https.cjs +524 -228
- package/dist/https.d.ts +44 -36
- package/dist/https.js +520 -226
- package/dist/https.mjs +522 -228
- package/dist/index.cjs +7502 -7690
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7486 -7676
- package/dist/index.mjs +7497 -7686
- package/dist/mime-types.cjs +10 -4
- package/dist/mime-types.d.ts +8 -11
- package/dist/mime-types.js +9 -3
- package/dist/mime-types.mjs +9 -3
- package/dist/native.cjs +8616 -8869
- package/dist/native.d.ts +7 -8
- package/dist/native.js +8682 -8935
- package/dist/native.mjs +8615 -8868
- package/dist/path.cjs +83 -77
- package/dist/path.d.ts +29 -29
- package/dist/path.js +82 -76
- package/dist/path.mjs +82 -76
- package/dist/pm.cjs +3300 -0
- package/dist/pm.d.ts +256 -0
- package/dist/pm.js +5638 -0
- package/dist/pm.mjs +3196 -0
- package/dist/preview-build.cjs +712 -0
- package/dist/preview-build.d.ts +59 -0
- package/dist/preview-build.js +3194 -0
- package/dist/preview-build.mjs +676 -0
- package/dist/render-context.cjs +13 -2
- package/dist/render-context.d.ts +9 -31
- package/dist/render-context.js +11 -2
- package/dist/render-context.mjs +11 -2
- package/dist/router.cjs +787 -645
- package/dist/router.d.ts +8 -12
- package/dist/router.js +786 -644
- package/dist/router.mjs +786 -644
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/server.cjs +3315 -2603
- package/dist/server.d.ts +49 -4
- package/dist/server.js +7611 -2834
- package/dist/server.mjs +3317 -2607
- package/dist/smtp-server.cjs +128 -0
- package/dist/smtp-server.d.ts +27 -0
- package/dist/smtp-server.js +4199 -0
- package/dist/smtp-server.mjs +100 -0
- package/dist/state-DvEkDehk.d.ts +195 -0
- package/dist/state.cjs +768 -658
- package/dist/state.d.ts +11 -69
- package/dist/state.js +760 -650
- package/dist/state.mjs +767 -657
- package/dist/style.cjs +1011 -968
- package/dist/style.d.ts +13 -127
- package/dist/style.js +1009 -970
- package/dist/style.mjs +1011 -971
- package/dist/test-reporter.cjs +332 -316
- package/dist/test-reporter.d.ts +28 -33
- package/dist/test-reporter.js +328 -312
- package/dist/test-reporter.mjs +328 -312
- package/dist/test-runtime.cjs +927 -968
- package/dist/test-runtime.d.ts +24 -99
- package/dist/test-runtime.js +922 -965
- package/dist/test-runtime.mjs +922 -965
- package/dist/test.cjs +4428 -4273
- package/dist/test.d.ts +2 -8
- package/dist/test.js +4307 -4154
- package/dist/test.mjs +4419 -4267
- package/dist/types-BONVzPtp.d.ts +59 -0
- package/dist/types-BR4wMiVx.d.ts +32 -0
- package/dist/types-C4gKykuG.d.ts +23 -0
- package/dist/types-CIhpN1-K.d.ts +64 -0
- package/dist/types-Ckj8md_j.d.ts +84 -0
- package/dist/types-CpjQTAkX.d.ts +24 -0
- package/dist/types-D0LjrYjS.d.ts +14 -0
- package/dist/types-DAisuVr5.d.ts +75 -0
- package/dist/types-tJn88E1N.d.ts +242 -0
- package/dist/types.d.ts +71 -226
- package/dist/universal.cjs +1 -1
- package/dist/universal.d.ts +1 -5
- package/dist/universal.js +1 -1
- package/dist/universal.mjs +1 -1
- package/dist/websocket-XfyK23zD.d.ts +119 -0
- package/dist/ws.cjs +129 -108
- package/dist/ws.d.ts +21 -131
- package/dist/ws.js +128 -109
- package/dist/ws.mjs +128 -109
- package/dist/wss.cjs +757 -479
- package/dist/wss.d.ts +31 -28
- package/dist/wss.js +755 -479
- package/dist/wss.mjs +758 -482
- package/package.json +16 -1
- package/vendor/epaint-0.31.1/src/image.rs +418 -0
- package/dist/server-CcBFc2F5.d.ts +0 -449
package/dist/test-runtime.cjs
CHANGED
|
@@ -17,9 +17,9 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/test
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// src/test/runtime/index.ts
|
|
21
|
+
var runtime_exports = {};
|
|
22
|
+
__export(runtime_exports, {
|
|
23
23
|
clearGlobals: () => clearGlobals,
|
|
24
24
|
getCoveredFiles: () => getCoveredFiles,
|
|
25
25
|
globals: () => globals,
|
|
@@ -28,10 +28,55 @@ __export(test_runtime_exports, {
|
|
|
28
28
|
setupGlobals: () => setupGlobals,
|
|
29
29
|
transpileFile: () => transpileFile
|
|
30
30
|
});
|
|
31
|
-
module.exports = __toCommonJS(
|
|
32
|
-
|
|
31
|
+
module.exports = __toCommonJS(runtime_exports);
|
|
32
|
+
|
|
33
|
+
// src/test/runtime/state.ts
|
|
34
|
+
function createRootSuite() {
|
|
35
|
+
return {
|
|
36
|
+
name: "root",
|
|
37
|
+
tests: [],
|
|
38
|
+
suites: [],
|
|
39
|
+
skip: false,
|
|
40
|
+
only: false
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var runtimeState = {
|
|
44
|
+
currentSuite: createRootSuite(),
|
|
45
|
+
testResults: [],
|
|
46
|
+
hasOnly: false,
|
|
47
|
+
coveredFiles: /* @__PURE__ */ new Set(),
|
|
48
|
+
describePattern: void 0,
|
|
49
|
+
testPattern: void 0,
|
|
50
|
+
currentTestFile: void 0,
|
|
51
|
+
currentSourceMapConsumer: void 0,
|
|
52
|
+
wrapperLineOffset: 0,
|
|
53
|
+
beforeAllHooks: [],
|
|
54
|
+
afterAllHooks: [],
|
|
55
|
+
beforeEachHooks: [],
|
|
56
|
+
afterEachHooks: []
|
|
57
|
+
};
|
|
58
|
+
function resetSuiteState() {
|
|
59
|
+
runtimeState.currentSuite = createRootSuite();
|
|
60
|
+
runtimeState.hasOnly = false;
|
|
61
|
+
}
|
|
62
|
+
function resetHookState() {
|
|
63
|
+
runtimeState.beforeAllHooks = [];
|
|
64
|
+
runtimeState.afterAllHooks = [];
|
|
65
|
+
runtimeState.beforeEachHooks = [];
|
|
66
|
+
runtimeState.afterEachHooks = [];
|
|
67
|
+
}
|
|
68
|
+
function resetSourceMapState() {
|
|
69
|
+
runtimeState.currentSourceMapConsumer = void 0;
|
|
70
|
+
runtimeState.wrapperLineOffset = 0;
|
|
71
|
+
}
|
|
72
|
+
function getCoveredFiles() {
|
|
73
|
+
return runtimeState.coveredFiles;
|
|
74
|
+
}
|
|
75
|
+
function resetCoveredFiles() {
|
|
76
|
+
runtimeState.coveredFiles.clear();
|
|
77
|
+
}
|
|
33
78
|
|
|
34
|
-
// src/runtime.ts
|
|
79
|
+
// src/shares/runtime.ts
|
|
35
80
|
var runtime = (() => {
|
|
36
81
|
if (typeof Deno !== "undefined") return "deno";
|
|
37
82
|
if (typeof Bun !== "undefined") return "bun";
|
|
@@ -41,7 +86,15 @@ var isNode = runtime === "node";
|
|
|
41
86
|
var isBun = runtime === "bun";
|
|
42
87
|
var isDeno = runtime === "deno";
|
|
43
88
|
|
|
44
|
-
// src/fs.ts
|
|
89
|
+
// src/server/fs/node-modules.ts
|
|
90
|
+
var fs;
|
|
91
|
+
var fsPromises;
|
|
92
|
+
if (isNode || isBun) {
|
|
93
|
+
fs = require("fs");
|
|
94
|
+
fsPromises = require("fs/promises");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/server/fs/utils.ts
|
|
45
98
|
function parseOptions(options, defaultValue) {
|
|
46
99
|
return typeof options === "string" ? { encoding: options } : options || defaultValue;
|
|
47
100
|
}
|
|
@@ -51,12 +104,37 @@ function decodeContent(content, encoding) {
|
|
|
51
104
|
}
|
|
52
105
|
return Buffer.from(content instanceof ArrayBuffer ? new Uint8Array(content) : content);
|
|
53
106
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
107
|
+
function createStatsFromDenoFileInfo(info) {
|
|
108
|
+
return {
|
|
109
|
+
isFile: () => info.isFile,
|
|
110
|
+
isDirectory: () => info.isDirectory,
|
|
111
|
+
isBlockDevice: () => false,
|
|
112
|
+
isCharacterDevice: () => false,
|
|
113
|
+
isSymbolicLink: () => info.isSymlink || false,
|
|
114
|
+
isFIFO: () => false,
|
|
115
|
+
isSocket: () => false,
|
|
116
|
+
dev: info.dev || 0,
|
|
117
|
+
ino: info.ino || 0,
|
|
118
|
+
mode: info.mode || 0,
|
|
119
|
+
nlink: info.nlink || 1,
|
|
120
|
+
uid: info.uid || 0,
|
|
121
|
+
gid: info.gid || 0,
|
|
122
|
+
rdev: 0,
|
|
123
|
+
size: info.size,
|
|
124
|
+
blksize: info.blksize || 4096,
|
|
125
|
+
blocks: info.blocks || Math.ceil(info.size / 512),
|
|
126
|
+
atimeMs: info.atime?.getTime() || Date.now(),
|
|
127
|
+
mtimeMs: info.mtime?.getTime() || Date.now(),
|
|
128
|
+
ctimeMs: info.birthtime?.getTime() || Date.now(),
|
|
129
|
+
birthtimeMs: info.birthtime?.getTime() || Date.now(),
|
|
130
|
+
atime: info.atime || /* @__PURE__ */ new Date(),
|
|
131
|
+
mtime: info.mtime || /* @__PURE__ */ new Date(),
|
|
132
|
+
ctime: info.birthtime || /* @__PURE__ */ new Date(),
|
|
133
|
+
birthtime: info.birthtime || /* @__PURE__ */ new Date()
|
|
134
|
+
};
|
|
59
135
|
}
|
|
136
|
+
|
|
137
|
+
// src/server/fs/file-ops.ts
|
|
60
138
|
async function readFile(path, options) {
|
|
61
139
|
const opts = parseOptions(options, {});
|
|
62
140
|
if (isNode || isBun) {
|
|
@@ -94,421 +172,460 @@ function statSync(path) {
|
|
|
94
172
|
}
|
|
95
173
|
throw new Error("Unsupported runtime");
|
|
96
174
|
}
|
|
97
|
-
function createStatsFromDenoFileInfo(info) {
|
|
98
|
-
return {
|
|
99
|
-
isFile: () => info.isFile,
|
|
100
|
-
isDirectory: () => info.isDirectory,
|
|
101
|
-
isBlockDevice: () => false,
|
|
102
|
-
isCharacterDevice: () => false,
|
|
103
|
-
isSymbolicLink: () => info.isSymlink || false,
|
|
104
|
-
isFIFO: () => false,
|
|
105
|
-
isSocket: () => false,
|
|
106
|
-
dev: info.dev || 0,
|
|
107
|
-
ino: info.ino || 0,
|
|
108
|
-
mode: info.mode || 0,
|
|
109
|
-
nlink: info.nlink || 1,
|
|
110
|
-
uid: info.uid || 0,
|
|
111
|
-
gid: info.gid || 0,
|
|
112
|
-
rdev: 0,
|
|
113
|
-
size: info.size,
|
|
114
|
-
blksize: info.blksize || 4096,
|
|
115
|
-
blocks: info.blocks || Math.ceil(info.size / 512),
|
|
116
|
-
atimeMs: info.atime?.getTime() || Date.now(),
|
|
117
|
-
mtimeMs: info.mtime?.getTime() || Date.now(),
|
|
118
|
-
ctimeMs: info.birthtime?.getTime() || Date.now(),
|
|
119
|
-
birthtimeMs: info.birthtime?.getTime() || Date.now(),
|
|
120
|
-
atime: info.atime || /* @__PURE__ */ new Date(),
|
|
121
|
-
mtime: info.mtime || /* @__PURE__ */ new Date(),
|
|
122
|
-
ctime: info.birthtime || /* @__PURE__ */ new Date(),
|
|
123
|
-
birthtime: info.birthtime || /* @__PURE__ */ new Date()
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
175
|
|
|
127
|
-
// src/
|
|
128
|
-
function
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
function getCwd() {
|
|
132
|
-
if (isNode || isBun) {
|
|
133
|
-
return process.cwd();
|
|
134
|
-
} else if (isDeno) {
|
|
135
|
-
return Deno.cwd();
|
|
136
|
-
}
|
|
137
|
-
return "/";
|
|
138
|
-
}
|
|
139
|
-
function findLastSeparator(path) {
|
|
140
|
-
return Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
176
|
+
// src/test/runtime/assertion-context.ts
|
|
177
|
+
function getAssertionMethod(stack) {
|
|
178
|
+
const assertionMatch = stack.match(/at _?Expect\.(\w+)/);
|
|
179
|
+
return assertionMatch ? assertionMatch[1] : void 0;
|
|
141
180
|
}
|
|
142
|
-
function
|
|
143
|
-
return
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return path.length > 0 && path[0] === "/";
|
|
181
|
+
function getTargetPattern(assertionMethod) {
|
|
182
|
+
if (assertionMethod === "toEqual") return ".toEqual(";
|
|
183
|
+
if (assertionMethod === "toStrictEqual") return ".toStrictEqual(";
|
|
184
|
+
if (assertionMethod === "toMatch") return ".toMatch(";
|
|
185
|
+
if (assertionMethod === "toContain") return ".toContain(";
|
|
186
|
+
if (assertionMethod === "toHaveLength") return ".toHaveLength(";
|
|
187
|
+
if (assertionMethod === "toBeDefined") return ".toBeDefined(";
|
|
188
|
+
if (assertionMethod === "toBeNull") return ".toBeNull(";
|
|
189
|
+
if (assertionMethod === "toBeUndefined") return ".toBeUndefined(";
|
|
190
|
+
if (assertionMethod === "toBeTruthy") return ".toBeTruthy(";
|
|
191
|
+
if (assertionMethod === "toBeFalsy") return ".toBeFalsy(";
|
|
192
|
+
if (assertionMethod === "toThrow") return ".toThrow(";
|
|
193
|
+
if (assertionMethod === "toBeGreaterThan") return ".toBeGreaterThan(";
|
|
194
|
+
if (assertionMethod === "toBeGreaterThanOrEqual") return ".toBeGreaterThanOrEqual(";
|
|
195
|
+
if (assertionMethod === "toBeLessThan") return ".toBeLessThan(";
|
|
196
|
+
if (assertionMethod === "toBeLessThanOrEqual") return ".toBeLessThanOrEqual(";
|
|
197
|
+
return ".toBe(";
|
|
160
198
|
}
|
|
161
|
-
function
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
|
|
169
|
-
if (len > 2 && path.charCodeAt(1) === 58) {
|
|
170
|
-
const code2 = path.charCodeAt(2);
|
|
171
|
-
if (code2 === 47 || code2 === 92) {
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
199
|
+
function readSourceLines(filePath) {
|
|
200
|
+
try {
|
|
201
|
+
let sourceCode = readFileSync(filePath, "utf-8");
|
|
202
|
+
if (Buffer.isBuffer(sourceCode)) {
|
|
203
|
+
sourceCode = sourceCode.toString("utf-8");
|
|
174
204
|
}
|
|
205
|
+
return sourceCode.split("\n");
|
|
206
|
+
} catch {
|
|
207
|
+
return void 0;
|
|
175
208
|
}
|
|
176
|
-
return false;
|
|
177
209
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
210
|
+
function resolveMappedLine(lineNumber, sourceLines, assertionMethod) {
|
|
211
|
+
const targetPattern = getTargetPattern(assertionMethod);
|
|
212
|
+
if (lineNumber <= 0 || lineNumber > sourceLines.length) {
|
|
213
|
+
return lineNumber;
|
|
214
|
+
}
|
|
215
|
+
if (sourceLines[lineNumber - 1].includes(targetPattern)) {
|
|
216
|
+
return lineNumber;
|
|
217
|
+
}
|
|
218
|
+
for (let index = 1; index <= 3; index++) {
|
|
219
|
+
const searchLine = lineNumber - index;
|
|
220
|
+
if (searchLine > 0 && searchLine <= sourceLines.length && sourceLines[searchLine - 1].includes(targetPattern)) {
|
|
221
|
+
return searchLine;
|
|
222
|
+
}
|
|
183
223
|
}
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (i === 0 && isAbsolute) result.push("");
|
|
200
|
-
continue;
|
|
224
|
+
return lineNumber;
|
|
225
|
+
}
|
|
226
|
+
function resolveAssertionContext(stack) {
|
|
227
|
+
if (!stack) {
|
|
228
|
+
return {};
|
|
229
|
+
}
|
|
230
|
+
const assertionMethod = getAssertionMethod(stack);
|
|
231
|
+
const stackFrames = [];
|
|
232
|
+
for (const line of stack.split("\n")) {
|
|
233
|
+
const match = line.match(/<anonymous>:([0-9]+):([0-9]+)/);
|
|
234
|
+
if (match) {
|
|
235
|
+
stackFrames.push({
|
|
236
|
+
line: parseInt(match[1], 10),
|
|
237
|
+
column: parseInt(match[2], 10)
|
|
238
|
+
});
|
|
201
239
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
240
|
+
}
|
|
241
|
+
const targetFrame = stackFrames.length > 1 ? stackFrames[1] : stackFrames[0];
|
|
242
|
+
let lineNumber;
|
|
243
|
+
if (targetFrame && runtimeState.currentSourceMapConsumer) {
|
|
244
|
+
try {
|
|
245
|
+
const transpiledLine = targetFrame.line - runtimeState.wrapperLineOffset;
|
|
246
|
+
const originalPosition = runtimeState.currentSourceMapConsumer.originalPositionFor({
|
|
247
|
+
line: transpiledLine,
|
|
248
|
+
column: targetFrame.column
|
|
249
|
+
});
|
|
250
|
+
if (originalPosition.line !== null) {
|
|
251
|
+
lineNumber = originalPosition.line;
|
|
252
|
+
} else {
|
|
253
|
+
const posWithoutColumn = runtimeState.currentSourceMapConsumer.originalPositionFor({
|
|
254
|
+
line: transpiledLine,
|
|
255
|
+
column: 0
|
|
256
|
+
});
|
|
257
|
+
if (posWithoutColumn.line !== null) {
|
|
258
|
+
lineNumber = posWithoutColumn.line;
|
|
259
|
+
} else {
|
|
260
|
+
const lineMappings = [];
|
|
261
|
+
runtimeState.currentSourceMapConsumer.eachMapping((mapping) => {
|
|
262
|
+
if (mapping.originalLine !== null) {
|
|
263
|
+
lineMappings.push({
|
|
264
|
+
line: mapping.originalLine,
|
|
265
|
+
distance: Math.abs(mapping.generatedLine - transpiledLine)
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
if (lineMappings.length > 0) {
|
|
270
|
+
lineMappings.sort((left, right) => left.distance - right.distance);
|
|
271
|
+
lineNumber = lineMappings[0].line;
|
|
272
|
+
}
|
|
206
273
|
}
|
|
207
|
-
} else if (!isAbsolute) {
|
|
208
|
-
result.push("..");
|
|
209
274
|
}
|
|
210
|
-
}
|
|
211
|
-
result.push(part);
|
|
275
|
+
} catch {
|
|
212
276
|
}
|
|
213
277
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return isAbsolute ? separator : ".";
|
|
278
|
+
if (!runtimeState.currentTestFile || !lineNumber) {
|
|
279
|
+
return { lineNumber };
|
|
217
280
|
}
|
|
218
|
-
|
|
219
|
-
|
|
281
|
+
const sourceLines = readSourceLines(runtimeState.currentTestFile);
|
|
282
|
+
if (!sourceLines) {
|
|
283
|
+
return { lineNumber };
|
|
220
284
|
}
|
|
221
|
-
|
|
285
|
+
lineNumber = resolveMappedLine(lineNumber, sourceLines, assertionMethod);
|
|
286
|
+
const codeLine = lineNumber > 0 && lineNumber <= sourceLines.length ? sourceLines[lineNumber - 1] : void 0;
|
|
287
|
+
return {
|
|
288
|
+
lineNumber,
|
|
289
|
+
codeSnippet: codeLine ? codeLine.trim() : void 0
|
|
290
|
+
};
|
|
222
291
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
292
|
+
|
|
293
|
+
// src/test/runtime/expect.ts
|
|
294
|
+
var AssertionError = class extends Error {
|
|
295
|
+
constructor(message, filePath, lineNumber, columnNumber, codeSnippet) {
|
|
296
|
+
super(message);
|
|
297
|
+
this.filePath = filePath;
|
|
298
|
+
this.lineNumber = lineNumber;
|
|
299
|
+
this.columnNumber = columnNumber;
|
|
300
|
+
this.codeSnippet = codeSnippet;
|
|
301
|
+
this.name = "AssertionError";
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
var Expect = class _Expect {
|
|
305
|
+
constructor(actual, isNot = false, isAsync = false) {
|
|
306
|
+
this.actual = actual;
|
|
307
|
+
this.isNot = isNot;
|
|
308
|
+
this.isAsync = isAsync;
|
|
309
|
+
this._not = null;
|
|
310
|
+
this._resolves = null;
|
|
311
|
+
this._rejects = null;
|
|
312
|
+
}
|
|
313
|
+
get not() {
|
|
314
|
+
if (!this._not) {
|
|
315
|
+
this._not = new _Expect(this.actual, !this.isNot, false);
|
|
235
316
|
}
|
|
317
|
+
return this._not;
|
|
236
318
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
function resolvePaths(paths, isWin) {
|
|
241
|
-
const separator = getSeparator(isWin);
|
|
242
|
-
let resolved = "";
|
|
243
|
-
let isAbsolute = false;
|
|
244
|
-
for (let i = paths.length - 1; i >= 0 && !isAbsolute; i--) {
|
|
245
|
-
const path = paths[i];
|
|
246
|
-
if (path && path.length > 0) {
|
|
247
|
-
resolved = path + (resolved.length > 0 ? separator + resolved : "");
|
|
248
|
-
isAbsolute = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);
|
|
319
|
+
get resolves() {
|
|
320
|
+
if (!this._resolves) {
|
|
321
|
+
this._resolves = new _Expect(this.actual, this.isNot, true);
|
|
249
322
|
}
|
|
323
|
+
return this._resolves;
|
|
250
324
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
325
|
+
get rejects() {
|
|
326
|
+
if (!this._rejects) {
|
|
327
|
+
this._rejects = new _Expect(this.actual, this.isNot, true);
|
|
328
|
+
}
|
|
329
|
+
return this._rejects;
|
|
254
330
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
break;
|
|
331
|
+
assertCondition(condition, message, showExpectedReceived = true, expectedDisplay, callerStack) {
|
|
332
|
+
if (this.isNot) {
|
|
333
|
+
condition = !condition;
|
|
334
|
+
}
|
|
335
|
+
if (!condition) {
|
|
336
|
+
let errorMessage = message;
|
|
337
|
+
if (showExpectedReceived) {
|
|
338
|
+
const expectedValue = expectedDisplay ?? this.stringify(this.expected ?? "truthy");
|
|
339
|
+
errorMessage += `
|
|
340
|
+
Expected: ${expectedValue}
|
|
341
|
+
Received: ${this.stringify(this.actual)}`;
|
|
342
|
+
}
|
|
343
|
+
const stack = callerStack || new Error().stack;
|
|
344
|
+
const { lineNumber, codeSnippet } = resolveAssertionContext(stack);
|
|
345
|
+
throw new AssertionError(errorMessage, runtimeState.currentTestFile, lineNumber, void 0, codeSnippet);
|
|
271
346
|
}
|
|
272
347
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
348
|
+
stringify(value) {
|
|
349
|
+
if (value === void 0) return "undefined";
|
|
350
|
+
if (value === null) return "null";
|
|
351
|
+
if (typeof value === "string") return `"${value}"`;
|
|
352
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
353
|
+
if (typeof value === "function") return "Function";
|
|
354
|
+
if (Array.isArray(value)) return `[${value.map((item) => this.stringify(item)).join(", ")}]`;
|
|
355
|
+
if (typeof value === "object") {
|
|
356
|
+
const keys = Object.keys(value);
|
|
357
|
+
if (keys.length === 0) return "{}";
|
|
358
|
+
return `{ ${keys.slice(0, 3).map((key) => `${key}: ${this.stringify(value[key])}`).join(", ")}${keys.length > 3 ? "..." : ""} }`;
|
|
359
|
+
}
|
|
360
|
+
return String(value);
|
|
277
361
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
function getDirname(path, isWin) {
|
|
284
|
-
if (path.length === 0) return ".";
|
|
285
|
-
const separator = getSeparator(isWin);
|
|
286
|
-
const normalized = normalizePath(path, isWin);
|
|
287
|
-
const lastSepIndex = normalized.lastIndexOf(separator);
|
|
288
|
-
if (lastSepIndex === -1) return ".";
|
|
289
|
-
if (lastSepIndex === 0) return separator;
|
|
290
|
-
return normalized.slice(0, lastSepIndex);
|
|
291
|
-
}
|
|
292
|
-
function getBasename(path, ext, isWin) {
|
|
293
|
-
if (path.length === 0) return "";
|
|
294
|
-
const lastSepIndex = isWin ? findLastSeparator(path) : path.lastIndexOf("/");
|
|
295
|
-
let base = lastSepIndex === -1 ? path : path.slice(lastSepIndex + 1);
|
|
296
|
-
if (ext && base.endsWith(ext)) {
|
|
297
|
-
base = base.slice(0, base.length - ext.length);
|
|
298
|
-
}
|
|
299
|
-
return base;
|
|
300
|
-
}
|
|
301
|
-
function getExtname(path) {
|
|
302
|
-
const lastDotIndex = path.lastIndexOf(".");
|
|
303
|
-
const lastSepIndex = findLastSeparator(path);
|
|
304
|
-
if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex === path.length - 1) {
|
|
305
|
-
return "";
|
|
306
|
-
}
|
|
307
|
-
return path.slice(lastDotIndex);
|
|
308
|
-
}
|
|
309
|
-
function parsePath(path, isWin) {
|
|
310
|
-
let root = "";
|
|
311
|
-
if (isWin) {
|
|
312
|
-
if (path.length >= 2 && path[1] === ":") {
|
|
313
|
-
root = path.slice(0, 2);
|
|
314
|
-
if (path.length > 2 && (path[2] === "\\" || path[2] === "/")) {
|
|
315
|
-
root += "\\";
|
|
362
|
+
async handleAsyncAssertion(value, assertion) {
|
|
363
|
+
try {
|
|
364
|
+
const resolvedValue = await this.actual;
|
|
365
|
+
if (this.isNot) {
|
|
366
|
+
throw new Error("Promise resolved when it should have rejected");
|
|
316
367
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
368
|
+
assertion(resolvedValue);
|
|
369
|
+
return Promise.resolve(resolvedValue);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
if (this.isNot) {
|
|
372
|
+
return Promise.resolve(void 0);
|
|
373
|
+
}
|
|
374
|
+
if (typeof value === "string") {
|
|
375
|
+
this.assertCondition(
|
|
376
|
+
error.message?.includes(value),
|
|
377
|
+
`Expected error message to include "${value}"`
|
|
378
|
+
);
|
|
379
|
+
} else if (value instanceof RegExp) {
|
|
380
|
+
this.assertCondition(
|
|
381
|
+
value.test(error.message),
|
|
382
|
+
`Expected error message to match ${value}`
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
return Promise.resolve(void 0);
|
|
323
386
|
}
|
|
324
387
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// src/test-runtime.ts
|
|
344
|
-
var import_source_map = require("source-map");
|
|
345
|
-
function escapeRegex(str) {
|
|
346
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
347
|
-
}
|
|
348
|
-
var AssertionError = class extends Error {
|
|
349
|
-
constructor(message, filePath, lineNumber, columnNumber, codeSnippet) {
|
|
350
|
-
super(message);
|
|
351
|
-
this.filePath = filePath;
|
|
352
|
-
this.lineNumber = lineNumber;
|
|
353
|
-
this.columnNumber = columnNumber;
|
|
354
|
-
this.codeSnippet = codeSnippet;
|
|
355
|
-
this.name = "AssertionError";
|
|
388
|
+
toBe(value) {
|
|
389
|
+
const stack = new Error().stack;
|
|
390
|
+
if (this.isAsync) {
|
|
391
|
+
return this.handleAsyncAssertion(value, (actual) => {
|
|
392
|
+
this.expected = value;
|
|
393
|
+
this.assertCondition(actual === value, "Expected values to be strictly equal (using ===)", false, void 0, stack);
|
|
394
|
+
if (typeof actual !== typeof value) {
|
|
395
|
+
throw new Error(`Types don't match: expected ${typeof value} but got ${typeof actual}`);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
this.expected = value;
|
|
400
|
+
this.assertCondition(this.actual === value, "Expected values to be strictly equal (using ===)", true, void 0, stack);
|
|
401
|
+
if (typeof this.actual !== typeof value) {
|
|
402
|
+
throw new Error(`Types don't match: expected ${typeof value} but got ${typeof this.actual}`);
|
|
403
|
+
}
|
|
356
404
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
var testPattern = void 0;
|
|
370
|
-
var currentTestFile = void 0;
|
|
371
|
-
var currentSourceMapConsumer = void 0;
|
|
372
|
-
var wrapperLineOffset = 0;
|
|
373
|
-
var TEST_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
374
|
-
function resolveTestLoader(filePath) {
|
|
375
|
-
return /\.(?:ts|tsx|mts|cts)$/i.test(filePath) ? "ts" : "js";
|
|
376
|
-
}
|
|
377
|
-
function createTestTransformOptions(filePath, format, sourcemap) {
|
|
378
|
-
return {
|
|
379
|
-
loader: resolveTestLoader(filePath),
|
|
380
|
-
format,
|
|
381
|
-
sourcemap,
|
|
382
|
-
sourcefile: filePath,
|
|
383
|
-
target: "es2020",
|
|
384
|
-
tsconfigRaw: {
|
|
385
|
-
compilerOptions: {
|
|
386
|
-
jsx: "react",
|
|
387
|
-
jsxFactory: "h",
|
|
388
|
-
jsxFragmentFactory: "Fragment"
|
|
405
|
+
toEqual(value) {
|
|
406
|
+
const stack = new Error().stack;
|
|
407
|
+
this.expected = value;
|
|
408
|
+
const isEqual = (left, right) => {
|
|
409
|
+
if (left === right) return true;
|
|
410
|
+
if (left == null || right == null) return left === right;
|
|
411
|
+
if (typeof left !== typeof right) return false;
|
|
412
|
+
if (typeof left !== "object") return left === right;
|
|
413
|
+
if (Array.isArray(left) !== Array.isArray(right)) return false;
|
|
414
|
+
if (Array.isArray(left)) {
|
|
415
|
+
if (left.length !== right.length) return false;
|
|
416
|
+
return left.every((item, index) => isEqual(item, right[index]));
|
|
389
417
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return basePath;
|
|
418
|
+
const keysLeft = Object.keys(left);
|
|
419
|
+
const keysRight = Object.keys(right);
|
|
420
|
+
if (keysLeft.length !== keysRight.length) return false;
|
|
421
|
+
return keysLeft.every((key) => isEqual(left[key], right[key]));
|
|
422
|
+
};
|
|
423
|
+
this.assertCondition(isEqual(this.actual, value), "Expected values to be deeply equal", false, void 0, stack);
|
|
397
424
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
425
|
+
toBeTruthy() {
|
|
426
|
+
this.assertCondition(!!this.actual, "Expected value to be truthy", false, void 0, new Error().stack);
|
|
427
|
+
}
|
|
428
|
+
toBeFalsy() {
|
|
429
|
+
this.assertCondition(!this.actual, "Expected value to be falsy", false, void 0, new Error().stack);
|
|
430
|
+
}
|
|
431
|
+
toBeNull() {
|
|
432
|
+
this.assertCondition(this.actual === null, "Expected value to be null", false, void 0, new Error().stack);
|
|
433
|
+
}
|
|
434
|
+
toBeUndefined() {
|
|
435
|
+
this.assertCondition(this.actual === void 0, "Expected value to be undefined", false, void 0, new Error().stack);
|
|
436
|
+
}
|
|
437
|
+
toBeDefined() {
|
|
438
|
+
this.assertCondition(this.actual !== void 0, "Expected value to be defined", false, void 0, new Error().stack);
|
|
439
|
+
}
|
|
440
|
+
toBeGreaterThan(value) {
|
|
441
|
+
const stack = new Error().stack;
|
|
442
|
+
this.expected = value;
|
|
443
|
+
this.assertCondition(typeof this.actual === "number" && this.actual > value, `Expected ${this.stringify(this.actual)} to be greater than ${value}`, true, String(value), stack);
|
|
444
|
+
}
|
|
445
|
+
toBeGreaterThanOrEqual(value) {
|
|
446
|
+
const stack = new Error().stack;
|
|
447
|
+
this.expected = value;
|
|
448
|
+
this.assertCondition(typeof this.actual === "number" && this.actual >= value, `Expected ${this.stringify(this.actual)} to be greater than or equal to ${value}`, true, `${value}`, stack);
|
|
449
|
+
}
|
|
450
|
+
toBeLessThan(value) {
|
|
451
|
+
const stack = new Error().stack;
|
|
452
|
+
this.expected = value;
|
|
453
|
+
this.assertCondition(typeof this.actual === "number" && this.actual < value, `Expected ${this.stringify(this.actual)} to be less than ${value}`, true, String(value), stack);
|
|
454
|
+
}
|
|
455
|
+
toBeLessThanOrEqual(value) {
|
|
456
|
+
const stack = new Error().stack;
|
|
457
|
+
this.expected = value;
|
|
458
|
+
this.assertCondition(typeof this.actual === "number" && this.actual <= value, `Expected ${this.stringify(this.actual)} to be less than or equal to ${value}`, true, `${value}`, stack);
|
|
459
|
+
}
|
|
460
|
+
toContain(value) {
|
|
461
|
+
const stack = new Error().stack;
|
|
462
|
+
this.expected = value;
|
|
463
|
+
if (typeof this.actual === "string") {
|
|
464
|
+
this.assertCondition(this.actual.includes(value), `Expected "${this.actual}" to contain "${value}"`, false, void 0, stack);
|
|
465
|
+
} else if (Array.isArray(this.actual)) {
|
|
466
|
+
this.assertCondition(this.actual.some((item) => this.deepEqual(item, value)), `Expected array to contain ${this.stringify(value)}`, false, void 0, stack);
|
|
467
|
+
} else {
|
|
468
|
+
throw new Error(`toContain expects string or array, got ${typeof this.actual}`);
|
|
402
469
|
}
|
|
403
470
|
}
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
471
|
+
toHaveLength(length) {
|
|
472
|
+
const stack = new Error().stack;
|
|
473
|
+
this.expected = length;
|
|
474
|
+
const actualLength = this.actual?.length;
|
|
475
|
+
this.assertCondition(actualLength === length, `Expected length to be ${length}, but got ${actualLength}`, false, void 0, stack);
|
|
476
|
+
}
|
|
477
|
+
toThrow(error) {
|
|
478
|
+
if (this.isAsync) {
|
|
479
|
+
return this.handleAsyncAssertion(error, () => {
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
let threw = false;
|
|
483
|
+
let thrownError = null;
|
|
484
|
+
try {
|
|
485
|
+
if (typeof this.actual === "function") {
|
|
486
|
+
this.actual();
|
|
420
487
|
}
|
|
488
|
+
} catch (caughtError) {
|
|
489
|
+
threw = true;
|
|
490
|
+
thrownError = caughtError;
|
|
421
491
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (
|
|
425
|
-
|
|
492
|
+
this.assertCondition(threw, "Expected function to throw an error");
|
|
493
|
+
if (error) {
|
|
494
|
+
if (typeof error === "string") {
|
|
495
|
+
this.assertCondition(thrownError.message.includes(error), `Expected error message to include "${error}"`);
|
|
496
|
+
} else if (error instanceof RegExp) {
|
|
497
|
+
this.assertCondition(error.test(thrownError.message), `Expected error message to match ${error}`);
|
|
426
498
|
}
|
|
427
499
|
}
|
|
428
500
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const basePath = specifier.startsWith(".") ? nodePath.resolve(dirname(fromFilePath), specifier) : specifier;
|
|
437
|
-
return resolveExistingTestModulePath(basePath);
|
|
438
|
-
}
|
|
439
|
-
function shouldTranspileTestModule(filePath) {
|
|
440
|
-
return /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(filePath);
|
|
441
|
-
}
|
|
442
|
-
function createTestModuleRequire(fromFilePath, moduleCache) {
|
|
443
|
-
return (specifier) => {
|
|
444
|
-
if (specifier.startsWith("elit/") || specifier === "elit") {
|
|
445
|
-
return require(specifier);
|
|
446
|
-
}
|
|
447
|
-
const resolvedPath = resolveTestModulePath(fromFilePath, specifier);
|
|
448
|
-
if (resolvedPath === specifier) {
|
|
449
|
-
return require(specifier);
|
|
501
|
+
toMatch(pattern) {
|
|
502
|
+
this.expected = pattern;
|
|
503
|
+
const text = String(this.actual);
|
|
504
|
+
if (pattern instanceof RegExp) {
|
|
505
|
+
this.assertCondition(pattern.test(text), `Expected "${text}" to match ${pattern}`);
|
|
506
|
+
} else {
|
|
507
|
+
this.assertCondition(text.includes(pattern), `Expected "${text}" to contain "${pattern}"`);
|
|
450
508
|
}
|
|
451
|
-
|
|
452
|
-
|
|
509
|
+
}
|
|
510
|
+
toBeInstanceOf(classType) {
|
|
511
|
+
this.expected = classType;
|
|
512
|
+
this.assertCondition(this.actual instanceof classType, `Expected value to be instance of ${classType.name}`);
|
|
513
|
+
}
|
|
514
|
+
toHaveProperty(path, value) {
|
|
515
|
+
const keys = Array.isArray(path) ? path : path.split(".");
|
|
516
|
+
let object = this.actual;
|
|
517
|
+
for (const key of keys) {
|
|
518
|
+
if (object == null || !Object.hasOwnProperty.call(object, key)) {
|
|
519
|
+
throw new Error(`Expected object to have property "${path}"`);
|
|
520
|
+
}
|
|
521
|
+
object = object[key];
|
|
453
522
|
}
|
|
454
|
-
if (
|
|
455
|
-
|
|
523
|
+
if (value !== void 0) {
|
|
524
|
+
this.assertCondition(this.deepEqual(object, value), `Expected property "${path}" to equal ${this.stringify(value)}`);
|
|
456
525
|
}
|
|
457
|
-
return loadTranspiledTestModule(resolvedPath, moduleCache);
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
function loadTranspiledTestModule(modulePath, moduleCache) {
|
|
461
|
-
const cached = moduleCache.get(modulePath);
|
|
462
|
-
if (cached) {
|
|
463
|
-
return cached.exports;
|
|
464
526
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
try {
|
|
468
|
-
transpiled = (0, import_esbuild.transformSync)(source, createTestTransformOptions(modulePath, "cjs", false));
|
|
469
|
-
} catch (error) {
|
|
470
|
-
throw new Error(`Failed to transpile test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
527
|
+
toBeCalled() {
|
|
528
|
+
this.assertCondition(this.actual._isMock && this.actual._calls.length > 0, "Expected mock function to have been called");
|
|
471
529
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
moduleCache.set(modulePath, moduleRecord);
|
|
475
|
-
try {
|
|
476
|
-
const fn = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
477
|
-
const requireFn = createTestModuleRequire(modulePath, moduleCache);
|
|
478
|
-
fn(moduleObj, moduleObj.exports, requireFn, modulePath, dirname(modulePath));
|
|
479
|
-
} catch (error) {
|
|
480
|
-
throw new Error(`Failed to execute test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
530
|
+
toBeCalledTimes(times) {
|
|
531
|
+
this.assertCondition(this.actual._isMock && this.actual._calls.length === times, `Expected mock to be called ${times} times, but was called ${this.actual._calls?.length || 0} times`);
|
|
481
532
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
coveredFiles.add(modulePath);
|
|
533
|
+
toBeCalledWith(...args) {
|
|
534
|
+
this.assertCondition(this.actual._isMock && this.actual._calls.some((call) => this.deepEqual(call, args)), `Expected mock to be called with ${this.stringify(args)}`);
|
|
485
535
|
}
|
|
486
|
-
|
|
536
|
+
lastReturnedWith(value) {
|
|
537
|
+
const lastResult = this.actual._results?.[this.actual._results.length - 1];
|
|
538
|
+
this.assertCondition(lastResult && this.deepEqual(lastResult.value, value), `Expected last call to return ${this.stringify(value)}`);
|
|
539
|
+
}
|
|
540
|
+
deepEqual(left, right) {
|
|
541
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
function expect(actual) {
|
|
545
|
+
return new Expect(actual);
|
|
487
546
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
547
|
+
|
|
548
|
+
// src/test/runtime/hooks.ts
|
|
549
|
+
var beforeAll = (fn) => runtimeState.beforeAllHooks.push(fn);
|
|
550
|
+
var afterAll = (fn) => runtimeState.afterAllHooks.push(fn);
|
|
551
|
+
var beforeEach = (fn) => runtimeState.beforeEachHooks.push(fn);
|
|
552
|
+
var afterEach = (fn) => runtimeState.afterEachHooks.push(fn);
|
|
553
|
+
|
|
554
|
+
// src/test/runtime/mocks.ts
|
|
555
|
+
function createMockFunction() {
|
|
556
|
+
const mock = function(...args) {
|
|
557
|
+
mock._calls.push(args);
|
|
558
|
+
try {
|
|
559
|
+
const result = mock._implementation ? mock._implementation(...args) : void 0;
|
|
560
|
+
mock._results.push({ type: "return", value: result });
|
|
561
|
+
return result;
|
|
562
|
+
} catch (error) {
|
|
563
|
+
mock._results.push({ type: "throw", value: error });
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
mock._isMock = true;
|
|
568
|
+
mock._calls = [];
|
|
569
|
+
mock._results = [];
|
|
570
|
+
mock._implementation = null;
|
|
571
|
+
mock.mockImplementation = function(fn) {
|
|
572
|
+
mock._implementation = fn;
|
|
573
|
+
return mock;
|
|
574
|
+
};
|
|
575
|
+
mock.mockReturnValue = function(value) {
|
|
576
|
+
mock._implementation = (() => value);
|
|
577
|
+
return mock;
|
|
578
|
+
};
|
|
579
|
+
mock.mockResolvedValue = function(value) {
|
|
580
|
+
mock._implementation = (() => Promise.resolve(value));
|
|
581
|
+
return mock;
|
|
582
|
+
};
|
|
583
|
+
mock.mockRejectedValue = function(value) {
|
|
584
|
+
mock._implementation = (() => Promise.reject(value));
|
|
585
|
+
return mock;
|
|
586
|
+
};
|
|
587
|
+
mock.restore = function() {
|
|
588
|
+
mock._calls = [];
|
|
589
|
+
mock._results = [];
|
|
590
|
+
mock._implementation = null;
|
|
591
|
+
};
|
|
592
|
+
mock.clear = function() {
|
|
593
|
+
mock._calls = [];
|
|
594
|
+
mock._results = [];
|
|
595
|
+
};
|
|
596
|
+
return mock;
|
|
499
597
|
}
|
|
598
|
+
var vi = {
|
|
599
|
+
fn: () => createMockFunction(),
|
|
600
|
+
spyOn: (obj, method) => {
|
|
601
|
+
const original = obj[method];
|
|
602
|
+
const mock = createMockFunction();
|
|
603
|
+
mock.mockImplementation(original);
|
|
604
|
+
obj[method] = mock;
|
|
605
|
+
mock.restore = () => {
|
|
606
|
+
obj[method] = original;
|
|
607
|
+
};
|
|
608
|
+
return mock;
|
|
609
|
+
},
|
|
610
|
+
clearAllMocks: () => {
|
|
611
|
+
},
|
|
612
|
+
restoreAllMocks: () => {
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
// src/test/runtime/test-api.ts
|
|
500
617
|
function createTestFunction(defaultTimeout = 5e3) {
|
|
501
618
|
const testFn = function(name, fn, timeout) {
|
|
502
619
|
const test = {
|
|
503
620
|
name,
|
|
504
621
|
fn,
|
|
505
|
-
skip: currentSuite.skip,
|
|
622
|
+
skip: runtimeState.currentSuite.skip,
|
|
506
623
|
only: false,
|
|
507
624
|
todo: false,
|
|
508
625
|
timeout: timeout ?? defaultTimeout,
|
|
509
|
-
suite: currentSuite
|
|
626
|
+
suite: runtimeState.currentSuite
|
|
510
627
|
};
|
|
511
|
-
currentSuite.tests.push(test);
|
|
628
|
+
runtimeState.currentSuite.tests.push(test);
|
|
512
629
|
};
|
|
513
630
|
testFn.skip = (name, fn, timeout) => {
|
|
514
631
|
const test = {
|
|
@@ -518,12 +635,12 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
518
635
|
only: false,
|
|
519
636
|
todo: false,
|
|
520
637
|
timeout: timeout ?? defaultTimeout,
|
|
521
|
-
suite: currentSuite
|
|
638
|
+
suite: runtimeState.currentSuite
|
|
522
639
|
};
|
|
523
|
-
currentSuite.tests.push(test);
|
|
640
|
+
runtimeState.currentSuite.tests.push(test);
|
|
524
641
|
};
|
|
525
642
|
testFn.only = (name, fn, timeout) => {
|
|
526
|
-
hasOnly = true;
|
|
643
|
+
runtimeState.hasOnly = true;
|
|
527
644
|
const test = {
|
|
528
645
|
name,
|
|
529
646
|
fn,
|
|
@@ -531,9 +648,9 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
531
648
|
only: true,
|
|
532
649
|
todo: false,
|
|
533
650
|
timeout: timeout ?? defaultTimeout,
|
|
534
|
-
suite: currentSuite
|
|
651
|
+
suite: runtimeState.currentSuite
|
|
535
652
|
};
|
|
536
|
-
currentSuite.tests.push(test);
|
|
653
|
+
runtimeState.currentSuite.tests.push(test);
|
|
537
654
|
};
|
|
538
655
|
testFn.todo = (name, fn, timeout) => {
|
|
539
656
|
const test = {
|
|
@@ -543,15 +660,15 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
543
660
|
only: false,
|
|
544
661
|
todo: true,
|
|
545
662
|
timeout: timeout ?? defaultTimeout,
|
|
546
|
-
suite: currentSuite
|
|
663
|
+
suite: runtimeState.currentSuite
|
|
547
664
|
};
|
|
548
|
-
currentSuite.tests.push(test);
|
|
665
|
+
runtimeState.currentSuite.tests.push(test);
|
|
549
666
|
};
|
|
550
667
|
return testFn;
|
|
551
668
|
}
|
|
552
669
|
function createDescribeFunction() {
|
|
553
670
|
const describeFn = function(name, fn) {
|
|
554
|
-
const parent = currentSuite;
|
|
671
|
+
const parent = runtimeState.currentSuite;
|
|
555
672
|
const suite = {
|
|
556
673
|
name,
|
|
557
674
|
tests: [],
|
|
@@ -561,12 +678,12 @@ function createDescribeFunction() {
|
|
|
561
678
|
only: parent.only
|
|
562
679
|
};
|
|
563
680
|
parent.suites.push(suite);
|
|
564
|
-
currentSuite = suite;
|
|
681
|
+
runtimeState.currentSuite = suite;
|
|
565
682
|
fn();
|
|
566
|
-
currentSuite = parent;
|
|
683
|
+
runtimeState.currentSuite = parent;
|
|
567
684
|
};
|
|
568
685
|
describeFn.skip = (name, fn) => {
|
|
569
|
-
const parent = currentSuite;
|
|
686
|
+
const parent = runtimeState.currentSuite;
|
|
570
687
|
const suite = {
|
|
571
688
|
name,
|
|
572
689
|
tests: [],
|
|
@@ -576,13 +693,13 @@ function createDescribeFunction() {
|
|
|
576
693
|
only: false
|
|
577
694
|
};
|
|
578
695
|
parent.suites.push(suite);
|
|
579
|
-
currentSuite = suite;
|
|
696
|
+
runtimeState.currentSuite = suite;
|
|
580
697
|
fn();
|
|
581
|
-
currentSuite = parent;
|
|
698
|
+
runtimeState.currentSuite = parent;
|
|
582
699
|
};
|
|
583
700
|
describeFn.only = (name, fn) => {
|
|
584
|
-
hasOnly = true;
|
|
585
|
-
const parent = currentSuite;
|
|
701
|
+
runtimeState.hasOnly = true;
|
|
702
|
+
const parent = runtimeState.currentSuite;
|
|
586
703
|
const suite = {
|
|
587
704
|
name,
|
|
588
705
|
tests: [],
|
|
@@ -592,594 +709,476 @@ function createDescribeFunction() {
|
|
|
592
709
|
only: true
|
|
593
710
|
};
|
|
594
711
|
parent.suites.push(suite);
|
|
595
|
-
currentSuite = suite;
|
|
712
|
+
runtimeState.currentSuite = suite;
|
|
596
713
|
fn();
|
|
597
|
-
currentSuite = parent;
|
|
714
|
+
runtimeState.currentSuite = parent;
|
|
598
715
|
};
|
|
599
716
|
return describeFn;
|
|
600
717
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
718
|
+
|
|
719
|
+
// src/test/runtime/globals.ts
|
|
720
|
+
var globals = {
|
|
721
|
+
describe: createDescribeFunction(),
|
|
722
|
+
it: createTestFunction(5e3),
|
|
723
|
+
test: createTestFunction(5e3),
|
|
724
|
+
expect,
|
|
725
|
+
beforeAll,
|
|
726
|
+
afterAll,
|
|
727
|
+
beforeEach,
|
|
728
|
+
afterEach,
|
|
729
|
+
vi
|
|
730
|
+
};
|
|
731
|
+
function setupGlobals() {
|
|
732
|
+
global.describe = globals.describe;
|
|
733
|
+
global.it = globals.it;
|
|
734
|
+
global.test = globals.test;
|
|
735
|
+
global.expect = globals.expect;
|
|
736
|
+
global.beforeAll = globals.beforeAll;
|
|
737
|
+
global.afterAll = globals.afterAll;
|
|
738
|
+
global.beforeEach = globals.beforeEach;
|
|
739
|
+
global.afterEach = globals.afterEach;
|
|
740
|
+
global.vi = globals.vi;
|
|
741
|
+
}
|
|
742
|
+
function clearGlobals() {
|
|
743
|
+
delete global.describe;
|
|
744
|
+
delete global.it;
|
|
745
|
+
delete global.test;
|
|
746
|
+
delete global.expect;
|
|
747
|
+
delete global.beforeAll;
|
|
748
|
+
delete global.afterAll;
|
|
749
|
+
delete global.beforeEach;
|
|
750
|
+
delete global.afterEach;
|
|
751
|
+
delete global.vi;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// src/test/runtime/transpile.ts
|
|
755
|
+
var import_esbuild = require("esbuild");
|
|
756
|
+
|
|
757
|
+
// src/server/path/platform.ts
|
|
758
|
+
function getSeparator(isWin) {
|
|
759
|
+
return isWin ? "\\" : "/";
|
|
760
|
+
}
|
|
761
|
+
function getCwd() {
|
|
762
|
+
if (isNode || isBun) {
|
|
763
|
+
return process.cwd();
|
|
609
764
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
this._not = new _Expect(this.actual, !this.isNot, false);
|
|
613
|
-
}
|
|
614
|
-
return this._not;
|
|
765
|
+
if (isDeno) {
|
|
766
|
+
return Deno.cwd();
|
|
615
767
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
return
|
|
768
|
+
return "/";
|
|
769
|
+
}
|
|
770
|
+
var isWindows = (() => {
|
|
771
|
+
if (isNode) {
|
|
772
|
+
return process.platform === "win32";
|
|
773
|
+
}
|
|
774
|
+
if (isDeno) {
|
|
775
|
+
return Deno.build.os === "windows";
|
|
776
|
+
}
|
|
777
|
+
return typeof process !== "undefined" && process.platform === "win32";
|
|
778
|
+
})();
|
|
779
|
+
|
|
780
|
+
// src/server/path/operations.ts
|
|
781
|
+
function findLastSeparator(path) {
|
|
782
|
+
return Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
783
|
+
}
|
|
784
|
+
function isAbsolutePosix(path) {
|
|
785
|
+
return path.length > 0 && path[0] === "/";
|
|
786
|
+
}
|
|
787
|
+
function isAbsoluteWin(path) {
|
|
788
|
+
const len = path.length;
|
|
789
|
+
if (len === 0) return false;
|
|
790
|
+
const code = path.charCodeAt(0);
|
|
791
|
+
if (code === 47 || code === 92) {
|
|
792
|
+
return true;
|
|
621
793
|
}
|
|
622
|
-
|
|
623
|
-
if (
|
|
624
|
-
|
|
794
|
+
if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
|
|
795
|
+
if (len > 2 && path.charCodeAt(1) === 58) {
|
|
796
|
+
const code2 = path.charCodeAt(2);
|
|
797
|
+
if (code2 === 47 || code2 === 92) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
625
800
|
}
|
|
626
|
-
return this._rejects;
|
|
627
801
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
802
|
+
return false;
|
|
803
|
+
}
|
|
804
|
+
function normalizePath(path, isWin) {
|
|
805
|
+
if (path.length === 0) return ".";
|
|
806
|
+
const separator = getSeparator(isWin);
|
|
807
|
+
const isAbsolute = isWin ? isAbsoluteWin(path) : isAbsolutePosix(path);
|
|
808
|
+
const trailingSeparator = path[path.length - 1] === separator || isWin && path[path.length - 1] === "/";
|
|
809
|
+
const normalized = path.replace(isWin ? /[\/\\]+/g : /\/+/g, separator);
|
|
810
|
+
const parts = normalized.split(separator);
|
|
811
|
+
const result = [];
|
|
812
|
+
for (let index = 0; index < parts.length; index++) {
|
|
813
|
+
const part = parts[index];
|
|
814
|
+
if (part === "" || part === ".") {
|
|
815
|
+
if (index === 0 && isAbsolute) result.push("");
|
|
816
|
+
continue;
|
|
631
817
|
}
|
|
632
|
-
if (
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
errorMsg += `
|
|
637
|
-
Expected: ${expectedValue}
|
|
638
|
-
Received: ${this.stringify(this.actual)}`;
|
|
639
|
-
}
|
|
640
|
-
const stack = callerStack || new Error().stack;
|
|
641
|
-
let lineNumber = void 0;
|
|
642
|
-
let codeSnippet = void 0;
|
|
643
|
-
let assertionMethod = void 0;
|
|
644
|
-
if (stack) {
|
|
645
|
-
const assertionMatch = stack.match(/at _Expect\.(\w+)/);
|
|
646
|
-
if (assertionMatch) {
|
|
647
|
-
assertionMethod = assertionMatch[1];
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
if (stack) {
|
|
651
|
-
const lines = stack.split("\n");
|
|
652
|
-
const stackFrames = [];
|
|
653
|
-
for (const line of lines) {
|
|
654
|
-
const match = line.match(/<anonymous>:([0-9]+):([0-9]+)/);
|
|
655
|
-
if (match) {
|
|
656
|
-
stackFrames.push({
|
|
657
|
-
line: parseInt(match[1], 10),
|
|
658
|
-
column: parseInt(match[2], 10)
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
const targetFrame = stackFrames.length > 1 ? stackFrames[1] : stackFrames[0];
|
|
663
|
-
if (targetFrame && currentSourceMapConsumer) {
|
|
664
|
-
try {
|
|
665
|
-
const transpiledLine = targetFrame.line - wrapperLineOffset;
|
|
666
|
-
const originalPosition = currentSourceMapConsumer.originalPositionFor({
|
|
667
|
-
line: transpiledLine,
|
|
668
|
-
column: targetFrame.column
|
|
669
|
-
});
|
|
670
|
-
if (originalPosition.line !== null) {
|
|
671
|
-
lineNumber = originalPosition.line;
|
|
672
|
-
if (currentTestFile) {
|
|
673
|
-
try {
|
|
674
|
-
let sourceCode = readFileSync(currentTestFile, "utf-8");
|
|
675
|
-
if (Buffer.isBuffer(sourceCode)) {
|
|
676
|
-
sourceCode = sourceCode.toString("utf-8");
|
|
677
|
-
}
|
|
678
|
-
const sourceLines = sourceCode.split("\n");
|
|
679
|
-
let targetPattern = ".toBe(";
|
|
680
|
-
if (assertionMethod === "toEqual") targetPattern = ".toEqual(";
|
|
681
|
-
else if (assertionMethod === "toStrictEqual") targetPattern = ".toStrictEqual(";
|
|
682
|
-
else if (assertionMethod === "toMatch") targetPattern = ".toMatch(";
|
|
683
|
-
else if (assertionMethod === "toContain") targetPattern = ".toContain(";
|
|
684
|
-
else if (assertionMethod === "toHaveLength") targetPattern = ".toHaveLength(";
|
|
685
|
-
else if (assertionMethod === "toBeDefined") targetPattern = ".toBeDefined(";
|
|
686
|
-
else if (assertionMethod === "toBeNull") targetPattern = ".toBeNull(";
|
|
687
|
-
else if (assertionMethod === "toBeUndefined") targetPattern = ".toBeUndefined(";
|
|
688
|
-
else if (assertionMethod === "toBeTruthy") targetPattern = ".toBeTruthy(";
|
|
689
|
-
else if (assertionMethod === "toBeFalsy") targetPattern = ".toBeFalsy(";
|
|
690
|
-
else if (assertionMethod === "toThrow") targetPattern = ".toThrow(";
|
|
691
|
-
else if (assertionMethod === "toBeGreaterThan") targetPattern = ".toBeGreaterThan(";
|
|
692
|
-
else if (assertionMethod === "toBeGreaterThanOrEqual") targetPattern = ".toBeGreaterThanOrEqual(";
|
|
693
|
-
else if (assertionMethod === "toBeLessThan") targetPattern = ".toBeLessThan(";
|
|
694
|
-
else if (assertionMethod === "toBeLessThanOrEqual") targetPattern = ".toBeLessThanOrEqual(";
|
|
695
|
-
if (lineNumber > 0 && lineNumber <= sourceLines.length) {
|
|
696
|
-
const mappedLine = sourceLines[lineNumber - 1];
|
|
697
|
-
const hasMatchingAssertion = mappedLine.includes(targetPattern);
|
|
698
|
-
if (!hasMatchingAssertion) {
|
|
699
|
-
for (let i = 1; i <= 3; i++) {
|
|
700
|
-
const searchLine = lineNumber - i;
|
|
701
|
-
if (searchLine > 0 && searchLine <= sourceLines.length) {
|
|
702
|
-
const testLine = sourceLines[searchLine - 1];
|
|
703
|
-
if (testLine.includes(targetPattern)) {
|
|
704
|
-
lineNumber = searchLine;
|
|
705
|
-
break;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
} catch (e) {
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
} else {
|
|
715
|
-
const posWithoutColumn = currentSourceMapConsumer.originalPositionFor({
|
|
716
|
-
line: transpiledLine,
|
|
717
|
-
column: 0
|
|
718
|
-
});
|
|
719
|
-
if (posWithoutColumn.line !== null) {
|
|
720
|
-
lineNumber = posWithoutColumn.line;
|
|
721
|
-
} else {
|
|
722
|
-
const lineMappings = [];
|
|
723
|
-
currentSourceMapConsumer.eachMapping((mapping) => {
|
|
724
|
-
if (mapping.originalLine !== null) {
|
|
725
|
-
const distance = Math.abs(mapping.generatedLine - transpiledLine);
|
|
726
|
-
lineMappings.push({
|
|
727
|
-
line: mapping.originalLine,
|
|
728
|
-
distance
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
});
|
|
732
|
-
if (lineMappings.length > 0) {
|
|
733
|
-
lineMappings.sort((a, b) => a.distance - b.distance);
|
|
734
|
-
lineNumber = lineMappings[0].line;
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
} catch (e) {
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
if (currentTestFile && lineNumber) {
|
|
742
|
-
try {
|
|
743
|
-
let sourceCode = readFileSync(currentTestFile, "utf-8");
|
|
744
|
-
if (Buffer.isBuffer(sourceCode)) {
|
|
745
|
-
sourceCode = sourceCode.toString("utf-8");
|
|
746
|
-
}
|
|
747
|
-
const sourceLines = sourceCode.split("\n");
|
|
748
|
-
if (lineNumber > 0 && lineNumber <= sourceLines.length) {
|
|
749
|
-
const codeLine = sourceLines[lineNumber - 1];
|
|
750
|
-
if (codeLine) {
|
|
751
|
-
codeSnippet = codeLine.trim();
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
} catch (e) {
|
|
755
|
-
}
|
|
818
|
+
if (part === "..") {
|
|
819
|
+
if (result.length > 0 && result[result.length - 1] !== "..") {
|
|
820
|
+
if (!(result.length === 1 && result[0] === "")) {
|
|
821
|
+
result.pop();
|
|
756
822
|
}
|
|
823
|
+
} else if (!isAbsolute) {
|
|
824
|
+
result.push("..");
|
|
757
825
|
}
|
|
758
|
-
|
|
826
|
+
} else {
|
|
827
|
+
result.push(part);
|
|
759
828
|
}
|
|
760
829
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (typeof value === "string") return `"${value}"`;
|
|
765
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
766
|
-
if (typeof value === "function") return "Function";
|
|
767
|
-
if (Array.isArray(value)) return `[${value.map((v) => this.stringify(v)).join(", ")}]`;
|
|
768
|
-
if (typeof value === "object") {
|
|
769
|
-
const keys = Object.keys(value);
|
|
770
|
-
if (keys.length === 0) return "{}";
|
|
771
|
-
return `{ ${keys.slice(0, 3).map((k) => `${k}: ${this.stringify(value[k])}`).join(", ")}${keys.length > 3 ? "..." : ""} }`;
|
|
772
|
-
}
|
|
773
|
-
return String(value);
|
|
830
|
+
let finalPath = result.join(separator);
|
|
831
|
+
if (finalPath.length === 0) {
|
|
832
|
+
return isAbsolute ? separator : ".";
|
|
774
833
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
if (
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
);
|
|
792
|
-
} else if (value instanceof RegExp) {
|
|
793
|
-
this.assertCondition(
|
|
794
|
-
value.test(error.message),
|
|
795
|
-
`Expected error message to match ${value}`
|
|
796
|
-
);
|
|
834
|
+
if (trailingSeparator && finalPath[finalPath.length - 1] !== separator) {
|
|
835
|
+
finalPath += separator;
|
|
836
|
+
}
|
|
837
|
+
return finalPath;
|
|
838
|
+
}
|
|
839
|
+
function joinPaths(paths, isWin) {
|
|
840
|
+
if (paths.length === 0) return ".";
|
|
841
|
+
const separator = getSeparator(isWin);
|
|
842
|
+
let joined = "";
|
|
843
|
+
for (let index = 0; index < paths.length; index++) {
|
|
844
|
+
const path = paths[index];
|
|
845
|
+
if (path && path.length > 0) {
|
|
846
|
+
if (joined.length === 0) {
|
|
847
|
+
joined = path;
|
|
848
|
+
} else {
|
|
849
|
+
joined += separator + path;
|
|
797
850
|
}
|
|
798
|
-
return Promise.resolve(void 0);
|
|
799
851
|
}
|
|
800
852
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
this.assertCondition(this.actual === value, `Expected values to be strictly equal (using ===)`, true, void 0, stack);
|
|
814
|
-
if (typeof this.actual !== typeof value) {
|
|
815
|
-
throw new Error(`Types don't match: expected ${typeof value} but got ${typeof this.actual}`);
|
|
853
|
+
if (joined.length === 0) return ".";
|
|
854
|
+
return normalizePath(joined, isWin);
|
|
855
|
+
}
|
|
856
|
+
function resolvePaths(paths, isWin) {
|
|
857
|
+
const separator = getSeparator(isWin);
|
|
858
|
+
let resolved = "";
|
|
859
|
+
let absolute = false;
|
|
860
|
+
for (let index = paths.length - 1; index >= 0 && !absolute; index--) {
|
|
861
|
+
const path = paths[index];
|
|
862
|
+
if (path && path.length > 0) {
|
|
863
|
+
resolved = path + (resolved.length > 0 ? separator + resolved : "");
|
|
864
|
+
absolute = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);
|
|
816
865
|
}
|
|
817
866
|
}
|
|
818
|
-
|
|
819
|
-
const
|
|
820
|
-
|
|
821
|
-
const isEqual = (a, b) => {
|
|
822
|
-
if (a === b) return true;
|
|
823
|
-
if (a == null || b == null) return a === b;
|
|
824
|
-
if (typeof a !== typeof b) return false;
|
|
825
|
-
if (typeof a !== "object") return a === b;
|
|
826
|
-
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
827
|
-
if (Array.isArray(a)) {
|
|
828
|
-
if (a.length !== b.length) return false;
|
|
829
|
-
return a.every((item, i) => isEqual(item, b[i]));
|
|
830
|
-
}
|
|
831
|
-
const keysA = Object.keys(a);
|
|
832
|
-
const keysB = Object.keys(b);
|
|
833
|
-
if (keysA.length !== keysB.length) return false;
|
|
834
|
-
return keysA.every((key) => isEqual(a[key], b[key]));
|
|
835
|
-
};
|
|
836
|
-
this.assertCondition(isEqual(this.actual, value), "Expected values to be deeply equal", false, void 0, stack);
|
|
837
|
-
}
|
|
838
|
-
toBeTruthy() {
|
|
839
|
-
const stack = new Error().stack;
|
|
840
|
-
this.assertCondition(!!this.actual, `Expected value to be truthy`, false, void 0, stack);
|
|
841
|
-
}
|
|
842
|
-
toBeFalsy() {
|
|
843
|
-
const stack = new Error().stack;
|
|
844
|
-
this.assertCondition(!this.actual, `Expected value to be falsy`, false, void 0, stack);
|
|
845
|
-
}
|
|
846
|
-
toBeNull() {
|
|
847
|
-
const stack = new Error().stack;
|
|
848
|
-
this.assertCondition(this.actual === null, `Expected value to be null`, false, void 0, stack);
|
|
867
|
+
if (!absolute) {
|
|
868
|
+
const cwd = getCwd();
|
|
869
|
+
resolved = cwd + (resolved.length > 0 ? separator + resolved : "");
|
|
849
870
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
871
|
+
return normalizePath(resolved, isWin);
|
|
872
|
+
}
|
|
873
|
+
function relativePath(from, to, isWin) {
|
|
874
|
+
const resolvedFrom = resolvePaths([from], isWin);
|
|
875
|
+
const resolvedTo = resolvePaths([to], isWin);
|
|
876
|
+
if (resolvedFrom === resolvedTo) return "";
|
|
877
|
+
const separator = getSeparator(isWin);
|
|
878
|
+
const fromParts = resolvedFrom.split(separator).filter((part) => part.length > 0);
|
|
879
|
+
const toParts = resolvedTo.split(separator).filter((part) => part.length > 0);
|
|
880
|
+
const minLength = Math.min(fromParts.length, toParts.length);
|
|
881
|
+
let commonLength = 0;
|
|
882
|
+
for (let index = 0; index < minLength; index++) {
|
|
883
|
+
if (fromParts[index] === toParts[index]) {
|
|
884
|
+
commonLength++;
|
|
885
|
+
} else {
|
|
886
|
+
break;
|
|
887
|
+
}
|
|
853
888
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
889
|
+
const result = [];
|
|
890
|
+
const upCount = fromParts.length - commonLength;
|
|
891
|
+
for (let index = 0; index < upCount; index++) {
|
|
892
|
+
result.push("..");
|
|
857
893
|
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
this.expected = value;
|
|
861
|
-
this.assertCondition(
|
|
862
|
-
typeof this.actual === "number" && this.actual > value,
|
|
863
|
-
`Expected ${this.stringify(this.actual)} to be greater than ${value}`,
|
|
864
|
-
true,
|
|
865
|
-
String(value),
|
|
866
|
-
stack
|
|
867
|
-
);
|
|
894
|
+
for (let index = commonLength; index < toParts.length; index++) {
|
|
895
|
+
result.push(toParts[index]);
|
|
868
896
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
897
|
+
return result.join(separator) || ".";
|
|
898
|
+
}
|
|
899
|
+
function getDirname(path, isWin) {
|
|
900
|
+
if (path.length === 0) return ".";
|
|
901
|
+
const separator = getSeparator(isWin);
|
|
902
|
+
const normalized = normalizePath(path, isWin);
|
|
903
|
+
const lastSeparatorIndex = normalized.lastIndexOf(separator);
|
|
904
|
+
if (lastSeparatorIndex === -1) return ".";
|
|
905
|
+
if (lastSeparatorIndex === 0) return separator;
|
|
906
|
+
return normalized.slice(0, lastSeparatorIndex);
|
|
907
|
+
}
|
|
908
|
+
function getBasename(path, ext, isWin) {
|
|
909
|
+
if (path.length === 0) return "";
|
|
910
|
+
const lastSeparatorIndex = isWin ? findLastSeparator(path) : path.lastIndexOf("/");
|
|
911
|
+
let base = lastSeparatorIndex === -1 ? path : path.slice(lastSeparatorIndex + 1);
|
|
912
|
+
if (ext && base.endsWith(ext)) {
|
|
913
|
+
base = base.slice(0, base.length - ext.length);
|
|
879
914
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
String(value),
|
|
888
|
-
stack
|
|
889
|
-
);
|
|
915
|
+
return base;
|
|
916
|
+
}
|
|
917
|
+
function getExtname(path) {
|
|
918
|
+
const lastDotIndex = path.lastIndexOf(".");
|
|
919
|
+
const lastSeparatorIndex = findLastSeparator(path);
|
|
920
|
+
if (lastDotIndex === -1 || lastDotIndex < lastSeparatorIndex || lastDotIndex === path.length - 1) {
|
|
921
|
+
return "";
|
|
890
922
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
923
|
+
return path.slice(lastDotIndex);
|
|
924
|
+
}
|
|
925
|
+
function parsePath(path, isWin) {
|
|
926
|
+
let root = "";
|
|
927
|
+
if (isWin) {
|
|
928
|
+
if (path.length >= 2 && path[1] === ":") {
|
|
929
|
+
root = path.slice(0, 2);
|
|
930
|
+
if (path.length > 2 && (path[2] === "\\" || path[2] === "/")) {
|
|
931
|
+
root += "\\";
|
|
932
|
+
}
|
|
933
|
+
} else if (path[0] === "\\" || path[0] === "/") {
|
|
934
|
+
root = "\\";
|
|
935
|
+
}
|
|
936
|
+
} else if (path[0] === "/") {
|
|
937
|
+
root = "/";
|
|
901
938
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
939
|
+
const dir = getDirname(path, isWin);
|
|
940
|
+
const base = getBasename(path, void 0, isWin);
|
|
941
|
+
const ext = getExtname(path);
|
|
942
|
+
const name = ext ? base.slice(0, base.length - ext.length) : base;
|
|
943
|
+
return { root, dir, base, ext, name };
|
|
944
|
+
}
|
|
945
|
+
function formatPath(pathObject, isWin) {
|
|
946
|
+
const separator = getSeparator(isWin);
|
|
947
|
+
const dir = pathObject.dir || pathObject.root || "";
|
|
948
|
+
const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
949
|
+
if (!dir) return base;
|
|
950
|
+
if (dir === pathObject.root) return dir + base;
|
|
951
|
+
return dir + separator + base;
|
|
952
|
+
}
|
|
953
|
+
function createPathOps(isWin) {
|
|
954
|
+
return {
|
|
955
|
+
sep: getSeparator(isWin),
|
|
956
|
+
delimiter: isWin ? ";" : ":",
|
|
957
|
+
normalize: (path) => normalizePath(path, isWin),
|
|
958
|
+
join: (...paths) => joinPaths(paths, isWin),
|
|
959
|
+
resolve: (...paths) => resolvePaths(paths, isWin),
|
|
960
|
+
isAbsolute: (path) => isWin ? isAbsoluteWin(path) : isAbsolutePosix(path),
|
|
961
|
+
relative: (from, to) => relativePath(from, to, isWin),
|
|
962
|
+
dirname: (path) => getDirname(path, isWin),
|
|
963
|
+
basename: (path, ext) => getBasename(path, ext, isWin),
|
|
964
|
+
extname: (path) => getExtname(path),
|
|
965
|
+
parse: (path) => parsePath(path, isWin),
|
|
966
|
+
format: (pathObject) => formatPath(pathObject, isWin)
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/server/path/index.ts
|
|
971
|
+
var posix = createPathOps(false);
|
|
972
|
+
var win32 = createPathOps(true);
|
|
973
|
+
function dirname(path) {
|
|
974
|
+
return getDirname(path, isWindows);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// src/test/runtime/transpile.ts
|
|
978
|
+
var TEST_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
979
|
+
function resolveTestLoader(filePath) {
|
|
980
|
+
return /\.(?:ts|tsx|mts|cts)$/i.test(filePath) ? "ts" : "js";
|
|
981
|
+
}
|
|
982
|
+
function createTestTransformOptions(filePath, format, sourcemap) {
|
|
983
|
+
return {
|
|
984
|
+
loader: resolveTestLoader(filePath),
|
|
985
|
+
format,
|
|
986
|
+
sourcemap,
|
|
987
|
+
sourcefile: filePath,
|
|
988
|
+
target: "es2020",
|
|
989
|
+
tsconfigRaw: {
|
|
990
|
+
compilerOptions: {
|
|
991
|
+
jsx: "react",
|
|
992
|
+
jsxFactory: "h",
|
|
993
|
+
jsxFragmentFactory: "Fragment"
|
|
994
|
+
}
|
|
923
995
|
}
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
function extractInlineSourceMap(code) {
|
|
999
|
+
const sourceMapMatch = code.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/);
|
|
1000
|
+
if (!sourceMapMatch) {
|
|
1001
|
+
return void 0;
|
|
924
1002
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
false,
|
|
933
|
-
void 0,
|
|
934
|
-
stack
|
|
935
|
-
);
|
|
1003
|
+
const json = Buffer.from(sourceMapMatch[1], "base64").toString("utf-8");
|
|
1004
|
+
return JSON.parse(json);
|
|
1005
|
+
}
|
|
1006
|
+
function resolveExistingTestModulePath(basePath) {
|
|
1007
|
+
const nodePath = require("path");
|
|
1008
|
+
if (existsSync(basePath) && statSync(basePath).isFile()) {
|
|
1009
|
+
return basePath;
|
|
936
1010
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1011
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
1012
|
+
const candidatePath = `${basePath}${extension}`;
|
|
1013
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
1014
|
+
return candidatePath;
|
|
941
1015
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1016
|
+
}
|
|
1017
|
+
if (existsSync(basePath) && statSync(basePath).isDirectory()) {
|
|
1018
|
+
const packageJsonPath = nodePath.join(basePath, "package.json");
|
|
1019
|
+
if (existsSync(packageJsonPath) && statSync(packageJsonPath).isFile()) {
|
|
1020
|
+
try {
|
|
1021
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
1022
|
+
for (const candidateEntry of [packageJson.main, packageJson.module]) {
|
|
1023
|
+
if (typeof candidateEntry !== "string" || candidateEntry.trim().length === 0) {
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
try {
|
|
1027
|
+
return resolveExistingTestModulePath(nodePath.resolve(basePath, candidateEntry));
|
|
1028
|
+
} catch {
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
} catch {
|
|
947
1033
|
}
|
|
948
|
-
} catch (e) {
|
|
949
|
-
threw = true;
|
|
950
|
-
thrownError = e;
|
|
951
1034
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
if (
|
|
955
|
-
|
|
956
|
-
thrownError.message.includes(error),
|
|
957
|
-
`Expected error message to include "${error}"`
|
|
958
|
-
);
|
|
959
|
-
} else if (error instanceof RegExp) {
|
|
960
|
-
this.assertCondition(
|
|
961
|
-
error.test(thrownError.message),
|
|
962
|
-
`Expected error message to match ${error}`
|
|
963
|
-
);
|
|
1035
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
1036
|
+
const candidatePath = nodePath.join(basePath, `index${extension}`);
|
|
1037
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
1038
|
+
return candidatePath;
|
|
964
1039
|
}
|
|
965
1040
|
}
|
|
966
1041
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
pattern.test(str),
|
|
973
|
-
`Expected "${str}" to match ${pattern}`
|
|
974
|
-
);
|
|
975
|
-
} else {
|
|
976
|
-
this.assertCondition(
|
|
977
|
-
str.includes(pattern),
|
|
978
|
-
`Expected "${str}" to contain "${pattern}"`
|
|
979
|
-
);
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
toBeInstanceOf(classType) {
|
|
983
|
-
this.expected = classType;
|
|
984
|
-
this.assertCondition(
|
|
985
|
-
this.actual instanceof classType,
|
|
986
|
-
`Expected value to be instance of ${classType.name}`
|
|
987
|
-
);
|
|
1042
|
+
return basePath;
|
|
1043
|
+
}
|
|
1044
|
+
function resolveTestModulePath(fromFilePath, specifier) {
|
|
1045
|
+
if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
|
|
1046
|
+
return specifier;
|
|
988
1047
|
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1048
|
+
const nodePath = require("path");
|
|
1049
|
+
const basePath = specifier.startsWith(".") ? nodePath.resolve(dirname(fromFilePath), specifier) : specifier;
|
|
1050
|
+
return resolveExistingTestModulePath(basePath);
|
|
1051
|
+
}
|
|
1052
|
+
function shouldTranspileTestModule(filePath) {
|
|
1053
|
+
return /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(filePath);
|
|
1054
|
+
}
|
|
1055
|
+
function createTestModuleRequire(fromFilePath, moduleCache) {
|
|
1056
|
+
return (specifier) => {
|
|
1057
|
+
if (specifier.startsWith("elit/") || specifier === "elit") {
|
|
1058
|
+
return require(specifier);
|
|
997
1059
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
`Expected property "${path}" to equal ${this.stringify(value)}`
|
|
1002
|
-
);
|
|
1060
|
+
const resolvedPath = resolveTestModulePath(fromFilePath, specifier);
|
|
1061
|
+
if (resolvedPath === specifier) {
|
|
1062
|
+
return require(specifier);
|
|
1003
1063
|
}
|
|
1064
|
+
if (!existsSync(resolvedPath) || !statSync(resolvedPath).isFile()) {
|
|
1065
|
+
return require(resolvedPath);
|
|
1066
|
+
}
|
|
1067
|
+
if (!shouldTranspileTestModule(resolvedPath)) {
|
|
1068
|
+
return require(resolvedPath);
|
|
1069
|
+
}
|
|
1070
|
+
return loadTranspiledTestModule(resolvedPath, moduleCache);
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
function loadTranspiledTestModule(modulePath, moduleCache) {
|
|
1074
|
+
const cached = moduleCache.get(modulePath);
|
|
1075
|
+
if (cached) {
|
|
1076
|
+
return cached.exports;
|
|
1004
1077
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
);
|
|
1011
|
-
}
|
|
1012
|
-
toBeCalledTimes(times) {
|
|
1013
|
-
this.assertCondition(
|
|
1014
|
-
this.actual._isMock && this.actual._calls.length === times,
|
|
1015
|
-
`Expected mock to be called ${times} times, but was called ${this.actual._calls?.length || 0} times`
|
|
1016
|
-
);
|
|
1017
|
-
}
|
|
1018
|
-
toBeCalledWith(...args) {
|
|
1019
|
-
this.assertCondition(this.actual._isMock && this.actual._calls.some((call) => this.deepEqual(call, args)), `Expected mock to be called with ${this.stringify(args)}`);
|
|
1078
|
+
const source = readFileSync(modulePath, "utf-8");
|
|
1079
|
+
let transpiled;
|
|
1080
|
+
try {
|
|
1081
|
+
transpiled = (0, import_esbuild.transformSync)(source, createTestTransformOptions(modulePath, "cjs", false));
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
throw new Error(`Failed to transpile test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1020
1084
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
);
|
|
1085
|
+
const moduleRecord = { exports: {} };
|
|
1086
|
+
const moduleObject = { exports: moduleRecord.exports };
|
|
1087
|
+
moduleCache.set(modulePath, moduleRecord);
|
|
1088
|
+
try {
|
|
1089
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
1090
|
+
const requireFn = createTestModuleRequire(modulePath, moduleCache);
|
|
1091
|
+
fn(moduleObject, moduleObject.exports, requireFn, modulePath, dirname(modulePath));
|
|
1092
|
+
} catch (error) {
|
|
1093
|
+
throw new Error(`Failed to execute test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1027
1094
|
}
|
|
1028
|
-
|
|
1029
|
-
|
|
1095
|
+
moduleRecord.exports = moduleObject.exports;
|
|
1096
|
+
if (!modulePath.includes(".test.") && !modulePath.includes(".spec.")) {
|
|
1097
|
+
runtimeState.coveredFiles.add(modulePath);
|
|
1030
1098
|
}
|
|
1031
|
-
|
|
1032
|
-
function expect(actual) {
|
|
1033
|
-
return new Expect(actual);
|
|
1099
|
+
return moduleRecord.exports;
|
|
1034
1100
|
}
|
|
1035
|
-
function
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
return result;
|
|
1042
|
-
} catch (error) {
|
|
1043
|
-
mock._results.push({ type: "throw", value: error });
|
|
1044
|
-
throw error;
|
|
1045
|
-
}
|
|
1046
|
-
};
|
|
1047
|
-
mock._isMock = true;
|
|
1048
|
-
mock._calls = [];
|
|
1049
|
-
mock._results = [];
|
|
1050
|
-
mock._implementation = null;
|
|
1051
|
-
mock.mockImplementation = function(fn) {
|
|
1052
|
-
mock._implementation = fn;
|
|
1053
|
-
return mock;
|
|
1054
|
-
};
|
|
1055
|
-
mock.mockReturnValue = function(value) {
|
|
1056
|
-
mock._implementation = (() => value);
|
|
1057
|
-
return mock;
|
|
1058
|
-
};
|
|
1059
|
-
mock.mockResolvedValue = function(value) {
|
|
1060
|
-
mock._implementation = (() => Promise.resolve(value));
|
|
1061
|
-
return mock;
|
|
1062
|
-
};
|
|
1063
|
-
mock.mockRejectedValue = function(value) {
|
|
1064
|
-
mock._implementation = (() => Promise.reject(value));
|
|
1065
|
-
return mock;
|
|
1066
|
-
};
|
|
1067
|
-
mock.restore = function() {
|
|
1068
|
-
mock._calls = [];
|
|
1069
|
-
mock._results = [];
|
|
1070
|
-
mock._implementation = null;
|
|
1071
|
-
};
|
|
1072
|
-
mock.clear = function() {
|
|
1073
|
-
mock._calls = [];
|
|
1074
|
-
mock._results = [];
|
|
1101
|
+
async function transpileFile(filePath) {
|
|
1102
|
+
const source = await readFile(filePath, "utf-8");
|
|
1103
|
+
const result = (0, import_esbuild.transformSync)(source, createTestTransformOptions(filePath, "esm", "inline"));
|
|
1104
|
+
return {
|
|
1105
|
+
code: result.code,
|
|
1106
|
+
sourceMap: extractInlineSourceMap(result.code)
|
|
1075
1107
|
};
|
|
1076
|
-
return mock;
|
|
1077
1108
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
},
|
|
1090
|
-
clearAllMocks: () => {
|
|
1091
|
-
},
|
|
1092
|
-
restoreAllMocks: () => {
|
|
1109
|
+
|
|
1110
|
+
// src/test/runtime/runner.ts
|
|
1111
|
+
var import_esbuild2 = require("esbuild");
|
|
1112
|
+
var import_source_map = require("source-map");
|
|
1113
|
+
function escapeRegex(str) {
|
|
1114
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1115
|
+
}
|
|
1116
|
+
function destroyCurrentSourceMapConsumer() {
|
|
1117
|
+
if (runtimeState.currentSourceMapConsumer) {
|
|
1118
|
+
runtimeState.currentSourceMapConsumer.destroy();
|
|
1119
|
+
runtimeState.currentSourceMapConsumer = void 0;
|
|
1093
1120
|
}
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1121
|
+
}
|
|
1122
|
+
function suiteOrDescendantMatches(suite) {
|
|
1123
|
+
if (!runtimeState.describePattern) {
|
|
1124
|
+
return true;
|
|
1125
|
+
}
|
|
1126
|
+
const regex = new RegExp(escapeRegex(runtimeState.describePattern), "i");
|
|
1127
|
+
if (regex.test(suite.name)) {
|
|
1128
|
+
return true;
|
|
1129
|
+
}
|
|
1130
|
+
for (const child of suite.suites) {
|
|
1131
|
+
if (suiteOrDescendantMatches(child)) {
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1103
1137
|
async function runTests(options) {
|
|
1104
|
-
const { files, timeout = 5e3, bail = false, describePattern
|
|
1105
|
-
describePattern =
|
|
1106
|
-
testPattern =
|
|
1107
|
-
testResults.length = 0;
|
|
1108
|
-
hasOnly = false;
|
|
1138
|
+
const { files, timeout = 5e3, bail = false, describePattern, testPattern } = options;
|
|
1139
|
+
runtimeState.describePattern = describePattern;
|
|
1140
|
+
runtimeState.testPattern = testPattern;
|
|
1141
|
+
runtimeState.testResults.length = 0;
|
|
1109
1142
|
for (const file of files) {
|
|
1110
|
-
|
|
1143
|
+
resetSuiteState();
|
|
1144
|
+
resetHookState();
|
|
1145
|
+
resetSourceMapState();
|
|
1146
|
+
runtimeState.currentTestFile = file;
|
|
1111
1147
|
try {
|
|
1112
1148
|
const source = await readFile(file, "utf-8");
|
|
1113
1149
|
const testFileDir = dirname(file);
|
|
1114
|
-
const result = (0,
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
const base64 = sourceMapMatch[1];
|
|
1119
|
-
const json = Buffer.from(base64, "base64").toString("utf-8");
|
|
1120
|
-
const sourceMap = JSON.parse(json);
|
|
1121
|
-
currentSourceMapConsumer = await new import_source_map.SourceMapConsumer(sourceMap);
|
|
1122
|
-
} else {
|
|
1123
|
-
currentSourceMapConsumer = void 0;
|
|
1124
|
-
}
|
|
1125
|
-
wrapperLineOffset = 0;
|
|
1150
|
+
const result = (0, import_esbuild2.transformSync)(source, createTestTransformOptions(file, "cjs", "inline"));
|
|
1151
|
+
const sourceMap = extractInlineSourceMap(result.code);
|
|
1152
|
+
runtimeState.currentSourceMapConsumer = sourceMap ? await new import_source_map.SourceMapConsumer(sourceMap) : void 0;
|
|
1153
|
+
runtimeState.wrapperLineOffset = 0;
|
|
1126
1154
|
setupGlobals();
|
|
1127
1155
|
const moduleCache = /* @__PURE__ */ new Map();
|
|
1128
1156
|
const moduleRecord = { exports: {} };
|
|
1129
|
-
const
|
|
1157
|
+
const moduleObject = { exports: moduleRecord.exports };
|
|
1130
1158
|
moduleCache.set(file, moduleRecord);
|
|
1131
|
-
const fn = new Function("module", "exports", "require", "__filename", "__dirname", code);
|
|
1159
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", result.code);
|
|
1132
1160
|
const requireFn = createTestModuleRequire(file, moduleCache);
|
|
1133
|
-
await fn(
|
|
1134
|
-
await executeSuite(currentSuite, timeout, bail);
|
|
1135
|
-
if (currentSourceMapConsumer) {
|
|
1136
|
-
currentSourceMapConsumer.destroy();
|
|
1137
|
-
currentSourceMapConsumer = void 0;
|
|
1138
|
-
}
|
|
1139
|
-
currentSuite = {
|
|
1140
|
-
name: "root",
|
|
1141
|
-
tests: [],
|
|
1142
|
-
suites: [],
|
|
1143
|
-
skip: false,
|
|
1144
|
-
only: false
|
|
1145
|
-
};
|
|
1146
|
-
hasOnly = false;
|
|
1147
|
-
beforeAllHooks = [];
|
|
1148
|
-
afterAllHooks = [];
|
|
1149
|
-
beforeEachHooks = [];
|
|
1150
|
-
afterEachHooks = [];
|
|
1161
|
+
await fn(moduleObject, moduleObject.exports, requireFn, file, testFileDir);
|
|
1162
|
+
await executeSuite(runtimeState.currentSuite, timeout, bail);
|
|
1151
1163
|
} catch (error) {
|
|
1152
|
-
if (currentSourceMapConsumer) {
|
|
1153
|
-
currentSourceMapConsumer.destroy();
|
|
1154
|
-
currentSourceMapConsumer = void 0;
|
|
1155
|
-
}
|
|
1156
1164
|
console.error(`Error loading test file ${file}:`, error);
|
|
1165
|
+
} finally {
|
|
1166
|
+
destroyCurrentSourceMapConsumer();
|
|
1157
1167
|
}
|
|
1158
1168
|
}
|
|
1159
|
-
const passed = testResults.filter((
|
|
1160
|
-
const failed = testResults.filter((
|
|
1161
|
-
const skipped = testResults.filter((
|
|
1162
|
-
const todo = testResults.filter((
|
|
1163
|
-
return { passed, failed, skipped, todo, results: testResults };
|
|
1169
|
+
const passed = runtimeState.testResults.filter((result) => result.status === "pass").length;
|
|
1170
|
+
const failed = runtimeState.testResults.filter((result) => result.status === "fail").length;
|
|
1171
|
+
const skipped = runtimeState.testResults.filter((result) => result.status === "skip").length;
|
|
1172
|
+
const todo = runtimeState.testResults.filter((result) => result.status === "todo").length;
|
|
1173
|
+
return { passed, failed, skipped, todo, results: runtimeState.testResults };
|
|
1164
1174
|
}
|
|
1165
1175
|
async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
1166
1176
|
let directMatch = false;
|
|
1167
|
-
if (describePattern) {
|
|
1168
|
-
const
|
|
1169
|
-
const regex = new RegExp(escapedPattern, "i");
|
|
1177
|
+
if (runtimeState.describePattern) {
|
|
1178
|
+
const regex = new RegExp(escapeRegex(runtimeState.describePattern), "i");
|
|
1170
1179
|
directMatch = regex.test(suite.name);
|
|
1171
1180
|
}
|
|
1172
|
-
|
|
1173
|
-
if (!describePattern) return true;
|
|
1174
|
-
const escapedPattern = escapeRegex(describePattern);
|
|
1175
|
-
const regex = new RegExp(escapedPattern, "i");
|
|
1176
|
-
if (regex.test(s.name)) return true;
|
|
1177
|
-
for (const child of s.suites) {
|
|
1178
|
-
if (suiteOrDescendantMatches(child)) return true;
|
|
1179
|
-
}
|
|
1180
|
-
return false;
|
|
1181
|
-
}
|
|
1182
|
-
const shouldRunSuite = !describePattern || directMatch || parentMatched || suiteOrDescendantMatches(suite);
|
|
1181
|
+
const shouldRunSuite = !runtimeState.describePattern || directMatch || parentMatched || suiteOrDescendantMatches(suite);
|
|
1183
1182
|
if (!shouldRunSuite) {
|
|
1184
1183
|
return;
|
|
1185
1184
|
}
|
|
@@ -1188,47 +1187,46 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
1188
1187
|
await executeSuite(childSuite, timeout, bail, parentMatched || directMatch);
|
|
1189
1188
|
}
|
|
1190
1189
|
}
|
|
1191
|
-
const shouldRunTests = !describePattern || directMatch || parentMatched || suite.name === "";
|
|
1190
|
+
const shouldRunTests = !runtimeState.describePattern || directMatch || parentMatched || suite.name === "";
|
|
1192
1191
|
if (!shouldRunTests) {
|
|
1193
1192
|
return;
|
|
1194
1193
|
}
|
|
1195
|
-
for (const hook of beforeAllHooks) {
|
|
1194
|
+
for (const hook of runtimeState.beforeAllHooks) {
|
|
1196
1195
|
await hook();
|
|
1197
1196
|
}
|
|
1198
1197
|
for (const test of suite.tests) {
|
|
1199
|
-
if (hasOnly && !test.only && !suite.only) {
|
|
1198
|
+
if (runtimeState.hasOnly && !test.only && !suite.only) {
|
|
1200
1199
|
continue;
|
|
1201
1200
|
}
|
|
1202
1201
|
let testMatches = true;
|
|
1203
|
-
if (testPattern) {
|
|
1204
|
-
const
|
|
1205
|
-
const regex = new RegExp(escapedPattern, "i");
|
|
1202
|
+
if (runtimeState.testPattern) {
|
|
1203
|
+
const regex = new RegExp(escapeRegex(runtimeState.testPattern), "i");
|
|
1206
1204
|
testMatches = regex.test(test.name);
|
|
1207
1205
|
}
|
|
1208
1206
|
if (!testMatches) {
|
|
1209
1207
|
continue;
|
|
1210
1208
|
}
|
|
1211
1209
|
if (test.skip || suite.skip) {
|
|
1212
|
-
testResults.push({
|
|
1210
|
+
runtimeState.testResults.push({
|
|
1213
1211
|
name: test.name,
|
|
1214
1212
|
status: "skip",
|
|
1215
1213
|
duration: 0,
|
|
1216
1214
|
suite: suite.name,
|
|
1217
|
-
file: currentTestFile
|
|
1215
|
+
file: runtimeState.currentTestFile
|
|
1218
1216
|
});
|
|
1219
1217
|
continue;
|
|
1220
1218
|
}
|
|
1221
1219
|
if (test.todo) {
|
|
1222
|
-
testResults.push({
|
|
1220
|
+
runtimeState.testResults.push({
|
|
1223
1221
|
name: test.name,
|
|
1224
1222
|
status: "todo",
|
|
1225
1223
|
duration: 0,
|
|
1226
1224
|
suite: suite.name,
|
|
1227
|
-
file: currentTestFile
|
|
1225
|
+
file: runtimeState.currentTestFile
|
|
1228
1226
|
});
|
|
1229
1227
|
continue;
|
|
1230
1228
|
}
|
|
1231
|
-
for (const hook of beforeEachHooks) {
|
|
1229
|
+
for (const hook of runtimeState.beforeEachHooks) {
|
|
1232
1230
|
await hook();
|
|
1233
1231
|
}
|
|
1234
1232
|
const startTime = Date.now();
|
|
@@ -1239,27 +1237,27 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
1239
1237
|
(_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${test.timeout}ms`)), test.timeout)
|
|
1240
1238
|
)
|
|
1241
1239
|
]);
|
|
1242
|
-
testResults.push({
|
|
1240
|
+
runtimeState.testResults.push({
|
|
1243
1241
|
name: test.name,
|
|
1244
1242
|
status: "pass",
|
|
1245
1243
|
duration: Date.now() - startTime,
|
|
1246
1244
|
suite: suite.name,
|
|
1247
|
-
file: currentTestFile
|
|
1245
|
+
file: runtimeState.currentTestFile
|
|
1248
1246
|
});
|
|
1249
1247
|
} catch (error) {
|
|
1250
|
-
let lineNumber
|
|
1251
|
-
let codeSnippet
|
|
1248
|
+
let lineNumber;
|
|
1249
|
+
let codeSnippet;
|
|
1252
1250
|
if (error instanceof AssertionError) {
|
|
1253
1251
|
lineNumber = error.lineNumber;
|
|
1254
1252
|
codeSnippet = error.codeSnippet;
|
|
1255
1253
|
}
|
|
1256
|
-
testResults.push({
|
|
1254
|
+
runtimeState.testResults.push({
|
|
1257
1255
|
name: test.name,
|
|
1258
1256
|
status: "fail",
|
|
1259
1257
|
duration: Date.now() - startTime,
|
|
1260
1258
|
error,
|
|
1261
1259
|
suite: suite.name,
|
|
1262
|
-
file: currentTestFile,
|
|
1260
|
+
file: runtimeState.currentTestFile,
|
|
1263
1261
|
lineNumber,
|
|
1264
1262
|
codeSnippet
|
|
1265
1263
|
});
|
|
@@ -1267,53 +1265,14 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
1267
1265
|
throw error;
|
|
1268
1266
|
}
|
|
1269
1267
|
}
|
|
1270
|
-
for (const hook of afterEachHooks) {
|
|
1268
|
+
for (const hook of runtimeState.afterEachHooks) {
|
|
1271
1269
|
await hook();
|
|
1272
1270
|
}
|
|
1273
1271
|
}
|
|
1274
|
-
for (const hook of afterAllHooks) {
|
|
1272
|
+
for (const hook of runtimeState.afterAllHooks) {
|
|
1275
1273
|
await hook();
|
|
1276
1274
|
}
|
|
1277
1275
|
}
|
|
1278
|
-
var globals = {
|
|
1279
|
-
describe: createDescribeFunction(),
|
|
1280
|
-
it: createTestFunction(5e3),
|
|
1281
|
-
test: createTestFunction(5e3),
|
|
1282
|
-
expect,
|
|
1283
|
-
beforeAll,
|
|
1284
|
-
afterAll,
|
|
1285
|
-
beforeEach,
|
|
1286
|
-
afterEach,
|
|
1287
|
-
vi
|
|
1288
|
-
};
|
|
1289
|
-
function setupGlobals() {
|
|
1290
|
-
global.describe = globals.describe;
|
|
1291
|
-
global.it = globals.it;
|
|
1292
|
-
global.test = globals.test;
|
|
1293
|
-
global.expect = globals.expect;
|
|
1294
|
-
global.beforeAll = globals.beforeAll;
|
|
1295
|
-
global.afterAll = globals.afterAll;
|
|
1296
|
-
global.beforeEach = globals.beforeEach;
|
|
1297
|
-
global.afterEach = globals.afterEach;
|
|
1298
|
-
global.vi = globals.vi;
|
|
1299
|
-
}
|
|
1300
|
-
function clearGlobals() {
|
|
1301
|
-
delete global.describe;
|
|
1302
|
-
delete global.it;
|
|
1303
|
-
delete global.test;
|
|
1304
|
-
delete global.expect;
|
|
1305
|
-
delete global.beforeAll;
|
|
1306
|
-
delete global.afterAll;
|
|
1307
|
-
delete global.beforeEach;
|
|
1308
|
-
delete global.afterEach;
|
|
1309
|
-
delete global.vi;
|
|
1310
|
-
}
|
|
1311
|
-
function getCoveredFiles() {
|
|
1312
|
-
return coveredFiles;
|
|
1313
|
-
}
|
|
1314
|
-
function resetCoveredFiles() {
|
|
1315
|
-
coveredFiles.clear();
|
|
1316
|
-
}
|
|
1317
1276
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1318
1277
|
0 && (module.exports = {
|
|
1319
1278
|
clearGlobals,
|