vitest-pool-assemblyscript 0.9.1 → 0.10.1
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/assembly/compare.ts +11 -12
- package/assembly/describe.ts +4 -4
- package/assembly/expect.ts +44 -26
- package/assembly/test.ts +9 -9
- package/assembly/utils.ts +218 -62
- package/dist/{addon-interface-CYFXMbK7.mjs → addon-interface-BaUmn7uC.mjs} +12 -12
- package/dist/addon-interface-BaUmn7uC.mjs.map +1 -0
- package/dist/{ast-visitor-CWEOd3UH.mjs → ast-visitor-w1HMbuJR.mjs} +2 -2
- package/dist/{ast-visitor-CWEOd3UH.mjs.map → ast-visitor-w1HMbuJR.mjs.map} +1 -1
- package/dist/compile-runner-BGHM_85g.mjs +82 -0
- package/dist/compile-runner-BGHM_85g.mjs.map +1 -0
- package/dist/compiler/transforms/deep-equals.d.mts.map +1 -1
- package/dist/compiler/transforms/deep-equals.mjs +61 -22
- package/dist/compiler/transforms/deep-equals.mjs.map +1 -1
- package/dist/compiler/transforms/strip-inline.mjs +2 -2
- package/dist/{compiler-Dqs-qd3I.mjs → compiler-CXR5UJId.mjs} +55 -27
- package/dist/compiler-CXR5UJId.mjs.map +1 -0
- package/dist/config/index-v3.d.mts +1 -1
- package/dist/config/index-v3.d.mts.map +1 -1
- package/dist/config/index-v3.mjs.map +1 -1
- package/dist/config/index.d.mts +2 -2
- package/dist/config/index.mjs +5 -7
- package/dist/{constants-DbxJ3hzg.mjs → constants-Bq5KNxXJ.mjs} +4 -2
- package/dist/constants-Bq5KNxXJ.mjs.map +1 -0
- package/dist/{coverage-merge-CBXkpM1O.mjs → coverage-merge-0WqdC-dq.mjs} +1 -1
- package/dist/{coverage-merge-CBXkpM1O.mjs.map → coverage-merge-0WqdC-dq.mjs.map} +1 -1
- package/dist/coverage-provider/index.mjs +36 -36
- package/dist/coverage-provider/index.mjs.map +1 -1
- package/dist/{feature-check-Bje3ntpV.mjs → feature-check-BJpc4LoO.mjs} +4 -4
- package/dist/{feature-check-Bje3ntpV.mjs.map → feature-check-BJpc4LoO.mjs.map} +1 -1
- package/dist/index-internal.d.mts +3 -3
- package/dist/index-internal.d.mts.map +1 -1
- package/dist/index-internal.mjs +5 -4
- package/dist/index-v3.d.mts.map +1 -1
- package/dist/index-v3.mjs +19 -33
- package/dist/index-v3.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +5 -7
- package/dist/{load-user-imports-Bx5ZlhSm.mjs → load-user-imports-Bcx9NOt9.mjs} +119 -232
- package/dist/load-user-imports-Bcx9NOt9.mjs.map +1 -0
- package/dist/pool-errors-Bn6YaguR.mjs +630 -0
- package/dist/pool-errors-Bn6YaguR.mjs.map +1 -0
- package/dist/{pool-runner-init-CNpRdA5u.d.mts → pool-runner-init-CCvnKt5o.d.mts} +2 -2
- package/dist/pool-runner-init-CCvnKt5o.d.mts.map +1 -0
- package/dist/{pool-runner-init-BqkwQ2tk.mjs → pool-runner-init-DjRCbiX-.mjs} +15 -30
- package/dist/pool-runner-init-DjRCbiX-.mjs.map +1 -0
- package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
- package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -1
- package/dist/pool-thread/compile-worker-thread.mjs +29 -19
- package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
- package/dist/pool-thread/test-worker-thread.d.mts +1 -1
- package/dist/pool-thread/test-worker-thread.d.mts.map +1 -1
- package/dist/pool-thread/test-worker-thread.mjs +25 -18
- package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
- package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
- package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -1
- package/dist/pool-thread/v3-tinypool-thread.mjs +43 -33
- package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
- package/dist/test-runner-BeP8ClnE.mjs +147 -0
- package/dist/test-runner-BeP8ClnE.mjs.map +1 -0
- package/dist/{types-DHVk5iAx.d.mts → types-CoroKYxB.d.mts} +39 -16
- package/dist/types-CoroKYxB.d.mts.map +1 -0
- package/dist/vitest-file-tasks-vvZzigcF.mjs +473 -0
- package/dist/vitest-file-tasks-vvZzigcF.mjs.map +1 -0
- package/dist/wasm-memory-C8Nkl2Sz.mjs +134 -0
- package/dist/wasm-memory-C8Nkl2Sz.mjs.map +1 -0
- package/dist/{worker-rpc-channel-CZZIxtv5.mjs → worker-rpc-channel-CvCrc8aa.mjs} +1 -1
- package/dist/{worker-rpc-channel-CZZIxtv5.mjs.map → worker-rpc-channel-CvCrc8aa.mjs.map} +1 -1
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
- package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/src/instrumentation/native/addon.cpp +71 -32
- package/dist/addon-interface-CYFXMbK7.mjs.map +0 -1
- package/dist/compile-runner-BNFHRGZO.mjs +0 -85
- package/dist/compile-runner-BNFHRGZO.mjs.map +0 -1
- package/dist/compiler-Dqs-qd3I.mjs.map +0 -1
- package/dist/constants-DbxJ3hzg.mjs.map +0 -1
- package/dist/debug-DtRAL4rM.mjs +0 -232
- package/dist/debug-DtRAL4rM.mjs.map +0 -1
- package/dist/load-user-imports-Bx5ZlhSm.mjs.map +0 -1
- package/dist/path-utils-t9OzjXYF.mjs +0 -24
- package/dist/path-utils-t9OzjXYF.mjs.map +0 -1
- package/dist/pool-runner-init-BqkwQ2tk.mjs.map +0 -1
- package/dist/pool-runner-init-CNpRdA5u.d.mts.map +0 -1
- package/dist/resolve-config-s9gSJSMc.mjs +0 -85
- package/dist/resolve-config-s9gSJSMc.mjs.map +0 -1
- package/dist/test-runner-BGqc9uCK.mjs +0 -138
- package/dist/test-runner-BGqc9uCK.mjs.map +0 -1
- package/dist/types-DHVk5iAx.d.mts.map +0 -1
- package/dist/vitest-file-tasks-D8sOClGX.mjs +0 -149
- package/dist/vitest-file-tasks-D8sOClGX.mjs.map +0 -1
- package/dist/vitest-tasks-BZ24sghI.mjs +0 -321
- package/dist/vitest-tasks-BZ24sghI.mjs.map +0 -1
- package/dist/wasm-names-BFtzQCH4.mjs +0 -124
- package/dist/wasm-names-BFtzQCH4.mjs.map +0 -1
|
@@ -1,79 +1,11 @@
|
|
|
1
|
-
import { COVERAGE_PAYLOAD_FORMATS, POOL_ERROR_NAMES,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { COVERAGE_PAYLOAD_FORMATS, POOL_ERROR_NAMES, TEST_ERROR_NAMES } from "./constants-Bq5KNxXJ.mjs";
|
|
2
|
+
import { createAfterSuiteRunMeta, createSuiteTask, createTestTask, failTestAssertionError, failTestRuntimeError, getTaskLogLabel, isSuiteOwnFile } from "./vitest-file-tasks-vvZzigcF.mjs";
|
|
3
|
+
import { abortWASMExecution, abortWASMExecutionOnSuccess, createPoolError, debug, debugOverride, enhanceTestError, extractCallStack, getExpectedMessageOrAny, wrapPoolError } from "./pool-errors-Bn6YaguR.mjs";
|
|
4
|
+
import { createMemory, decodeAbortInfo, liftString } from "./wasm-memory-C8Nkl2Sz.mjs";
|
|
5
5
|
import { basename, resolve } from "node:path";
|
|
6
|
-
import { createBirpc } from "birpc";
|
|
7
|
-
import { diff } from "@vitest/utils/diff";
|
|
8
|
-
import { SourceMapConsumer } from "source-map";
|
|
9
6
|
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { createBirpc } from "birpc";
|
|
10
8
|
|
|
11
|
-
//#region src/util/assemblyscript/binding-helpers.ts
|
|
12
|
-
const STRING_EXTRACT_CHUNK_SIZE = 1024;
|
|
13
|
-
/**
|
|
14
|
-
* Decode an AssemblyScript string from WASM memory, using the length stored at
|
|
15
|
-
* the beginning of the string.
|
|
16
|
-
*
|
|
17
|
-
* This approach is borrowed from AssemblyScript with changes for clarity.
|
|
18
|
-
* AssemblyScript is released under the Apache 2.0 license, included here.
|
|
19
|
-
*
|
|
20
|
-
* When a string argument crosses the boundary to JS, we get a pointer to the
|
|
21
|
-
* string data in WASM memory. WASM strings store their length in the 4 bytes
|
|
22
|
-
* before the string data pointer so we know how much to read from memory.
|
|
23
|
-
*
|
|
24
|
-
* @param memory - WebAssembly memory instance
|
|
25
|
-
* @param pointer - Pointer to the start of the string
|
|
26
|
-
* @returns Decoded string
|
|
27
|
-
*/
|
|
28
|
-
function liftString(memory, pointer) {
|
|
29
|
-
if (!pointer) return void 0;
|
|
30
|
-
const unsigned = pointer >>> 0;
|
|
31
|
-
const uint32LengthPtr = unsigned - 4 >>> 2;
|
|
32
|
-
const byteOffsetLength = new Uint32Array(memory.buffer)[uint32LengthPtr];
|
|
33
|
-
if (byteOffsetLength === 0) return "";
|
|
34
|
-
const uint16EndPtr = unsigned + byteOffsetLength >>> 1;
|
|
35
|
-
let uint16StartPtr = unsigned >>> 1;
|
|
36
|
-
const memoryU16 = new Uint16Array(memory.buffer);
|
|
37
|
-
let string = "";
|
|
38
|
-
while (uint16EndPtr - uint16StartPtr > STRING_EXTRACT_CHUNK_SIZE) string += String.fromCharCode(...memoryU16.subarray(uint16StartPtr, uint16StartPtr += STRING_EXTRACT_CHUNK_SIZE));
|
|
39
|
-
return string + String.fromCharCode(...memoryU16.subarray(uint16StartPtr, uint16EndPtr));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/wasm-executor/wasm-memory.ts
|
|
44
|
-
/**
|
|
45
|
-
* Create a WebAssembly memory instance
|
|
46
|
-
* Used for imported memory pattern (matches --importMemory flag)
|
|
47
|
-
*/
|
|
48
|
-
function createMemory(initialPages, maximumPages) {
|
|
49
|
-
return new WebAssembly.Memory({
|
|
50
|
-
initial: initialPages,
|
|
51
|
-
maximum: maximumPages
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Decode AssemblyScript abort information
|
|
56
|
-
*
|
|
57
|
-
* Helper for handling abort() calls from AssemblyScript runtime.
|
|
58
|
-
* Decodes the error message and file path from WASM memory.
|
|
59
|
-
*
|
|
60
|
-
* @param memory - WebAssembly memory instance
|
|
61
|
-
* @param msgPtr - Pointer to error message string (or 0 if none)
|
|
62
|
-
* @param filePtr - Pointer to file path string (or 0 if none)
|
|
63
|
-
* @param line - Line number where abort occurred
|
|
64
|
-
* @param column - Column number where abort occurred
|
|
65
|
-
* @returns Decoded message and location (null if no meaningful location info)
|
|
66
|
-
*/
|
|
67
|
-
function decodeAbortInfo(memory, msgPtr, filePtr, line, column) {
|
|
68
|
-
const errorMsg = liftString(memory, msgPtr) ?? "Unknown error";
|
|
69
|
-
const filePath = liftString(memory, filePtr);
|
|
70
|
-
return {
|
|
71
|
-
message: errorMsg,
|
|
72
|
-
location: filePath && filePath !== "unknown" && (line !== 0 || column !== 0) ? `${filePath}:${line}:${column}` : null
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
//#endregion
|
|
77
9
|
//#region src/wasm-executor/wasm-console.ts
|
|
78
10
|
function createWasmConsole(memory, handleLog) {
|
|
79
11
|
const getMessage = (msgPtr, memory, prefix = "") => {
|
|
@@ -165,12 +97,10 @@ function createUserWasmImports(createWasmImports, memory, module, logPrefix) {
|
|
|
165
97
|
});
|
|
166
98
|
debug(`${logPrefix} Created user WASM imports for test execution in ${(performance.now() - start).toFixed(2)} ms`);
|
|
167
99
|
userEnvImports = userImports?.env;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
delete userCustomEnvImports.env;
|
|
171
|
-
}
|
|
100
|
+
userCustomEnvImports = { ...userImports };
|
|
101
|
+
if (userEnvImports) delete userCustomEnvImports.env;
|
|
172
102
|
} catch (error) {
|
|
173
|
-
throw
|
|
103
|
+
throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, "Could not create user WasmImportsFactory. Ensure that your module has a default export matching () => WebAssembly.Imports", error, true);
|
|
174
104
|
}
|
|
175
105
|
return {
|
|
176
106
|
userEnvImports,
|
|
@@ -190,18 +120,15 @@ function createDiscoveryImports(memory, module, file, handleLog, logPrefix, cove
|
|
|
190
120
|
memory,
|
|
191
121
|
abort(msgPtr, filePtr, line, column) {
|
|
192
122
|
const { message, location } = decodeAbortInfo(memory, msgPtr, filePtr, line, column);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const rawCallStack = extractCallStack(/* @__PURE__ */ new Error());
|
|
196
|
-
const testError = {
|
|
123
|
+
debug(`${logPrefix} - Unexpected abort during test discovery: ${`${message}${location ? ` at ${location}` : ""}`}`);
|
|
124
|
+
throw abortWASMExecution({
|
|
197
125
|
message,
|
|
198
126
|
name: TEST_ERROR_NAMES.WASMRuntimeError
|
|
199
|
-
};
|
|
200
|
-
throw createPoolError(msgAtLoc, POOL_ERROR_NAMES.WASMExecutionAbortError, void 0, testError, rawCallStack);
|
|
127
|
+
}, /* @__PURE__ */ new Error());
|
|
201
128
|
}
|
|
202
129
|
},
|
|
203
130
|
["__as_pool_env__"]: {
|
|
204
|
-
...coverageMemory ? { __coverage_memory: coverageMemory } : {},
|
|
131
|
+
...coverageMemory ? { ["__coverage_memory"]: coverageMemory } : {},
|
|
205
132
|
__assertion_pass() {},
|
|
206
133
|
__assertion_fail() {},
|
|
207
134
|
__expect_throw() {},
|
|
@@ -238,6 +165,7 @@ function createDiscoveryImports(memory, module, file, handleLog, logPrefix, cove
|
|
|
238
165
|
* runtime aborts as expected cases for test execution by capturing the error on the test meta.
|
|
239
166
|
*/
|
|
240
167
|
function createTestExecutionImports(memory, module, test, handleLog, logPrefix, coverageMemory, createWasmImports) {
|
|
168
|
+
let lastFailedAssertion;
|
|
241
169
|
let isExpectingError = false;
|
|
242
170
|
let expectedErrorMsgStr;
|
|
243
171
|
let wasmFunctionTable;
|
|
@@ -255,72 +183,72 @@ function createTestExecutionImports(memory, module, test, handleLog, logPrefix,
|
|
|
255
183
|
if (isExpectingError) if (!expectedErrorMsgStr || message.includes(expectedErrorMsgStr)) {
|
|
256
184
|
test.meta.assertionsPassedCount++;
|
|
257
185
|
debug(`${logPrefix} - Thrown error matches expected - assertion passes`);
|
|
258
|
-
throw
|
|
186
|
+
throw abortWASMExecutionOnSuccess();
|
|
259
187
|
} else {
|
|
260
|
-
|
|
261
|
-
|
|
188
|
+
const expected = getExpectedMessageOrAny(expectedErrorMsgStr);
|
|
189
|
+
failureMessage = `expected function to throw error ${expected}, but received error "${message}"`;
|
|
190
|
+
lastFailedAssertion = {
|
|
262
191
|
message: failureMessage,
|
|
263
|
-
|
|
192
|
+
actualTypeName: "string",
|
|
193
|
+
expectedTypeName: "string",
|
|
264
194
|
valuesProvided: true,
|
|
265
195
|
actual: message,
|
|
266
196
|
expected: expectedErrorMsgStr
|
|
267
|
-
}
|
|
268
|
-
debug(`${logPrefix} - Assertion failed: ${`Thrown error does not match expected | Expected:
|
|
197
|
+
};
|
|
198
|
+
debug(`${logPrefix} - Assertion failed: ${`Thrown error does not match expected | Expected: ${expected} | Actual: "${message}"`}`);
|
|
269
199
|
}
|
|
270
|
-
|
|
271
|
-
throw createPoolError(`AssemblyScript abort() import called during test execution for ${test.name}`, POOL_ERROR_NAMES.WASMExecutionAbortError);
|
|
200
|
+
throw abortWASMExecution(lastFailedAssertion ? failTestAssertionError(test, lastFailedAssertion) : failTestRuntimeError(test, "", failureMessage), /* @__PURE__ */ new Error());
|
|
272
201
|
}
|
|
273
202
|
},
|
|
274
203
|
["__as_pool_env__"]: {
|
|
275
|
-
...coverageMemory ? { __coverage_memory: coverageMemory } : {},
|
|
204
|
+
...coverageMemory ? { ["__coverage_memory"]: coverageMemory } : {},
|
|
276
205
|
__register_test() {},
|
|
277
206
|
__begin_register_suite() {},
|
|
278
207
|
__end_register_suite() {},
|
|
279
208
|
__assertion_pass() {
|
|
280
209
|
test.meta.assertionsPassedCount++;
|
|
281
210
|
},
|
|
282
|
-
__assertion_fail(msgPtr,
|
|
283
|
-
const errorMsg = liftString(memory, msgPtr);
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
let
|
|
287
|
-
|
|
211
|
+
__assertion_fail(msgPtr, actualTypeNamePtr, expectedTypeNamePtr, valuesProvided, actualPtr, expectedPtr) {
|
|
212
|
+
const errorMsg = liftString(memory, msgPtr) ?? "";
|
|
213
|
+
const actualTypeName = liftString(memory, actualTypeNamePtr) ?? "";
|
|
214
|
+
const expectedTypeName = liftString(memory, expectedTypeNamePtr) ?? "";
|
|
215
|
+
let valuesMsg = " | No Values Provided";
|
|
216
|
+
lastFailedAssertion = {
|
|
217
|
+
actualTypeName,
|
|
218
|
+
expectedTypeName,
|
|
288
219
|
message: errorMsg,
|
|
289
|
-
typeName: assertionValueType,
|
|
290
220
|
valuesProvided: Boolean(valuesProvided)
|
|
291
221
|
};
|
|
222
|
+
test.meta.assertionsFailed.push(lastFailedAssertion);
|
|
292
223
|
if (valuesProvided && actualPtr && expectedPtr) {
|
|
293
|
-
|
|
294
|
-
|
|
224
|
+
lastFailedAssertion.actual = liftString(memory, actualPtr);
|
|
225
|
+
lastFailedAssertion.expected = liftString(memory, expectedPtr);
|
|
226
|
+
valuesMsg = ` | Actual Type: ${actualTypeName} | Expected Type: ${expectedTypeName} | Actual Value: \`${lastFailedAssertion.actual}\` | Expected Value: \`${lastFailedAssertion.expected}\``;
|
|
295
227
|
}
|
|
296
|
-
|
|
297
|
-
debug(`${logPrefix} - Assertion failed: ${errorMsg}${valuesProvided ? ` | Value Type: ${assertionValueType} | Expected: \`${expected !== void 0 ? expected : ""}\` | Actual: \`${actual !== void 0 ? actual : ""}\`` : ""}`);
|
|
228
|
+
debug(`${logPrefix} - Assertion failed: ${errorMsg}${valuesMsg}`);
|
|
298
229
|
},
|
|
299
230
|
__expect_throw(fnIndex, expectedErrorMsgPtr) {
|
|
300
231
|
isExpectingError = true;
|
|
301
232
|
if (expectedErrorMsgPtr) expectedErrorMsgStr = liftString(memory, expectedErrorMsgPtr);
|
|
302
|
-
debug(`${logPrefix} - Registered expected error throw: ${expectedErrorMsgStr
|
|
233
|
+
debug(`${logPrefix} - Registered expected error throw: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`);
|
|
303
234
|
if (wasmFunctionTable && typeof wasmFunctionTable.get === "function") {
|
|
304
235
|
const fn = wasmFunctionTable.get(fnIndex);
|
|
305
|
-
if (!fn) throw createPoolError(`Could not access function (fnPtr ${fnIndex}) which is expected to throw in test "${test.name}"
|
|
236
|
+
if (!fn) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Could not access function (fnPtr ${fnIndex}) which is expected to throw in test "${test.name}"`);
|
|
306
237
|
debug(`${logPrefix} - Calling function (idx ${fnIndex})`);
|
|
307
238
|
fn();
|
|
308
|
-
} else throw createPoolError(`Could not access WASM function table to call function expected to throw
|
|
239
|
+
} else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Could not access WASM function table to call function expected to throw`);
|
|
309
240
|
},
|
|
310
241
|
__end_expect_throw() {
|
|
311
242
|
if (isExpectingError) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
valuesProvided:
|
|
243
|
+
debug(`${logPrefix} - Assertion failed: ${`Expected thrown error but got none | Expected: "${expectedErrorMsgStr}"`}`);
|
|
244
|
+
throw abortWASMExecution(failTestAssertionError(test, {
|
|
245
|
+
message: `function did not throw, but was expected to throw error: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`,
|
|
246
|
+
actualTypeName: "undefined",
|
|
247
|
+
expectedTypeName: "string",
|
|
248
|
+
valuesProvided: true,
|
|
318
249
|
actual: void 0,
|
|
319
250
|
expected: expectedErrorMsgStr
|
|
320
|
-
});
|
|
321
|
-
debug(`${logPrefix} - Assertion failed: ${`Expected thrown error but got none | Expected: "${expectedErrorMsgStr}"`}`);
|
|
322
|
-
failTest(test, failureMessage, /* @__PURE__ */ new Error(), logPrefix);
|
|
323
|
-
throw createPoolError(`AssemblyScript __end_expect_throw() import called during test execution for ${test.name}`, POOL_ERROR_NAMES.WASMExecutionAbortError);
|
|
251
|
+
}));
|
|
324
252
|
}
|
|
325
253
|
}
|
|
326
254
|
},
|
|
@@ -334,112 +262,58 @@ function createTestExecutionImports(memory, module, test, handleLog, logPrefix,
|
|
|
334
262
|
}
|
|
335
263
|
|
|
336
264
|
//#endregion
|
|
337
|
-
//#region src/wasm-executor/
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const mappedCallSite = createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix);
|
|
345
|
-
if (mappedCallSite) mappedStack.push(mappedCallSite);
|
|
346
|
-
});
|
|
347
|
-
sourceMapConsumer.destroy();
|
|
348
|
-
return mappedStack;
|
|
349
|
-
}
|
|
350
|
-
function parseMappedStack(mappedStack) {
|
|
351
|
-
return mappedStack.filter((frame) => !POOL_INTERNAL_PATHS_SET.has(frame.location.filePath)).map((frame) => ({
|
|
352
|
-
method: getShortFunctionName(frame.functionName),
|
|
353
|
-
file: frame.location.filePath,
|
|
354
|
-
line: frame.location.line,
|
|
355
|
-
column: frame.location.column + 1
|
|
356
|
-
}));
|
|
265
|
+
//#region src/wasm-executor/index.ts
|
|
266
|
+
const SIG_MISMATCH_ERROR_MSG = "WASM function signature type mismatch during test collection. This is most likely caused by passing a type-inferred, non-void callback to expect(). To fix, either explicitly define the non-void return type on the callback e.g. `expect((): i32 => failingFunction()).toThrowError()` or use braces to make it void e.g. `expect(() => { failingFunction(); }).toThrowError()`. Look for the failing expect() within the describe() block indicated in the stack trace.";
|
|
267
|
+
function verifyMemoryRequirements(compilation, poolOptions) {
|
|
268
|
+
if (poolOptions.testMemoryPagesInitial && poolOptions.testMemoryPagesInitial < compilation.requiredMemory.testMemory.initialPages) throw createPoolError(POOL_ERROR_NAMES.PoolConfigError, `WASM binary requires initial test memory pages (${compilation.requiredMemory.testMemory.initialPages}) exceeding configured "testMemoryPagesInitial" (${poolOptions.testMemoryPagesInitial}). Increase value, or remove for auto sizing.`);
|
|
269
|
+
if (poolOptions.testMemoryPagesMax && compilation.requiredMemory.testMemory.maximumPages && poolOptions.testMemoryPagesMax < compilation.requiredMemory.testMemory.maximumPages) throw createPoolError(POOL_ERROR_NAMES.PoolConfigError, `WASM binary requires maximum test memory pages (${compilation.requiredMemory.testMemory.maximumPages}) exceeding configured "testMemoryPagesMax" (${poolOptions.testMemoryPagesMax}). Increase value, or remove for auto sizing.`);
|
|
270
|
+
if (poolOptions.coverageMemoryPagesInitial && poolOptions.coverageMemoryPagesInitial < compilation.requiredMemory.coverageMemory.initialPages) throw createPoolError(POOL_ERROR_NAMES.PoolConfigError, `WASM binary requires initial coverage memory pages (${compilation.requiredMemory.coverageMemory.initialPages}) exceeding configured "coverageMemoryPagesInitial" (${poolOptions.coverageMemoryPagesInitial}). Increase value, or remove for auto sizing.`);
|
|
271
|
+
if (poolOptions.coverageMemoryPagesMax && compilation.requiredMemory.coverageMemory.maximumPages && poolOptions.coverageMemoryPagesMax < compilation.requiredMemory.coverageMemory.maximumPages) throw createPoolError(POOL_ERROR_NAMES.PoolConfigError, `WASM binary requires maximum coverage memory pages (${compilation.requiredMemory.coverageMemory.maximumPages}) exceeding configured "coverageMemoryPagesMax" (${poolOptions.coverageMemoryPagesMax}). Increase value, or remove for auto sizing.`);
|
|
357
272
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const sourceMappedStack = await sourceMapRawCallStack(rawCallStack, sourceMapObj, loggingPrefix);
|
|
361
|
-
debug(`${loggingPrefix} - Mapped ${rawCallStack.length} call sites to ${sourceMappedStack.length} source locations`);
|
|
273
|
+
function createExecutorMemories(compilation, poolOptions, includeCoverageMemory) {
|
|
274
|
+
verifyMemoryRequirements(compilation, poolOptions);
|
|
362
275
|
return {
|
|
363
|
-
|
|
364
|
-
|
|
276
|
+
testMemory: createMemory(poolOptions.testMemoryPagesInitial ?? compilation.requiredMemory.testMemory.initialPages, poolOptions.testMemoryPagesMax ?? compilation.requiredMemory.testMemory.maximumPages),
|
|
277
|
+
coverageMemory: includeCoverageMemory ? createMemory(poolOptions.coverageMemoryPagesInitial ?? compilation.requiredMemory.coverageMemory.initialPages, poolOptions.coverageMemoryPagesMax ?? compilation.requiredMemory.coverageMemory.maximumPages) : void 0
|
|
365
278
|
};
|
|
366
279
|
}
|
|
367
280
|
/**
|
|
368
|
-
* Enhance reportable test error on the provided test result with source mapped stack locations
|
|
369
|
-
* and a formatted diff based on the error type
|
|
370
|
-
*/
|
|
371
|
-
async function enhanceTestError(error, task, sourceMap, valuesProvided, logPrefix, rawCallStack, diffOptions) {
|
|
372
|
-
const isAssertionFailure = error.name === TEST_ERROR_NAMES.AssertionError;
|
|
373
|
-
let expectedVsActualDiffString = "";
|
|
374
|
-
if (isAssertionFailure && valuesProvided) expectedVsActualDiffString = diff(error.expected, error.actual, diffOptions) ?? "";
|
|
375
|
-
if (!rawCallStack || rawCallStack.length === 0) {
|
|
376
|
-
error.diff = expectedVsActualDiffString;
|
|
377
|
-
error.stack = `${task.name} - ${error.message}`;
|
|
378
|
-
return error;
|
|
379
|
-
}
|
|
380
|
-
const { parsedStack, parsedSourceMap } = await processWASMErrorStack(rawCallStack, sourceMap, logPrefix);
|
|
381
|
-
let primaryStackFrameString;
|
|
382
|
-
let highlightedSourceCodeFrameString;
|
|
383
|
-
if (parsedStack.length > 0) {
|
|
384
|
-
const primaryStackFrame = parsedStack[0];
|
|
385
|
-
primaryStackFrameString = toVitestLikeStackFrameString(primaryStackFrame);
|
|
386
|
-
error.stacks = parsedStack.slice(1);
|
|
387
|
-
highlightedSourceCodeFrameString = getSourceCodeFrameString(parsedSourceMap, primaryStackFrame);
|
|
388
|
-
debug(`${logPrefix} - Enhanced ${error.name} error with parsed source stack`);
|
|
389
|
-
}
|
|
390
|
-
if (isAssertionFailure) error.diff = [
|
|
391
|
-
`${expectedVsActualDiffString}${expectedVsActualDiffString ? "\n\n" : ""}`,
|
|
392
|
-
`${primaryStackFrameString}\n`,
|
|
393
|
-
`${highlightedSourceCodeFrameString}`
|
|
394
|
-
].join("");
|
|
395
|
-
else error.diff = [`${primaryStackFrameString}\n`, `${highlightedSourceCodeFrameString}`].join("");
|
|
396
|
-
error.stack = parsedStack.map(toPlaintextStackFrameString).join("\n");
|
|
397
|
-
debug(`[${logPrefix} - Enhanced ${error.name} error with diffs`);
|
|
398
|
-
return error;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
//#endregion
|
|
402
|
-
//#region src/wasm-executor/index.ts
|
|
403
|
-
const SIG_MISMATCH_ERROR_MSG = "WASM RuntimeError indicates function signature type mismatch during test suite collection. This is likely caused by passing a non-void callback to expect(). Use braces to ensure it returns void e.g. `expect(() => { failingFunction(); }).toThrowError()`. Look for the failing expect() within the describe() block indicated in the stack trace.";
|
|
404
|
-
function createExecutorPoolError(testFileBasename, context, reason, cause) {
|
|
405
|
-
return createPoolError(`${testFileBasename} - ${context} WASM executor: ${reason}`, POOL_ERROR_NAMES.WASMExecutionHarnessError, void 0, cause);
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
281
|
* Discover tests via test() and suites via describe() registration calls
|
|
409
282
|
*/
|
|
410
|
-
async function executeWASMDiscovery(
|
|
283
|
+
async function executeWASMDiscovery(compilation, poolOptions, isBinaryInstrumented, handleLog, file, moduleLabel, threadImports) {
|
|
411
284
|
const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(basename(file.filepath), file)}`;
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
exports._start();
|
|
285
|
+
try {
|
|
286
|
+
const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, isBinaryInstrumented);
|
|
287
|
+
const importObject = createDiscoveryImports(testMemory, compilation.compiledModule, file, handleLog, logPrefix, coverageMemory, threadImports.createUserWasmImports);
|
|
288
|
+
const exports = new WebAssembly.Instance(compilation.compiledModule, importObject).exports;
|
|
289
|
+
if (typeof exports._start === "function") exports._start();
|
|
290
|
+
else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "no _start() export found on compiled WASM binary");
|
|
417
291
|
} catch (error) {
|
|
418
|
-
|
|
419
|
-
if (error instanceof WebAssembly.RuntimeError &&
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
292
|
+
if (error && error["__as_pool_error__"]) throw error;
|
|
293
|
+
if (error instanceof WebAssembly.RuntimeError && error.message.includes("null function or function signature mismatch")) throw createPoolError(POOL_ERROR_NAMES.PoolSyntaxError, SIG_MISMATCH_ERROR_MSG, error);
|
|
294
|
+
if (error instanceof Error) {
|
|
295
|
+
let match = null;
|
|
296
|
+
let moduleName;
|
|
297
|
+
let functionName;
|
|
298
|
+
let errorMessage;
|
|
299
|
+
if (match = /"(.+)": module is not an object or function/.exec(error.message)) {
|
|
300
|
+
moduleName = match[1];
|
|
301
|
+
errorMessage = `Expected module "${moduleName}" to be defined as an object or function within user WASM imports (returned by WasmImportsFactory).`;
|
|
302
|
+
} else if (match = /"(.+)" (function=)?"(.+)": function import requires a callable/.exec(error.message)) {
|
|
303
|
+
moduleName = match[1];
|
|
304
|
+
functionName = match[3];
|
|
305
|
+
errorMessage = `Expected function "${functionName}" to be defined in module "${moduleName}" within user WASM imports (returned by WasmImportsFactory).`;
|
|
306
|
+
}
|
|
307
|
+
if (errorMessage) throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, errorMessage, error);
|
|
427
308
|
}
|
|
428
|
-
|
|
429
|
-
const thrownPoolErr = thrownErrAny;
|
|
430
|
-
thrownPoolErr.cause = await enhanceTestError(thrownPoolErr.cause, file, sourceMap, false, logPrefix, thrownPoolErr.rawCallStack, diffOptions);
|
|
431
|
-
thrownPoolErr.causeIsEnhancedError = true;
|
|
432
|
-
delete thrownPoolErr.rawCallStack;
|
|
433
|
-
throw thrownPoolErr;
|
|
434
|
-
} else throw createPoolErrorFromAnyError(`${testFileBasename} - Unexpected discovery error`, POOL_ERROR_NAMES.WASMExecutionHarnessError, error);
|
|
309
|
+
throw wrapPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, error, true);
|
|
435
310
|
}
|
|
436
|
-
else throw createExecutorPoolError(testFileBasename, "discoverTests", "no _start() export");
|
|
437
311
|
debug(`${logPrefix} - Discovered ${file.tasks.length} top-level tasks`);
|
|
438
312
|
}
|
|
439
313
|
/**
|
|
440
314
|
* Execute a single test with crash isolation
|
|
441
315
|
*/
|
|
442
|
-
async function executeWASMTest(test, compilation,
|
|
316
|
+
async function executeWASMTest(test, compilation, poolOptions, collectCoverage, handleLog, moduleLabel, threadImports, projectRoot, diffOptions) {
|
|
443
317
|
const testTimings = {
|
|
444
318
|
fnInit: performance.now(),
|
|
445
319
|
execStart: 0,
|
|
@@ -451,40 +325,51 @@ async function executeWASMTest(test, compilation, testFileBasename, poolOptions,
|
|
|
451
325
|
function covDebug(...args) {
|
|
452
326
|
if (poolOptions.debugCoverageExtract) debugOverride(...args);
|
|
453
327
|
}
|
|
454
|
-
const
|
|
455
|
-
const
|
|
456
|
-
const
|
|
457
|
-
const { imports, provideFunctionTable } = createTestExecutionImports(memory, wasmModule, test, handleLog, logPrefix, coverageMemory, threadImports.createUserWasmImports);
|
|
458
|
-
const exports = new WebAssembly.Instance(wasmModule, imports).exports;
|
|
328
|
+
const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, collectCoverage);
|
|
329
|
+
const { imports, provideFunctionTable } = createTestExecutionImports(testMemory, compilation.compiledModule, test, handleLog, logPrefix, coverageMemory, threadImports.createUserWasmImports);
|
|
330
|
+
const exports = new WebAssembly.Instance(compilation.compiledModule, imports).exports;
|
|
459
331
|
const table = exports.table;
|
|
460
332
|
if (table && typeof table.get === "function") provideFunctionTable(table);
|
|
461
333
|
if (typeof exports._start === "function") exports._start();
|
|
462
|
-
else throw
|
|
334
|
+
else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "no _start() export found on compiled WASM binary");
|
|
463
335
|
let testFn;
|
|
464
336
|
if (table && typeof table.get === "function") {
|
|
465
337
|
const idx = test.meta.fnIndex;
|
|
466
338
|
testFn = table.get(idx);
|
|
467
|
-
if (!testFn) throw
|
|
468
|
-
} else throw
|
|
339
|
+
if (!testFn) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Test function at index ${idx} not found in function table`);
|
|
340
|
+
} else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "Function table not found in WASM exports (missing --exportTable flag?)");
|
|
469
341
|
try {
|
|
470
342
|
testTimings.execStart = performance.now();
|
|
471
343
|
testFn();
|
|
472
344
|
testTimings.execEnd = performance.now();
|
|
473
345
|
} catch (error) {
|
|
474
346
|
testTimings.execEnd = performance.now();
|
|
475
|
-
|
|
347
|
+
let testError;
|
|
348
|
+
let stack;
|
|
349
|
+
let allowStackJS;
|
|
350
|
+
let applyStackToTestErrorCause;
|
|
351
|
+
if (error && error["__as_pool_error__"]) {
|
|
352
|
+
const wrapper = error;
|
|
353
|
+
testError = wrapper.testError;
|
|
354
|
+
stack = wrapper.originalErrorRawStack;
|
|
355
|
+
allowStackJS = wrapper.originalErrorMayContainJS;
|
|
356
|
+
applyStackToTestErrorCause = wrapper.applyStackToTestErrorCause;
|
|
357
|
+
} else if (error instanceof Error) {
|
|
358
|
+
testError = failTestRuntimeError(test, error.name, error.message);
|
|
359
|
+
stack = extractCallStack(error);
|
|
360
|
+
allowStackJS = true;
|
|
361
|
+
applyStackToTestErrorCause = false;
|
|
362
|
+
} else {
|
|
363
|
+
testError = failTestRuntimeError(test, "", `Unexpected WASM test execution error: ${String(error)}`);
|
|
364
|
+
stack = extractCallStack(/* @__PURE__ */ new Error());
|
|
365
|
+
allowStackJS = true;
|
|
366
|
+
applyStackToTestErrorCause = false;
|
|
367
|
+
}
|
|
368
|
+
await enhanceTestError(testError, test, compilation.sourceMap, logPrefix, allowStackJS, projectRoot, applyStackToTestErrorCause, stack, diffOptions);
|
|
476
369
|
}
|
|
477
370
|
const meta = test.meta;
|
|
478
|
-
if (meta.lastError) {
|
|
479
|
-
const enhancedError = await enhanceTestError(meta.lastError, test, compilation.sourceMap, meta.lastErrorValuesProvided ?? false, logPrefix, meta.lastErrorRawCallStack, diffOptions);
|
|
480
|
-
if (test.result) if (test.result.errors) test.result.errors.push(enhancedError);
|
|
481
|
-
else test.result.errors = [enhancedError];
|
|
482
|
-
delete meta.lastError;
|
|
483
|
-
delete meta.lastErrorValuesProvided;
|
|
484
|
-
delete meta.lastErrorRawCallStack;
|
|
485
|
-
}
|
|
486
371
|
if (collectCoverage && compilation.debugInfo) {
|
|
487
|
-
if (!coverageMemory) throw
|
|
372
|
+
if (!coverageMemory) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "Coverage memory not created despite collectCoverage=true");
|
|
488
373
|
const coverage = { hitCountsByFileAndPosition: {} };
|
|
489
374
|
const extractedHitCounters = new Uint32Array(coverageMemory.buffer, 0, compilation.debugInfo.instrumentedFunctionCount);
|
|
490
375
|
covDebug(`${logPrefix} - Read coverage memory for ${compilation.debugInfo.instrumentedFunctionCount} instrumented functions`);
|
|
@@ -668,15 +553,17 @@ async function loadUserWasmImportsFactory(relativePath, projectRoot, logModule)
|
|
|
668
553
|
try {
|
|
669
554
|
const start = performance.now();
|
|
670
555
|
const createWasmImports = (await import(safeUrl)).default;
|
|
671
|
-
debug(`[${logModule}]
|
|
672
|
-
if (typeof createWasmImports !== "function")
|
|
673
|
-
|
|
556
|
+
debug(`[${logModule}] Imported user WasmImportsFactory "${safeUrl}" | TIMING ${(performance.now() - start).toFixed(2)} ms`);
|
|
557
|
+
if (typeof createWasmImports !== "function") {
|
|
558
|
+
const msg = `Could not load user WasmImportsFactory from "${safeUrl}". Ensure that your module has a default export matching () => WebAssembly.Imports \nDefault export type is currently "${typeof createWasmImports}"`;
|
|
559
|
+
throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, msg);
|
|
560
|
+
} else return createWasmImports;
|
|
674
561
|
} catch (error) {
|
|
675
|
-
|
|
676
|
-
throw
|
|
562
|
+
const msg = `Could not load user WasmImportsFactory from "${safeUrl}". Ensure that your module path is relative to the project root (location of shallowest vitest config), and that it has a default export matching () => WebAssembly.Imports`;
|
|
563
|
+
throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, msg, error, true);
|
|
677
564
|
}
|
|
678
565
|
}
|
|
679
566
|
|
|
680
567
|
//#endregion
|
|
681
568
|
export { createRpcClient, executeWASMDiscovery, executeWASMTest, flushRpcUpdates, loadUserWasmImportsFactory, reportFileCollected, reportFileError, reportFileQueued, reportSuiteFinished, reportSuitePrepare, reportTestFinished, reportTestPrepare, reportTestRetried, reportUserConsoleLogs };
|
|
682
|
-
//# sourceMappingURL=load-user-imports-
|
|
569
|
+
//# sourceMappingURL=load-user-imports-Bcx9NOt9.mjs.map
|