vitest-pool-assemblyscript 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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-DJB-K27u.mjs} +12 -12
- package/dist/addon-interface-DJB-K27u.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-D4SJWhMh.mjs +82 -0
- package/dist/compile-runner-D4SJWhMh.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-DSKhQ5--.mjs} +55 -27
- package/dist/compiler-DSKhQ5--.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-DLfJqIrE.mjs} +4 -4
- package/dist/{feature-check-Bje3ntpV.mjs.map → feature-check-DLfJqIrE.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-6Pv-9hRg.mjs} +103 -229
- package/dist/load-user-imports-6Pv-9hRg.mjs.map +1 -0
- package/dist/pool-errors-GWfwrsD7.mjs +631 -0
- package/dist/pool-errors-GWfwrsD7.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-Cta6aVJ6.mjs} +15 -30
- package/dist/pool-runner-init-Cta6aVJ6.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-M21HMDdH.mjs +147 -0
- package/dist/test-runner-M21HMDdH.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-Coc4btUw.mjs +473 -0
- package/dist/vitest-file-tasks-Coc4btUw.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-Coc4btUw.mjs";
|
|
3
|
+
import { abortWASMExecution, abortWASMExecutionOnSuccess, createPoolError, debug, debugOverride, enhanceTestError, extractCallStack, getExpectedMessageOrAny, wrapPoolError } from "./pool-errors-GWfwrsD7.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 = "") => {
|
|
@@ -170,7 +102,7 @@ function createUserWasmImports(createWasmImports, memory, module, logPrefix) {
|
|
|
170
102
|
delete userCustomEnvImports.env;
|
|
171
103
|
}
|
|
172
104
|
} catch (error) {
|
|
173
|
-
throw
|
|
105
|
+
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
106
|
}
|
|
175
107
|
return {
|
|
176
108
|
userEnvImports,
|
|
@@ -190,18 +122,15 @@ function createDiscoveryImports(memory, module, file, handleLog, logPrefix, cove
|
|
|
190
122
|
memory,
|
|
191
123
|
abort(msgPtr, filePtr, line, column) {
|
|
192
124
|
const { message, location } = decodeAbortInfo(memory, msgPtr, filePtr, line, column);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const rawCallStack = extractCallStack(/* @__PURE__ */ new Error());
|
|
196
|
-
const testError = {
|
|
125
|
+
debug(`${logPrefix} - Unexpected abort during test discovery: ${`${message}${location ? ` at ${location}` : ""}`}`);
|
|
126
|
+
throw abortWASMExecution({
|
|
197
127
|
message,
|
|
198
128
|
name: TEST_ERROR_NAMES.WASMRuntimeError
|
|
199
|
-
};
|
|
200
|
-
throw createPoolError(msgAtLoc, POOL_ERROR_NAMES.WASMExecutionAbortError, void 0, testError, rawCallStack);
|
|
129
|
+
}, /* @__PURE__ */ new Error());
|
|
201
130
|
}
|
|
202
131
|
},
|
|
203
132
|
["__as_pool_env__"]: {
|
|
204
|
-
...coverageMemory ? { __coverage_memory: coverageMemory } : {},
|
|
133
|
+
...coverageMemory ? { ["__coverage_memory"]: coverageMemory } : {},
|
|
205
134
|
__assertion_pass() {},
|
|
206
135
|
__assertion_fail() {},
|
|
207
136
|
__expect_throw() {},
|
|
@@ -238,6 +167,7 @@ function createDiscoveryImports(memory, module, file, handleLog, logPrefix, cove
|
|
|
238
167
|
* runtime aborts as expected cases for test execution by capturing the error on the test meta.
|
|
239
168
|
*/
|
|
240
169
|
function createTestExecutionImports(memory, module, test, handleLog, logPrefix, coverageMemory, createWasmImports) {
|
|
170
|
+
let lastFailedAssertion;
|
|
241
171
|
let isExpectingError = false;
|
|
242
172
|
let expectedErrorMsgStr;
|
|
243
173
|
let wasmFunctionTable;
|
|
@@ -255,72 +185,72 @@ function createTestExecutionImports(memory, module, test, handleLog, logPrefix,
|
|
|
255
185
|
if (isExpectingError) if (!expectedErrorMsgStr || message.includes(expectedErrorMsgStr)) {
|
|
256
186
|
test.meta.assertionsPassedCount++;
|
|
257
187
|
debug(`${logPrefix} - Thrown error matches expected - assertion passes`);
|
|
258
|
-
throw
|
|
188
|
+
throw abortWASMExecutionOnSuccess();
|
|
259
189
|
} else {
|
|
260
|
-
|
|
261
|
-
|
|
190
|
+
const expected = getExpectedMessageOrAny(expectedErrorMsgStr);
|
|
191
|
+
failureMessage = `expected function to throw error ${expected}, but received error "${message}"`;
|
|
192
|
+
lastFailedAssertion = {
|
|
262
193
|
message: failureMessage,
|
|
263
|
-
|
|
194
|
+
actualTypeName: "string",
|
|
195
|
+
expectedTypeName: "string",
|
|
264
196
|
valuesProvided: true,
|
|
265
197
|
actual: message,
|
|
266
198
|
expected: expectedErrorMsgStr
|
|
267
|
-
}
|
|
268
|
-
debug(`${logPrefix} - Assertion failed: ${`Thrown error does not match expected | Expected:
|
|
199
|
+
};
|
|
200
|
+
debug(`${logPrefix} - Assertion failed: ${`Thrown error does not match expected | Expected: ${expected} | Actual: "${message}"`}`);
|
|
269
201
|
}
|
|
270
|
-
|
|
271
|
-
throw createPoolError(`AssemblyScript abort() import called during test execution for ${test.name}`, POOL_ERROR_NAMES.WASMExecutionAbortError);
|
|
202
|
+
throw abortWASMExecution(lastFailedAssertion ? failTestAssertionError(test, lastFailedAssertion) : failTestRuntimeError(test, "", failureMessage), /* @__PURE__ */ new Error());
|
|
272
203
|
}
|
|
273
204
|
},
|
|
274
205
|
["__as_pool_env__"]: {
|
|
275
|
-
...coverageMemory ? { __coverage_memory: coverageMemory } : {},
|
|
206
|
+
...coverageMemory ? { ["__coverage_memory"]: coverageMemory } : {},
|
|
276
207
|
__register_test() {},
|
|
277
208
|
__begin_register_suite() {},
|
|
278
209
|
__end_register_suite() {},
|
|
279
210
|
__assertion_pass() {
|
|
280
211
|
test.meta.assertionsPassedCount++;
|
|
281
212
|
},
|
|
282
|
-
__assertion_fail(msgPtr,
|
|
283
|
-
const errorMsg = liftString(memory, msgPtr);
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
let
|
|
287
|
-
|
|
213
|
+
__assertion_fail(msgPtr, actualTypeNamePtr, expectedTypeNamePtr, valuesProvided, actualPtr, expectedPtr) {
|
|
214
|
+
const errorMsg = liftString(memory, msgPtr) ?? "";
|
|
215
|
+
const actualTypeName = liftString(memory, actualTypeNamePtr) ?? "";
|
|
216
|
+
const expectedTypeName = liftString(memory, expectedTypeNamePtr) ?? "";
|
|
217
|
+
let valuesMsg = " | No Values Provided";
|
|
218
|
+
lastFailedAssertion = {
|
|
219
|
+
actualTypeName,
|
|
220
|
+
expectedTypeName,
|
|
288
221
|
message: errorMsg,
|
|
289
|
-
typeName: assertionValueType,
|
|
290
222
|
valuesProvided: Boolean(valuesProvided)
|
|
291
223
|
};
|
|
224
|
+
test.meta.assertionsFailed.push(lastFailedAssertion);
|
|
292
225
|
if (valuesProvided && actualPtr && expectedPtr) {
|
|
293
|
-
|
|
294
|
-
|
|
226
|
+
lastFailedAssertion.actual = liftString(memory, actualPtr);
|
|
227
|
+
lastFailedAssertion.expected = liftString(memory, expectedPtr);
|
|
228
|
+
valuesMsg = ` | Actual Type: ${actualTypeName} | Expected Type: ${expectedTypeName} | Actual Value: \`${lastFailedAssertion.actual}\` | Expected Value: \`${lastFailedAssertion.expected}\``;
|
|
295
229
|
}
|
|
296
|
-
|
|
297
|
-
debug(`${logPrefix} - Assertion failed: ${errorMsg}${valuesProvided ? ` | Value Type: ${assertionValueType} | Expected: \`${expected !== void 0 ? expected : ""}\` | Actual: \`${actual !== void 0 ? actual : ""}\`` : ""}`);
|
|
230
|
+
debug(`${logPrefix} - Assertion failed: ${errorMsg}${valuesMsg}`);
|
|
298
231
|
},
|
|
299
232
|
__expect_throw(fnIndex, expectedErrorMsgPtr) {
|
|
300
233
|
isExpectingError = true;
|
|
301
234
|
if (expectedErrorMsgPtr) expectedErrorMsgStr = liftString(memory, expectedErrorMsgPtr);
|
|
302
|
-
debug(`${logPrefix} - Registered expected error throw: ${expectedErrorMsgStr
|
|
235
|
+
debug(`${logPrefix} - Registered expected error throw: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`);
|
|
303
236
|
if (wasmFunctionTable && typeof wasmFunctionTable.get === "function") {
|
|
304
237
|
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}"
|
|
238
|
+
if (!fn) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Could not access function (fnPtr ${fnIndex}) which is expected to throw in test "${test.name}"`);
|
|
306
239
|
debug(`${logPrefix} - Calling function (idx ${fnIndex})`);
|
|
307
240
|
fn();
|
|
308
|
-
} else throw createPoolError(`Could not access WASM function table to call function expected to throw
|
|
241
|
+
} else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Could not access WASM function table to call function expected to throw`);
|
|
309
242
|
},
|
|
310
243
|
__end_expect_throw() {
|
|
311
244
|
if (isExpectingError) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
valuesProvided:
|
|
245
|
+
debug(`${logPrefix} - Assertion failed: ${`Expected thrown error but got none | Expected: "${expectedErrorMsgStr}"`}`);
|
|
246
|
+
throw abortWASMExecution(failTestAssertionError(test, {
|
|
247
|
+
message: `function did not throw, but was expected to throw error: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`,
|
|
248
|
+
actualTypeName: "undefined",
|
|
249
|
+
expectedTypeName: "string",
|
|
250
|
+
valuesProvided: true,
|
|
318
251
|
actual: void 0,
|
|
319
252
|
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);
|
|
253
|
+
}));
|
|
324
254
|
}
|
|
325
255
|
}
|
|
326
256
|
},
|
|
@@ -334,112 +264,43 @@ function createTestExecutionImports(memory, module, test, handleLog, logPrefix,
|
|
|
334
264
|
}
|
|
335
265
|
|
|
336
266
|
//#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
|
-
}));
|
|
267
|
+
//#region src/wasm-executor/index.ts
|
|
268
|
+
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.";
|
|
269
|
+
function verifyMemoryRequirements(compilation, poolOptions) {
|
|
270
|
+
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.`);
|
|
271
|
+
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.`);
|
|
272
|
+
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.`);
|
|
273
|
+
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
274
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const sourceMappedStack = await sourceMapRawCallStack(rawCallStack, sourceMapObj, loggingPrefix);
|
|
361
|
-
debug(`${loggingPrefix} - Mapped ${rawCallStack.length} call sites to ${sourceMappedStack.length} source locations`);
|
|
275
|
+
function createExecutorMemories(compilation, poolOptions, includeCoverageMemory) {
|
|
276
|
+
verifyMemoryRequirements(compilation, poolOptions);
|
|
362
277
|
return {
|
|
363
|
-
|
|
364
|
-
|
|
278
|
+
testMemory: createMemory(poolOptions.testMemoryPagesInitial ?? compilation.requiredMemory.testMemory.initialPages, poolOptions.testMemoryPagesMax ?? compilation.requiredMemory.testMemory.maximumPages),
|
|
279
|
+
coverageMemory: includeCoverageMemory ? createMemory(poolOptions.coverageMemoryPagesInitial ?? compilation.requiredMemory.coverageMemory.initialPages, poolOptions.coverageMemoryPagesMax ?? compilation.requiredMemory.coverageMemory.maximumPages) : void 0
|
|
365
280
|
};
|
|
366
281
|
}
|
|
367
282
|
/**
|
|
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
283
|
* Discover tests via test() and suites via describe() registration calls
|
|
409
284
|
*/
|
|
410
|
-
async function executeWASMDiscovery(
|
|
285
|
+
async function executeWASMDiscovery(compilation, poolOptions, isBinaryInstrumented, handleLog, file, moduleLabel, threadImports) {
|
|
411
286
|
const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(basename(file.filepath), file)}`;
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
exports._start();
|
|
287
|
+
try {
|
|
288
|
+
const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, isBinaryInstrumented);
|
|
289
|
+
const importObject = createDiscoveryImports(testMemory, compilation.compiledModule, file, handleLog, logPrefix, coverageMemory, threadImports.createUserWasmImports);
|
|
290
|
+
const exports = new WebAssembly.Instance(compilation.compiledModule, importObject).exports;
|
|
291
|
+
if (typeof exports._start === "function") exports._start();
|
|
292
|
+
else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "no _start() export found on compiled WASM binary");
|
|
417
293
|
} catch (error) {
|
|
418
|
-
|
|
419
|
-
if (error
|
|
420
|
-
|
|
421
|
-
const stack = extractCallStack(runtimeError);
|
|
422
|
-
const testError = await enhanceTestError({
|
|
423
|
-
name: TEST_ERROR_NAMES.WASMRuntimeError,
|
|
424
|
-
message: runtimeError.message
|
|
425
|
-
}, file, sourceMap, false, logPrefix, stack, diffOptions);
|
|
426
|
-
throw createPoolError(`${SIG_MISMATCH_ERROR_MSG}\n Caused by: ${runtimeError.name}: ${runtimeError.message}`, POOL_ERROR_NAMES.PoolSyntaxError, void 0, testError);
|
|
427
|
-
}
|
|
428
|
-
if (thrownErrAny?.name === POOL_ERROR_NAMES.WASMExecutionAbortError && thrownErrAny?.cause?.name === TEST_ERROR_NAMES.WASMRuntimeError && error.rawCallStack) {
|
|
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);
|
|
294
|
+
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);
|
|
295
|
+
if (error && error["__as_pool_error__"]) throw error;
|
|
296
|
+
else throw wrapPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, error, true);
|
|
435
297
|
}
|
|
436
|
-
else throw createExecutorPoolError(testFileBasename, "discoverTests", "no _start() export");
|
|
437
298
|
debug(`${logPrefix} - Discovered ${file.tasks.length} top-level tasks`);
|
|
438
299
|
}
|
|
439
300
|
/**
|
|
440
301
|
* Execute a single test with crash isolation
|
|
441
302
|
*/
|
|
442
|
-
async function executeWASMTest(test, compilation,
|
|
303
|
+
async function executeWASMTest(test, compilation, poolOptions, collectCoverage, handleLog, moduleLabel, threadImports, projectRoot, diffOptions) {
|
|
443
304
|
const testTimings = {
|
|
444
305
|
fnInit: performance.now(),
|
|
445
306
|
execStart: 0,
|
|
@@ -451,40 +312,51 @@ async function executeWASMTest(test, compilation, testFileBasename, poolOptions,
|
|
|
451
312
|
function covDebug(...args) {
|
|
452
313
|
if (poolOptions.debugCoverageExtract) debugOverride(...args);
|
|
453
314
|
}
|
|
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;
|
|
315
|
+
const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, collectCoverage);
|
|
316
|
+
const { imports, provideFunctionTable } = createTestExecutionImports(testMemory, compilation.compiledModule, test, handleLog, logPrefix, coverageMemory, threadImports.createUserWasmImports);
|
|
317
|
+
const exports = new WebAssembly.Instance(compilation.compiledModule, imports).exports;
|
|
459
318
|
const table = exports.table;
|
|
460
319
|
if (table && typeof table.get === "function") provideFunctionTable(table);
|
|
461
320
|
if (typeof exports._start === "function") exports._start();
|
|
462
|
-
else throw
|
|
321
|
+
else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "no _start() export found on compiled WASM binary");
|
|
463
322
|
let testFn;
|
|
464
323
|
if (table && typeof table.get === "function") {
|
|
465
324
|
const idx = test.meta.fnIndex;
|
|
466
325
|
testFn = table.get(idx);
|
|
467
|
-
if (!testFn) throw
|
|
468
|
-
} else throw
|
|
326
|
+
if (!testFn) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, `Test function at index ${idx} not found in function table`);
|
|
327
|
+
} else throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "Function table not found in WASM exports (missing --exportTable flag?)");
|
|
469
328
|
try {
|
|
470
329
|
testTimings.execStart = performance.now();
|
|
471
330
|
testFn();
|
|
472
331
|
testTimings.execEnd = performance.now();
|
|
473
332
|
} catch (error) {
|
|
474
333
|
testTimings.execEnd = performance.now();
|
|
475
|
-
|
|
334
|
+
let testError;
|
|
335
|
+
let stack;
|
|
336
|
+
let allowStackJS;
|
|
337
|
+
let applyStackToTestErrorCause;
|
|
338
|
+
if (error && error["__as_pool_error__"]) {
|
|
339
|
+
const wrapper = error;
|
|
340
|
+
testError = wrapper.testError;
|
|
341
|
+
stack = wrapper.originalErrorRawStack;
|
|
342
|
+
allowStackJS = wrapper.originalErrorMayContainJS;
|
|
343
|
+
applyStackToTestErrorCause = wrapper.applyStackToTestErrorCause;
|
|
344
|
+
} else if (error instanceof Error) {
|
|
345
|
+
testError = failTestRuntimeError(test, error.name, error.message);
|
|
346
|
+
stack = extractCallStack(error);
|
|
347
|
+
allowStackJS = true;
|
|
348
|
+
applyStackToTestErrorCause = false;
|
|
349
|
+
} else {
|
|
350
|
+
testError = failTestRuntimeError(test, "", `Unexpected WASM test execution error: ${String(error)}`);
|
|
351
|
+
stack = extractCallStack(/* @__PURE__ */ new Error());
|
|
352
|
+
allowStackJS = true;
|
|
353
|
+
applyStackToTestErrorCause = false;
|
|
354
|
+
}
|
|
355
|
+
await enhanceTestError(testError, test, compilation.sourceMap, logPrefix, allowStackJS, projectRoot, applyStackToTestErrorCause, stack, diffOptions);
|
|
476
356
|
}
|
|
477
357
|
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
358
|
if (collectCoverage && compilation.debugInfo) {
|
|
487
|
-
if (!coverageMemory) throw
|
|
359
|
+
if (!coverageMemory) throw createPoolError(POOL_ERROR_NAMES.WASMExecutionHarnessError, "Coverage memory not created despite collectCoverage=true");
|
|
488
360
|
const coverage = { hitCountsByFileAndPosition: {} };
|
|
489
361
|
const extractedHitCounters = new Uint32Array(coverageMemory.buffer, 0, compilation.debugInfo.instrumentedFunctionCount);
|
|
490
362
|
covDebug(`${logPrefix} - Read coverage memory for ${compilation.debugInfo.instrumentedFunctionCount} instrumented functions`);
|
|
@@ -668,15 +540,17 @@ async function loadUserWasmImportsFactory(relativePath, projectRoot, logModule)
|
|
|
668
540
|
try {
|
|
669
541
|
const start = performance.now();
|
|
670
542
|
const createWasmImports = (await import(safeUrl)).default;
|
|
671
|
-
debug(`[${logModule}]
|
|
672
|
-
if (typeof createWasmImports !== "function")
|
|
673
|
-
|
|
543
|
+
debug(`[${logModule}] Imported user WasmImportsFactory "${safeUrl}" | TIMING ${(performance.now() - start).toFixed(2)} ms`);
|
|
544
|
+
if (typeof createWasmImports !== "function") {
|
|
545
|
+
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}"`;
|
|
546
|
+
throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, msg);
|
|
547
|
+
} else return createWasmImports;
|
|
674
548
|
} catch (error) {
|
|
675
|
-
|
|
676
|
-
throw
|
|
549
|
+
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`;
|
|
550
|
+
throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, msg, error, true);
|
|
677
551
|
}
|
|
678
552
|
}
|
|
679
553
|
|
|
680
554
|
//#endregion
|
|
681
555
|
export { createRpcClient, executeWASMDiscovery, executeWASMTest, flushRpcUpdates, loadUserWasmImportsFactory, reportFileCollected, reportFileError, reportFileQueued, reportSuiteFinished, reportSuitePrepare, reportTestFinished, reportTestPrepare, reportTestRetried, reportUserConsoleLogs };
|
|
682
|
-
//# sourceMappingURL=load-user-imports-
|
|
556
|
+
//# sourceMappingURL=load-user-imports-6Pv-9hRg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-user-imports-6Pv-9hRg.mjs","names":[],"sources":["../src/wasm-executor/wasm-console.ts","../src/wasm-executor/collect-options.ts","../src/wasm-executor/wasm-imports.ts","../src/wasm-executor/index.ts","../src/pool-thread/rpc-reporter.ts","../src/pool-thread/load-user-imports.ts"],"sourcesContent":["import type { AssemblyScriptConsoleLogHandler } from '../types/types.js';\nimport { liftString } from '../util/assemblyscript/binding-helpers.js';\n\nexport function createWasmConsole(\n memory: WebAssembly.Memory,\n handleLog: AssemblyScriptConsoleLogHandler\n) {\n const getMessage = (msgPtr: number, memory: WebAssembly.Memory, prefix: string = ''): string => {\n return `${prefix}${msgPtr ? liftString(memory, msgPtr) : '<no message>'}`;\n };\n\n const timersByLabel: { [label: string]: number } = {};\n\n // provides the AssemblyScript \"brower-like console\" from AS std lib\n // see https://github.com/AssemblyScript/assemblyscript/blob/v0.28.9/std/assembly/index.d.ts#L2609\n return {\n 'console.assert': <T>(assertion: T, msgPtr: number): void => {\n if (!assertion) {\n const msg = getMessage(msgPtr, memory);\n handleLog(`Assertion failed${msg ? `: ${msg}` : ''}`);\n }\n },\n 'console.log': (msgPtr: number): void => {\n handleLog(getMessage(msgPtr, memory));\n },\n 'console.debug': (msgPtr: number): void => {\n handleLog(getMessage(msgPtr, memory, 'Debug: '));\n },\n 'console.info': (msgPtr: number): void => {\n handleLog(getMessage(msgPtr, memory, 'Info: '));\n },\n 'console.warn': (msgPtr: number): void => {\n handleLog(getMessage(msgPtr, memory, 'Warning: '), true);\n },\n 'console.error': (msgPtr: number): void => {\n handleLog(getMessage(msgPtr, memory, 'Error: '), true);\n },\n 'console.time': (labelPtr?: number): void => {\n const label = labelPtr ? liftString(memory, labelPtr) ?? 'default' : 'default';\n timersByLabel[label] = performance.now();\n },\n 'console.timeLog': (labelPtr?: number): void => {\n const label = labelPtr ? liftString(memory, labelPtr) ?? 'default' : 'default';\n const start = timersByLabel[label];\n let msg = '';\n if (start === undefined) {\n msg = `Warning: No such label '${label}' for console.timeLog()`;\n } else {\n msg = `${label}: ${(performance.now() - start).toFixed(3)}ms`;\n }\n handleLog(msg);\n },\n 'console.timeEnd': (labelPtr?: number): void => {\n const label = labelPtr ? liftString(memory, labelPtr) ?? 'default' : 'default';\n const start = timersByLabel[label];\n let msg = '';\n if (start === undefined) {\n msg = `Warning: No such label '${label}' for console.timeLog()`;\n } else {\n msg = `${label}: ${(performance.now() - start).toFixed(3)}ms`;\n }\n handleLog(msg);\n delete timersByLabel[label];\n },\n\n trace(msgPtr: number, n: number, a0: any, a1: any, a2: any, a3: any): void {\n const msg = liftString(memory, msgPtr);\n const args: any[] = [a0, a1, a2, a3];\n const nArgs: any[] = n && n > 0 ? args.slice(0, n) : args;\n\n console.trace(`WASM Trace:${msg ? ` ${msg}` : ''}`, ...nArgs);\n },\n };\n}\n","import { AssemblyScriptTestOptions } from '../types/types.js';\n\nconst TEST_OPTION_UNDEFINED: number = -1;\nconst TEST_OPTION_TRUE: number = 1;\n\nexport function mergeAssemblyScriptTestOptions(\n baseOptions: AssemblyScriptTestOptions,\n timeout: number,\n retry: number,\n skip: number,\n only: number,\n fails: number,\n): AssemblyScriptTestOptions {\n const options: AssemblyScriptTestOptions = { ...baseOptions };\n \n // numerical options\n if (timeout > TEST_OPTION_UNDEFINED) {\n options.timeout = timeout;\n }\n if (retry > TEST_OPTION_UNDEFINED) {\n options.retry = retry;\n }\n\n // boolean options\n if (skip > TEST_OPTION_UNDEFINED) {\n options.skip = skip === TEST_OPTION_TRUE ? true : false;\n }\n if (only > TEST_OPTION_UNDEFINED) {\n options.only = only === TEST_OPTION_TRUE ? true : false;\n }\n if (fails > TEST_OPTION_UNDEFINED) {\n options.fails = fails === TEST_OPTION_TRUE ? true : false;\n }\n\n return options;\n}\n","import type { File, Suite, Test } from '@vitest/runner/types';\n\nimport type {\n AssemblyScriptConsoleLogHandler,\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestError,\n AssemblyScriptTestTaskMeta,\n FailedAssertion,\n WasmImportsFactory,\n} from '../types/types.js';\nimport {\n AS_POOL_WASM_COVERAGE_MEM_IMPORT_NAME,\n AS_POOL_WASM_IMPORTS_MODULE_NAME,\n POOL_ERROR_NAMES,\n TEST_ERROR_NAMES\n} from '../types/constants.js';\nimport { debug } from '../util/debug.js';\nimport { abortWASMExecution, abortWASMExecutionOnSuccess, createPoolError, getExpectedMessageOrAny } from '../util/pool-errors.js';\nimport { liftString } from '../util/assemblyscript/binding-helpers.js';\nimport { decodeAbortInfo } from './wasm-memory.js';\nimport { createWasmConsole } from './wasm-console.js';\nimport { mergeAssemblyScriptTestOptions } from './collect-options.js';\nimport { createSuiteTask, createTestTask, failTestAssertionError, failTestRuntimeError } from '../util/vitest-tasks.js';\n\nfunction createUserWasmImports(\n createWasmImports: WasmImportsFactory | undefined,\n memory: WebAssembly.Memory,\n module: WebAssembly.Module,\n logPrefix: string\n) {\n let userEnvImports: WebAssembly.ModuleImports | undefined;\n let userCustomEnvImports: WebAssembly.Imports | undefined;\n\n if (createWasmImports) {\n try {\n const start = performance.now();\n const userImports: WebAssembly.Imports = createWasmImports({\n memory,\n module,\n utils: {\n liftString: (stringPtr: number) => liftString(memory, stringPtr)\n }\n });\n debug(`${logPrefix} Created user WASM imports for test execution in ${(performance.now() - start).toFixed(2)} ms`);\n\n userEnvImports = userImports?.env;\n \n if (userEnvImports) {\n userCustomEnvImports = { ...userImports };\n delete userCustomEnvImports.env;\n }\n } catch (error) {\n const msg = `Could not create user WasmImportsFactory.`\n + ` Ensure that your module has a default export matching () => WebAssembly.Imports`;\n throw createPoolError(\n POOL_ERROR_NAMES.WASMUserImportsError,\n msg,\n error,\n true\n );\n }\n }\n\n return { userEnvImports, userCustomEnvImports };\n}\n\n/**\n * Create import object for test discovery\n */\nexport function createDiscoveryImports(\n memory: WebAssembly.Memory,\n module: WebAssembly.Module,\n file: File,\n handleLog: AssemblyScriptConsoleLogHandler,\n logPrefix: string,\n coverageMemory?: WebAssembly.Memory,\n createWasmImports?: WasmImportsFactory,\n): WebAssembly.Imports {\n const suiteStack: Suite[] = [file];\n\n const {\n userEnvImports,\n userCustomEnvImports\n } = createUserWasmImports(createWasmImports, memory, module, logPrefix);\n \n return {\n env: {\n // users can choose to hide these with their own\n ...createWasmConsole(memory, handleLog),\n\n // user imports for \"env\"\n ...(userEnvImports ?? {}),\n\n memory,\n\n // handle runtime aborts, which are always unexpected during discovery\n abort(msgPtr: number, filePtr: number, line: number, column: number) {\n const { message, location } = decodeAbortInfo(memory, msgPtr, filePtr, line, column);\n const msgAtLoc = `${message}${location ? ` at ${location}` : ''}`;\n \n debug(`${logPrefix} - Unexpected abort during test discovery: ${msgAtLoc}`);\n\n const testError: AssemblyScriptTestError = {\n message,\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n };\n\n throw abortWASMExecution(testError, new Error());\n },\n },\n\n [AS_POOL_WASM_IMPORTS_MODULE_NAME]: {\n\n ...(coverageMemory ? { [AS_POOL_WASM_COVERAGE_MEM_IMPORT_NAME]: coverageMemory } : {}),\n\n // stubs during discovery\n __assertion_pass() {},\n __assertion_fail() {},\n __expect_throw() {},\n __end_expect_throw() {},\n\n __begin_register_suite(\n namePtr: number,\n timeout: number,\n retry: number,\n skip: number,\n only: number,\n fails: number,\n ) {\n const parentSuite = suiteStack[suiteStack.length - 1]!;\n const defaultTestOptions = (parentSuite.meta as AssemblyScriptSuiteTaskMeta).defaultTestOptions;\n const suiteName = liftString(memory, namePtr) ?? 'unknown suite';\n const options = mergeAssemblyScriptTestOptions(defaultTestOptions, timeout, retry, skip, only, fails);\n const suite = createSuiteTask(suiteName, file, parentSuite, options);\n suiteStack.push(suite);\n\n debug(\n `${logPrefix} - Registering Suite \"${suite.name}\" | timeout: ${options.timeout} ms | retry: ${options.retry}`\n + ` | skip: ${options.skip} | only: ${options.only} | fails: ${options.fails} `\n + ` | parent: \"${suite.suite?.name}\" (parent idx: ${(suite.meta as AssemblyScriptSuiteTaskMeta).idxInParentTasks})`\n );\n },\n \n __end_register_suite(_namePtr: number) {\n const suite = suiteStack.pop();\n\n debug(\n `${logPrefix} - Registered Suite \"${suite?.name}\" | ${suite?.tasks.length} top-level tasks | mode: \"${suite?.mode}\"`\n + ` | parent: \"${suite?.suite?.name}\" (parent idx: ${(suite?.meta as AssemblyScriptSuiteTaskMeta)?.idxInParentTasks})`\n );\n },\n\n // called by test() to register test names and function indices\n __register_test(\n namePtr: number,\n fnIndex: number,\n timeout: number,\n retry: number,\n skip: number,\n only: number,\n fails: number,\n ) {\n const parentSuite = suiteStack[suiteStack.length - 1]!;\n const defaultTestOptions = (parentSuite.meta as AssemblyScriptSuiteTaskMeta).defaultTestOptions;\n const testName = liftString(memory, namePtr) ?? 'unknown test';\n const options = mergeAssemblyScriptTestOptions(defaultTestOptions, timeout, retry, skip, only, fails);\n const test = createTestTask(testName, fnIndex, file, parentSuite, options);\n \n debug(`${logPrefix} - Registered test \"${test.name}\" | mode (pre-interp): \"${test.mode}\"`\n + ` | fnIndex ${fnIndex} | timeout: ${options.timeout} ms | retry: ${options.retry} | skip: ${options.skip}`\n + ` | only: ${options.only} | fails: ${options.fails} | suite: \"${test.suite?.name}\"`\n + ` (parent idx: ${(test.meta as AssemblyScriptTestTaskMeta).idxInParentTasks})`\n );\n },\n },\n\n // user imports for any other environments they defined\n ...(userCustomEnvImports ?? {}),\n };\n}\n\n/**\n * Create import object for test execution\n *\n * Used during test execution to capture test results / assertions, and to handle\n * runtime aborts as expected cases for test execution by capturing the error on the test meta.\n */\nexport function createTestExecutionImports(\n memory: WebAssembly.Memory,\n module: WebAssembly.Module,\n test: Test,\n handleLog: AssemblyScriptConsoleLogHandler,\n logPrefix: string,\n coverageMemory?: WebAssembly.Memory,\n createWasmImports?: WasmImportsFactory,\n): { imports: WebAssembly.Imports; provideFunctionTable: (table: WebAssembly.Table) => void; } {\n // execution imports are created per-test, so these represent per-test state\n let lastFailedAssertion: FailedAssertion | undefined;\n let isExpectingError: boolean = false;\n let expectedErrorMsgStr: string | undefined;\n let wasmFunctionTable: WebAssembly.Table | undefined;\n\n const {\n userEnvImports,\n userCustomEnvImports\n } = createUserWasmImports(createWasmImports, memory, module, logPrefix);\n\n const imports = {\n env: {\n // users can choose to hide these with their own\n ...createWasmConsole(memory, handleLog),\n\n // user imports for \"env\"\n ...(userEnvImports ?? {}),\n\n memory,\n\n abort(msgPtr: number, filePtr: number, line: number, column: number) {\n const { message, location } = decodeAbortInfo(memory, msgPtr, filePtr, line, column);\n const msgAtLoc = `${message}${location ? ` at ${location}` : ''}`;\n \n debug(`${logPrefix} - Handling test execution abort: ${msgAtLoc}`);\n\n let failureMessage = message;\n\n // handle expected aborts for thrown errors\n if (isExpectingError) {\n // TODO: decide if .includes is correct here or not\n if (!expectedErrorMsgStr || message.includes(expectedErrorMsgStr)) {\n // either no specifically expected error (any error), or error message matches\n (test.meta as AssemblyScriptTestTaskMeta).assertionsPassedCount++;\n \n debug(`${logPrefix} - Thrown error matches expected - assertion passes`);\n\n // abort without failing the test\n throw abortWASMExecutionOnSuccess();\n } else {\n const expected = getExpectedMessageOrAny(expectedErrorMsgStr);\n\n // error message mismatch\n failureMessage = `expected function to throw error ${expected}, but received error \"${message}\"`;\n\n lastFailedAssertion = {\n message: failureMessage,\n actualTypeName: 'string',\n expectedTypeName: 'string',\n valuesProvided: true,\n actual: message,\n expected: expectedErrorMsgStr\n };\n\n const errStr = `Thrown error does not match expected | Expected: ${expected} | Actual: \"${message}\"`;\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n }\n }\n\n const testError = lastFailedAssertion\n ? failTestAssertionError(test, lastFailedAssertion)\n : failTestRuntimeError(test, '', failureMessage);\n\n throw abortWASMExecution(testError, new Error());\n },\n },\n\n [AS_POOL_WASM_IMPORTS_MODULE_NAME]: {\n \n ...(coverageMemory ? { [AS_POOL_WASM_COVERAGE_MEM_IMPORT_NAME]: coverageMemory } : {}),\n\n // stubs during execution\n __register_test() {},\n __begin_register_suite() {},\n __end_register_suite() {},\n\n __assertion_pass() {\n (test.meta as AssemblyScriptTestTaskMeta).assertionsPassedCount++;\n },\n\n __assertion_fail(msgPtr: number, actualTypeNamePtr: number, expectedTypeNamePtr: number, valuesProvided: boolean, actualPtr?: number, expectedPtr?: number) {\n const errorMsg = liftString(memory, msgPtr) ?? '';\n const actualTypeName = liftString(memory, actualTypeNamePtr) ?? '';\n const expectedTypeName = liftString(memory, expectedTypeNamePtr) ?? '';\n let valuesMsg = ' | No Values Provided';\n \n lastFailedAssertion = {\n actualTypeName,\n expectedTypeName,\n message: errorMsg,\n valuesProvided: Boolean(valuesProvided)\n };\n\n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push(lastFailedAssertion);\n \n if (valuesProvided && actualPtr && expectedPtr) {\n lastFailedAssertion.actual = liftString(memory, actualPtr);\n lastFailedAssertion.expected = liftString(memory, expectedPtr);\n valuesMsg = ` | Actual Type: ${actualTypeName} | Expected Type: ${expectedTypeName}`\n + ` | Actual Value: \\`${lastFailedAssertion.actual}\\` | Expected Value: \\`${lastFailedAssertion.expected}\\``;\n }\n \n debug(`${logPrefix} - Assertion failed: ${errorMsg}${valuesMsg}`);\n },\n\n __expect_throw(fnIndex: number, expectedErrorMsgPtr?: number) {\n isExpectingError = true;\n if (expectedErrorMsgPtr) {\n expectedErrorMsgStr = liftString(memory, expectedErrorMsgPtr);\n }\n\n debug(`${logPrefix} - Registered expected error throw: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`);\n\n if (wasmFunctionTable && typeof wasmFunctionTable.get === 'function') {\n const fn = wasmFunctionTable.get(fnIndex);\n if (!fn) {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n `Could not access function (fnPtr ${fnIndex}) which is expected to throw in test \"${test.name}\"`,\n );\n }\n\n // successful:\n // - throws in WASM, calls abort handler\n // - abort handler confirms error matches expected, does NOT fail test, halts execution with WASMExecutionAbortError\n // - executor catches WASMExecutionAbortError as 'known' and proceeds to process & report passed test\n // failure (wrong error):\n // - throws in WASM, calls abort handler\n // - abort handler confirms error matches mismatch, failTest packages up an appropriate test error\n // - abort handler halts execution with WASMExecutionAbortError containing test error\n // - executor catches WASMExecutionAbortError as 'known' and proceeds to process & report test error\n // failure (no error):\n // - does NOT throw in WASM\n // - WASM continues executing and calls __end_expect_throw\n // - __end_expect_throw sees it is STILL expecting an error, failTest packages up an appropriate test error\n // - __end_expect_throw halts execution with WASMExecutionAbortError containing test error\n // - executor catches WASMExecutionAbortError as 'known' and proceeds to process & report test error\n debug(`${logPrefix} - Calling function (idx ${fnIndex})`);\n fn();\n } else {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n `Could not access WASM function table to call function expected to throw`,\n );\n }\n },\n\n __end_expect_throw() {\n if (isExpectingError) {\n const errStr = `Expected thrown error but got none | Expected: \"${expectedErrorMsgStr}\"`;\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n \n const failureMessage = `function did not throw, but was expected to throw error: ${getExpectedMessageOrAny(expectedErrorMsgStr)}`;\n const testError = failTestAssertionError(test, {\n message: failureMessage,\n actualTypeName: 'undefined',\n expectedTypeName: 'string',\n valuesProvided: true,\n actual: undefined,\n expected: expectedErrorMsgStr\n });\n\n // Must throw here to halt WASM execution on an assertion or runtime failure for this test.\n // This will be caught by the executor and reported as an appropriate test error\n throw abortWASMExecution(testError);\n }\n },\n },\n\n // user imports for any other environments they defined\n ...(userCustomEnvImports ?? {}),\n };\n\n return {\n imports,\n provideFunctionTable: (table: WebAssembly.Table) => {\n debug(`${logPrefix} - Got WASM function table | length: ${table.length}`);\n wasmFunctionTable = table;\n },\n };\n}\n","import { basename } from 'node:path';\nimport type { SerializedDiffOptions } from '@vitest/utils/diff';\nimport type { File, Test } from '@vitest/runner/types';\n\nimport type {\n AssemblyScriptConsoleLogHandler,\n AssemblyScriptPoolError,\n AssemblyScriptTestError,\n AssemblyScriptTestTaskMeta,\n CoverageData,\n ResolvedAssemblyScriptPoolOptions,\n ThreadImports,\n WASMCompilation,\n WASMExecutorPerfTimings,\n} from '../types/types.js';\nimport { AS_POOL_ERROR_FLAG, POOL_ERROR_NAMES } from '../types/constants.js';\nimport { debug, debugOverride } from '../util/debug.js';\nimport { createMemory } from './wasm-memory.js';\nimport { createDiscoveryImports, createTestExecutionImports } from './wasm-imports.js';\nimport { enhanceTestError } from './wasm-errors.js';\nimport { createPoolError, wrapPoolError } from '../util/pool-errors.js';\nimport { failTestRuntimeError, getTaskLogLabel } from '../util/vitest-tasks.js';\nimport { extractCallStack } from './source-maps.js';\n\nconst SIG_MISMATCH_ERROR_MSG = `WASM function signature type mismatch during test collection.`\n + ` This is most likely caused by passing a type-inferred, non-void callback to expect().`\n + ` To fix, either explicitly define the non-void return type on the callback`\n + ` e.g. \\`expect((): i32 => failingFunction()).toThrowError()\\``\n + ` or use braces to make it void e.g. \\`expect(() => { failingFunction(); }).toThrowError()\\`.`\n + ` Look for the failing expect() within the describe() block indicated in the stack trace.`;\n\nfunction verifyMemoryRequirements(\n compilation: WASMCompilation,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n) {\n if (poolOptions.testMemoryPagesInitial && poolOptions.testMemoryPagesInitial < compilation.requiredMemory.testMemory.initialPages) {\n throw createPoolError(\n POOL_ERROR_NAMES.PoolConfigError,\n `WASM binary requires initial test memory pages (${compilation.requiredMemory.testMemory.initialPages}) exceeding configured \"testMemoryPagesInitial\"`\n + ` (${poolOptions.testMemoryPagesInitial}). Increase value, or remove for auto sizing.`,\n );\n }\n \n if (poolOptions.testMemoryPagesMax && compilation.requiredMemory.testMemory.maximumPages\n && poolOptions.testMemoryPagesMax < compilation.requiredMemory.testMemory.maximumPages\n ) {\n throw createPoolError(\n POOL_ERROR_NAMES.PoolConfigError,\n `WASM binary requires maximum test memory pages (${compilation.requiredMemory.testMemory.maximumPages}) exceeding configured \"testMemoryPagesMax\"`\n + ` (${poolOptions.testMemoryPagesMax}). Increase value, or remove for auto sizing.`,\n );\n }\n \n if (poolOptions.coverageMemoryPagesInitial && poolOptions.coverageMemoryPagesInitial < compilation.requiredMemory.coverageMemory.initialPages) {\n throw createPoolError(\n POOL_ERROR_NAMES.PoolConfigError,\n `WASM binary requires initial coverage memory pages (${compilation.requiredMemory.coverageMemory.initialPages}) exceeding configured \"coverageMemoryPagesInitial\"`\n + ` (${poolOptions.coverageMemoryPagesInitial}). Increase value, or remove for auto sizing.`,\n );\n }\n\n if (poolOptions.coverageMemoryPagesMax && compilation.requiredMemory.coverageMemory.maximumPages\n && poolOptions.coverageMemoryPagesMax < compilation.requiredMemory.coverageMemory.maximumPages\n ) {\n throw createPoolError(\n POOL_ERROR_NAMES.PoolConfigError,\n `WASM binary requires maximum coverage memory pages (${compilation.requiredMemory.coverageMemory.maximumPages}) exceeding configured \"coverageMemoryPagesMax\"`\n + ` (${poolOptions.coverageMemoryPagesMax}). Increase value, or remove for auto sizing.`,\n );\n }\n}\n\nfunction createExecutorMemories(\n compilation: WASMCompilation,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n includeCoverageMemory: boolean,\n): { testMemory: WebAssembly.Memory; coverageMemory?: WebAssembly.Memory } {\n verifyMemoryRequirements(compilation, poolOptions);\n\n const testMemory = createMemory(\n poolOptions.testMemoryPagesInitial ?? compilation.requiredMemory.testMemory.initialPages,\n poolOptions.testMemoryPagesMax ?? compilation.requiredMemory.testMemory.maximumPages\n );\n const coverageMemory = includeCoverageMemory ?\n createMemory(\n poolOptions.coverageMemoryPagesInitial ?? compilation.requiredMemory.coverageMemory.initialPages,\n poolOptions.coverageMemoryPagesMax ?? compilation.requiredMemory.coverageMemory.maximumPages\n )\n : undefined;\n\n return { testMemory, coverageMemory };\n}\n\n/**\n * Discover tests via test() and suites via describe() registration calls\n */\nexport async function executeWASMDiscovery(\n compilation: WASMCompilation,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n isBinaryInstrumented: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n file: File,\n moduleLabel: string,\n threadImports: ThreadImports,\n): Promise<void> {\n const base = basename(file.filepath);\n const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(base, file)}`;\n \n try {\n const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, isBinaryInstrumented);\n\n const importObject = createDiscoveryImports(\n testMemory,\n compilation.compiledModule,\n file,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createUserWasmImports\n );\n\n // Instantiate WASM module\n const instance = new WebAssembly.Instance(compilation.compiledModule, importObject);\n const exports = instance.exports as Record<string, unknown>;\n\n // Call _start to run top-level test() and describe()\n if (typeof exports._start === 'function') {\n exports._start();\n } else {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n 'no _start() export found on compiled WASM binary'\n );\n }\n } catch (error: any) {\n const isFunctionSignatureMismatch: boolean = error instanceof WebAssembly.RuntimeError\n && error?.message.includes('null function or function signature mismatch');\n if (isFunctionSignatureMismatch) {\n throw createPoolError(\n POOL_ERROR_NAMES.PoolSyntaxError,\n SIG_MISMATCH_ERROR_MSG,\n error\n );\n } \n\n if (error && error[AS_POOL_ERROR_FLAG]) {\n throw error;\n } else {\n throw wrapPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n error,\n true\n );\n }\n }\n\n debug(`${logPrefix} - Discovered ${file.tasks.length} top-level tasks`);\n return;\n}\n\n/**\n * Execute a single test with crash isolation\n */\nexport async function executeWASMTest(\n test: Test,\n compilation: WASMCompilation,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n collectCoverage: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n moduleLabel: string,\n threadImports: ThreadImports,\n projectRoot: string,\n diffOptions?: SerializedDiffOptions,\n): Promise<{ test: Test, testTimings: WASMExecutorPerfTimings }> {\n const testTimings: WASMExecutorPerfTimings = {\n fnInit: performance.now(),\n execStart: 0,\n execEnd: 0,\n fnfinal: 0\n };\n const base = basename(test.file.filepath);\n const fullModuleLabel = `${moduleLabel} Exec`;\n const taskLabel = getTaskLogLabel(base, test);\n const logPrefix = `[${fullModuleLabel}] ${taskLabel}`;\n\n function covDebug(...args: any[]): void {\n if (poolOptions.debugCoverageExtract) {\n debugOverride(...args);\n }\n };\n\n const { testMemory, coverageMemory } = createExecutorMemories(compilation, poolOptions, collectCoverage);\n\n // Create import object with pool-side functions for capturing test execution results\n const { imports, provideFunctionTable } = createTestExecutionImports(\n testMemory,\n compilation.compiledModule,\n test,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createUserWasmImports\n );\n\n // Instantiate fresh WASM instance for this test\n const instance = new WebAssembly.Instance(compilation.compiledModule, imports);\n const exports = instance.exports as Record<string, unknown>;\n\n // Func table accessable because we're using the AS compiler --exportTable flag\n const table = exports.table as WebAssembly.Table | undefined;\n \n // allow imports to access table\n if (table && typeof table.get === 'function') {\n provideFunctionTable(table);\n }\n\n // Call _start to run top-level code. Test registration is stubbed/noop duing execution,\n // but this call is still needed to initialize any user-defined globals / other top level code.\n if (typeof exports._start === 'function') {\n // Not explicitly handling with try-catch here because failures in _start should be\n // caught during discovery and source-mapped. If this somehow fails, the worker still catches it.\n exports._start();\n } else {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n 'no _start() export found on compiled WASM binary'\n );\n }\n\n let testFn: (() => void) | null | undefined;\n \n if (table && typeof table.get === 'function') {\n const idx = (test.meta as AssemblyScriptTestTaskMeta).fnIndex;\n testFn = table.get(idx) as (() => void) | null;\n\n if (!testFn) {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n `Test function at index ${idx} not found in function table`\n );\n }\n } else {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n 'Function table not found in WASM exports (missing --exportTable flag?)'\n );\n }\n\n // try-catch to ensure we capture known test errors to report\n // as AssemblyScriptTestErrors to vitest\n try {\n // Execute this test\n testTimings.execStart = performance.now();\n testFn();\n testTimings.execEnd = performance.now();\n\n // If we reach here, test passed, i.e. No abort occurred.\n // Proceed below to prepare the test result\n } catch (error: any) {\n testTimings.execEnd = performance.now();\n\n let testError: AssemblyScriptTestError;\n let stack: NodeJS.CallSite[];\n let allowStackJS: boolean;\n let applyStackToTestErrorCause: boolean;\n\n if (error && error[AS_POOL_ERROR_FLAG]) {\n const wrapper = error as AssemblyScriptPoolError;\n testError = wrapper.testError;\n stack = wrapper.originalErrorRawStack;\n allowStackJS = wrapper.originalErrorMayContainJS;\n applyStackToTestErrorCause = wrapper.applyStackToTestErrorCause;\n } else if (error instanceof Error) {\n testError = failTestRuntimeError(test, error.name, error.message);\n stack = extractCallStack(error);\n allowStackJS = true;\n applyStackToTestErrorCause = false;\n } else {\n testError = failTestRuntimeError(test, '', `Unexpected WASM test execution error: ${String(error)}`);\n stack = extractCallStack(new Error());\n allowStackJS = true;\n applyStackToTestErrorCause = false;\n }\n\n await enhanceTestError(\n testError,\n test,\n compilation.sourceMap,\n logPrefix,\n allowStackJS,\n projectRoot,\n applyStackToTestErrorCause,\n stack,\n diffOptions\n );\n }\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n\n // Extract coverage hits from coverage memory\n if (collectCoverage && compilation.debugInfo) {\n if (!coverageMemory) {\n throw createPoolError(\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n 'Coverage memory not created despite collectCoverage=true'\n );\n }\n\n const coverage: CoverageData = {\n hitCountsByFileAndPosition: {},\n };\n\n // Read counters from coverage memory\n const extractedHitCounters = new Uint32Array(coverageMemory.buffer, 0, compilation.debugInfo.instrumentedFunctionCount);\n covDebug(`${logPrefix} - Read coverage memory for ${compilation.debugInfo.instrumentedFunctionCount} instrumented functions`);\n\n // Iterate all instrumented functions and build coverage data with hit counts extracted from coverage memory\n let functionsHit = 0;\n for (const [filePath, debugFunctions] of Object.entries(compilation.debugInfo.functionsByFileAndPosition)) {\n if (!coverage.hitCountsByFileAndPosition[filePath]) {\n coverage.hitCountsByFileAndPosition[filePath] = {};\n covDebug(`${logPrefix} - Extracting hits for source file \"${filePath}\"`);\n }\n\n for (const [positionKey, funcInfos] of Object.entries(debugFunctions)) {\n // Sum hit counts across all functions at this position (multiple for generic monomorphizations)\n let positionHitCount = 0;\n for (const funcInfo of funcInfos) {\n if (funcInfo.coverageMemoryIndex === undefined) {\n debug(`${logPrefix} - WARNING: NO COVERAGE MEMORY INDEX`\n + ` - func \"${funcInfo.name}\" (${positionKey}) Skipping hit extraction`\n );\n continue;\n }\n\n const hitCount = extractedHitCounters[funcInfo.coverageMemoryIndex] ?? 0;\n covDebug(`${logPrefix} - func \"${funcInfo.name}\" (${positionKey}) `\n + `[idx: ${funcInfo.coverageMemoryIndex}]: ${hitCount} hits`\n );\n positionHitCount += hitCount;\n }\n\n coverage.hitCountsByFileAndPosition[filePath][positionKey] = positionHitCount;\n\n if (positionHitCount > 0) {\n functionsHit++;\n }\n }\n }\n\n meta.coverageData = coverage;\n debug(`${logPrefix} - Extracted coverage data | ${functionsHit} functions hit`);\n }\n\n testTimings.fnfinal = performance.now();\n\n return { test, testTimings };\n}\n","/**\n * RPC Reporting Helpers\n *\n * This module provides helper functions for reporting test lifecycle events\n * to Vitest via RPC. All helpers are designed to be composable and reusable.\n */\n\nimport type { MessagePort } from 'node:worker_threads';\nimport { createBirpc } from 'birpc';\nimport type { RunnerRPC, RuntimeRPC, UserConsoleLog } from 'vitest';\nimport type {\n File,\n Suite,\n Test,\n Task,\n TaskEventPack, \n TaskResultPack,\n CancelReason,\n} from '@vitest/runner/types';\n\nimport type {\n AssemblyScriptConsoleLog,\n AssemblyScriptCoveragePayload,\n AssemblyScriptSuiteTaskMeta,\n VitestVersion,\n WorkerRPC\n} from '../types/types.js';\nimport { debug } from '../util/debug.js';\nimport { COVERAGE_PAYLOAD_FORMATS } from '../types/constants.js';\nimport {\n createAfterSuiteRunMeta,\n getTaskLogLabel,\n isSuiteOwnFile\n} from '../util/vitest-tasks.js';\n\n// ============================================================================\n// RPC Client Factory\n// ============================================================================\n\n/** Create RPC client from MessagePort */\nexport function createRpcClient(port: MessagePort): WorkerRPC {\n return createBirpc<RuntimeRPC, RunnerRPC>(\n {\n onCancel: (_reason: CancelReason) => void { }\n },\n {\n post: (v) => port.postMessage(v),\n on: (fn) => port.on('message', fn),\n }\n );\n}\n\n// ============================================================================\n// File Task Reporting\n// ============================================================================\n\n/** Report file as queued (before compilation & discovery starts) */\nexport async function reportFileQueued(\n rpc: WorkerRPC,\n fileTask: File,\n logModule: string,\n logLabel: string,\n): Promise<void> {\n await rpc.onQueued(fileTask);\n debug(`[${logModule} RPC] ${logLabel} - Reported onQueued for file \"${fileTask.filepath}\"`\n + ` | mode: \"${fileTask.mode}\" | state: \"${fileTask.result ? fileTask.result.state : '--'}\"`\n );\n}\n\n/** Report file collection complete with full task tree */\nexport async function reportFileCollected(\n rpc: WorkerRPC,\n fileTask: File,\n logModule: string,\n logLabel: string,\n): Promise<void> {\n await rpc.onCollected([fileTask]);\n debug(`[${logModule} RPC] ${logLabel} - Reported onCollected for file \"${fileTask.filepath}\"`\n + ` | ${fileTask.tasks.length} tasks | mode: \"${fileTask.mode}\" | state: \"${fileTask.result?.state}\"`\n );\n}\n\n/** Report file-level error (compilation/discovery failure) as \"suite-failed-early\" */\nexport async function reportFileError(\n rpc: WorkerRPC,\n fileTask: File, \n logModule: string,\n logLabel: string,\n): Promise<void> {\n const taskPack: TaskResultPack = [fileTask.id, fileTask.result, {}];\n const eventPack: TaskEventPack = [fileTask.id, \"suite-failed-early\", undefined];\n await rpc.onTaskUpdate([taskPack], [eventPack]);\n\n debug(`[${logModule} RPC] ${logLabel} - Reported \"suite-failed-early\" task update for \"${fileTask.filepath}\"`);\n}\n\n// ============================================================================\n// Suite Lifecycle Reporting\n// ============================================================================\n\n/** Report suite-prepare event */\nexport async function reportSuitePrepare(\n rpc: WorkerRPC,\n suite: Suite,\n logModule: string,\n base: string,\n): Promise<void> {\n // Report suite event (without the custom task meta so reporters won't log it)\n const taskPack: TaskResultPack = [suite.id, suite.result, {}];\n const eventPack: TaskEventPack = [suite.id, 'suite-prepare', undefined];\n\n await rpc.onTaskUpdate([taskPack], [eventPack]);\n\n debug(`[${logModule} RPC] ${getTaskLogLabel(base, suite)} - Reported \"suite-prepare\" task update`\n + ` | state: \"${suite.result?.state}\"`\n );\n}\n\n/** Report suite-finished event */\nexport async function reportSuiteFinished(\n rpc: WorkerRPC,\n suite: Suite,\n logModule: string,\n base: string,\n vitestVersion: VitestVersion = 'v4',\n): Promise<void> {\n const suiteLabel = getTaskLogLabel(base, suite);\n const rpcLogPrefix = `[${logModule} RPC] ${suiteLabel}`;\n const meta = suite.meta as AssemblyScriptSuiteTaskMeta;\n const coverageKeys: number = Object.keys(meta.coverageData?.hitCountsByFileAndPosition ?? {}).length;\n let coveragePromise: Promise<void> = Promise.resolve();\n \n // Report coverage if this is a file task, and coverage is available\n if (isSuiteOwnFile(suite) && coverageKeys > 0) {\n const coverage: AssemblyScriptCoveragePayload = {\n __format: COVERAGE_PAYLOAD_FORMATS.AssemblyScript,\n coverageData: meta.coverageData!,\n suiteLogLabel: suiteLabel\n };\n \n const afterSuiteMeta = createAfterSuiteRunMeta(\n coverage,\n [suite.file.filepath],\n suite.file.projectName,\n vitestVersion\n );\n coveragePromise = rpc.onAfterSuiteRun(afterSuiteMeta);\n\n debug(`${rpcLogPrefix} - onAfterSuiteRun: Reported suite coverage (${coverageKeys} unique positions)`);\n } else if (coverageKeys === 0) {\n debug(`${rpcLogPrefix} - onAfterSuiteRun: No suite coverage to report`);\n }\n\n // Report suite event (without the custom task meta so reporters won't log it)\n const taskPack: TaskResultPack = [suite.id, suite.result, {}];\n const eventPack: TaskEventPack = [suite.id, \"suite-finished\", undefined];\n\n await Promise.all([\n coveragePromise,\n rpc.onTaskUpdate([taskPack], [eventPack])\n ]);\n\n debug(`${rpcLogPrefix} - Reported \"suite-finished\" task update | state: \"${suite.result?.state}\"`\n + ` | duration: ${suite.result?.duration?.toFixed(2) ?? '--'} ms`\n );\n}\n\n// ============================================================================\n// Test Lifecycle Reporting\n// ============================================================================\n\nasync function reportTestTaskUpdate(\n rpc: WorkerRPC,\n test: Test,\n logModule: string,\n base: string,\n updateEvent: 'test-prepare' | 'test-finished' | 'test-retried'\n): Promise<void> {\n // Report test event (without the custom task meta so reporters won't log it)\n const taskPack: TaskResultPack = [test.id, test.result, {}];\n const eventPack: TaskEventPack = [test.id, updateEvent, undefined];\n\n debug(`[${logModule} RPC] ${getTaskLogLabel(base, test)} - Reporting \"${updateEvent}\" task update...`\n + ` | state: \"${test.result?.state}\"`\n + `${updateEvent === 'test-prepare' ? '' : ` | duration: ${test.result?.duration?.toFixed(2) ?? '--'} ms`}`\n );\n await rpc.onTaskUpdate([taskPack], [eventPack]);\n debug(`[${logModule} RPC] ${getTaskLogLabel(base, test)} - Reported \"${updateEvent}\" task update`\n + ` | state: \"${test.result?.state}\"`\n + `${updateEvent === 'test-prepare' ? '' : ` | duration: ${test.result?.duration?.toFixed(2) ?? '--'} ms`}`\n );\n}\n\n/** Report test starting execution */\nexport async function reportTestPrepare(\n rpc: WorkerRPC,\n test: Test,\n logModule: string,\n base: string,\n): Promise<void> {\n return reportTestTaskUpdate(rpc, test, logModule, base, 'test-prepare');\n}\n\n/** Report test finished execution */\nexport async function reportTestFinished(\n rpc: WorkerRPC,\n test: Test,\n logModule: string,\n base: string,\n): Promise<void> {\n return reportTestTaskUpdate(rpc, test, logModule, base, 'test-finished');\n}\n\n/** Report test retried (sent when test failed and is going to be retried) */\nexport async function reportTestRetried(\n rpc: WorkerRPC,\n test: Test,\n logModule: string,\n base: string,\n): Promise<void> {\n return reportTestTaskUpdate(rpc, test, logModule, base, 'test-retried');\n}\n\n// ============================================================================\n// Other Reporting\n// ============================================================================\n\n/** Report user console log messages */\nexport async function reportUserConsoleLogs(\n rpc: WorkerRPC,\n logs: AssemblyScriptConsoleLog[],\n logModule: string,\n base: string,\n task: Task,\n): Promise<void> {\n if (logs.length === 0) {\n return;\n }\n\n const stdLogs = logs.filter(l => !l.isError);\n const errorLogs = logs.filter(l => l.isError);\n\n const stdContent: string = stdLogs.map(l => `${l.msg}`).join('\\n');\n const errorContent: string = errorLogs.filter(l => l.isError).map(l => `${l.msg}`).join('\\n');\n\n const stdLog: UserConsoleLog = {\n content: `${stdContent}\\n`,\n size: stdContent.length,\n browser: false,\n type: 'stdout',\n time: stdLogs.length > 0 ? stdLogs[0]!.time : Date.now(),\n taskId: task.id,\n origin: task.id\n };\n \n const errorLog: UserConsoleLog = {\n content: `${errorContent}\\n`,\n size: errorContent.length,\n browser: false,\n type: 'stderr',\n time: errorLogs.length > 0 ? errorLogs[0]!.time : Date.now(),\n taskId: task.id,\n origin: task.id\n };\n\n const reportPromises: Promise<void>[] = [];\n if (stdContent.length > 0) {\n reportPromises.push(rpc.onUserConsoleLog(stdLog));\n }\n if (errorContent.length > 0) {\n reportPromises.push(rpc.onUserConsoleLog(errorLog));\n }\n\n await Promise.all(reportPromises);\n\n debug(`[${logModule} RPC] ${getTaskLogLabel(base, task)} - Reported onUserConsoleLog | ${logs.length} messages`);\n}\n\n// ============================================================================\n// Final Flush\n// ============================================================================\n\n/** Flush any pending RPC updates */\nexport async function flushRpcUpdates(\n rpc: WorkerRPC,\n): Promise<void> {\n await rpc.onTaskUpdate([], []);\n}\n","import { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { WasmImportsFactory } from '../types/types.js';\nimport { debug } from '../util/debug.js';\nimport { POOL_ERROR_NAMES } from '../types/constants.js';\nimport { createPoolError } from '../util/pool-errors.js';\n\nexport async function loadUserWasmImportsFactory(\n relativePath: string | undefined,\n projectRoot: string,\n logModule: string,\n): Promise<WasmImportsFactory | undefined> {\n if (!relativePath) {\n return undefined;\n }\n\n const path = resolve(projectRoot, relativePath);\n const safeUrl = pathToFileURL(path).href;\n\n try {\n const start = performance.now();\n const createWasmImports = (await import(safeUrl)).default;\n debug(`[${logModule}] Imported user WasmImportsFactory \"${safeUrl}\" | TIMING ${(performance.now() - start).toFixed(2)} ms`);\n\n if (typeof createWasmImports !== 'function') {\n const msg = `Could not load user WasmImportsFactory from \"${safeUrl}\".`\n + ` Ensure that your module has a default export matching () => WebAssembly.Imports`\n + ` \\nDefault export type is currently \"${typeof createWasmImports}\"`;\n \n throw createPoolError(POOL_ERROR_NAMES.WASMUserImportsError, msg);\n } else {\n return createWasmImports;\n }\n } catch (error) {\n const msg = `Could not load user WasmImportsFactory from \"${safeUrl}\".`\n + ` Ensure that your module path is relative to the project root`\n + ` (location of shallowest vitest config), and that it has a`\n + ` default export matching () => WebAssembly.Imports`;\n throw createPoolError(\n POOL_ERROR_NAMES.WASMUserImportsError,\n msg,\n error,\n true\n );\n }\n};\n"],"mappings":"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"}
|