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.
Files changed (100) hide show
  1. package/assembly/compare.ts +11 -12
  2. package/assembly/describe.ts +4 -4
  3. package/assembly/expect.ts +44 -26
  4. package/assembly/test.ts +9 -9
  5. package/assembly/utils.ts +218 -62
  6. package/dist/{addon-interface-CYFXMbK7.mjs → addon-interface-BaUmn7uC.mjs} +12 -12
  7. package/dist/addon-interface-BaUmn7uC.mjs.map +1 -0
  8. package/dist/{ast-visitor-CWEOd3UH.mjs → ast-visitor-w1HMbuJR.mjs} +2 -2
  9. package/dist/{ast-visitor-CWEOd3UH.mjs.map → ast-visitor-w1HMbuJR.mjs.map} +1 -1
  10. package/dist/compile-runner-BGHM_85g.mjs +82 -0
  11. package/dist/compile-runner-BGHM_85g.mjs.map +1 -0
  12. package/dist/compiler/transforms/deep-equals.d.mts.map +1 -1
  13. package/dist/compiler/transforms/deep-equals.mjs +61 -22
  14. package/dist/compiler/transforms/deep-equals.mjs.map +1 -1
  15. package/dist/compiler/transforms/strip-inline.mjs +2 -2
  16. package/dist/{compiler-Dqs-qd3I.mjs → compiler-CXR5UJId.mjs} +55 -27
  17. package/dist/compiler-CXR5UJId.mjs.map +1 -0
  18. package/dist/config/index-v3.d.mts +1 -1
  19. package/dist/config/index-v3.d.mts.map +1 -1
  20. package/dist/config/index-v3.mjs.map +1 -1
  21. package/dist/config/index.d.mts +2 -2
  22. package/dist/config/index.mjs +5 -7
  23. package/dist/{constants-DbxJ3hzg.mjs → constants-Bq5KNxXJ.mjs} +4 -2
  24. package/dist/constants-Bq5KNxXJ.mjs.map +1 -0
  25. package/dist/{coverage-merge-CBXkpM1O.mjs → coverage-merge-0WqdC-dq.mjs} +1 -1
  26. package/dist/{coverage-merge-CBXkpM1O.mjs.map → coverage-merge-0WqdC-dq.mjs.map} +1 -1
  27. package/dist/coverage-provider/index.mjs +36 -36
  28. package/dist/coverage-provider/index.mjs.map +1 -1
  29. package/dist/{feature-check-Bje3ntpV.mjs → feature-check-BJpc4LoO.mjs} +4 -4
  30. package/dist/{feature-check-Bje3ntpV.mjs.map → feature-check-BJpc4LoO.mjs.map} +1 -1
  31. package/dist/index-internal.d.mts +3 -3
  32. package/dist/index-internal.d.mts.map +1 -1
  33. package/dist/index-internal.mjs +5 -4
  34. package/dist/index-v3.d.mts.map +1 -1
  35. package/dist/index-v3.mjs +19 -33
  36. package/dist/index-v3.mjs.map +1 -1
  37. package/dist/index.d.mts +1 -1
  38. package/dist/index.mjs +5 -7
  39. package/dist/{load-user-imports-Bx5ZlhSm.mjs → load-user-imports-Bcx9NOt9.mjs} +119 -232
  40. package/dist/load-user-imports-Bcx9NOt9.mjs.map +1 -0
  41. package/dist/pool-errors-Bn6YaguR.mjs +630 -0
  42. package/dist/pool-errors-Bn6YaguR.mjs.map +1 -0
  43. package/dist/{pool-runner-init-CNpRdA5u.d.mts → pool-runner-init-CCvnKt5o.d.mts} +2 -2
  44. package/dist/pool-runner-init-CCvnKt5o.d.mts.map +1 -0
  45. package/dist/{pool-runner-init-BqkwQ2tk.mjs → pool-runner-init-DjRCbiX-.mjs} +15 -30
  46. package/dist/pool-runner-init-DjRCbiX-.mjs.map +1 -0
  47. package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
  48. package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -1
  49. package/dist/pool-thread/compile-worker-thread.mjs +29 -19
  50. package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
  51. package/dist/pool-thread/test-worker-thread.d.mts +1 -1
  52. package/dist/pool-thread/test-worker-thread.d.mts.map +1 -1
  53. package/dist/pool-thread/test-worker-thread.mjs +25 -18
  54. package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
  55. package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
  56. package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -1
  57. package/dist/pool-thread/v3-tinypool-thread.mjs +43 -33
  58. package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
  59. package/dist/test-runner-BeP8ClnE.mjs +147 -0
  60. package/dist/test-runner-BeP8ClnE.mjs.map +1 -0
  61. package/dist/{types-DHVk5iAx.d.mts → types-CoroKYxB.d.mts} +39 -16
  62. package/dist/types-CoroKYxB.d.mts.map +1 -0
  63. package/dist/vitest-file-tasks-vvZzigcF.mjs +473 -0
  64. package/dist/vitest-file-tasks-vvZzigcF.mjs.map +1 -0
  65. package/dist/wasm-memory-C8Nkl2Sz.mjs +134 -0
  66. package/dist/wasm-memory-C8Nkl2Sz.mjs.map +1 -0
  67. package/dist/{worker-rpc-channel-CZZIxtv5.mjs → worker-rpc-channel-CvCrc8aa.mjs} +1 -1
  68. package/dist/{worker-rpc-channel-CZZIxtv5.mjs.map → worker-rpc-channel-CvCrc8aa.mjs.map} +1 -1
  69. package/package.json +1 -1
  70. package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  71. package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  72. package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  73. package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  74. package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
  75. package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  76. package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  77. package/src/instrumentation/native/addon.cpp +71 -32
  78. package/dist/addon-interface-CYFXMbK7.mjs.map +0 -1
  79. package/dist/compile-runner-BNFHRGZO.mjs +0 -85
  80. package/dist/compile-runner-BNFHRGZO.mjs.map +0 -1
  81. package/dist/compiler-Dqs-qd3I.mjs.map +0 -1
  82. package/dist/constants-DbxJ3hzg.mjs.map +0 -1
  83. package/dist/debug-DtRAL4rM.mjs +0 -232
  84. package/dist/debug-DtRAL4rM.mjs.map +0 -1
  85. package/dist/load-user-imports-Bx5ZlhSm.mjs.map +0 -1
  86. package/dist/path-utils-t9OzjXYF.mjs +0 -24
  87. package/dist/path-utils-t9OzjXYF.mjs.map +0 -1
  88. package/dist/pool-runner-init-BqkwQ2tk.mjs.map +0 -1
  89. package/dist/pool-runner-init-CNpRdA5u.d.mts.map +0 -1
  90. package/dist/resolve-config-s9gSJSMc.mjs +0 -85
  91. package/dist/resolve-config-s9gSJSMc.mjs.map +0 -1
  92. package/dist/test-runner-BGqc9uCK.mjs +0 -138
  93. package/dist/test-runner-BGqc9uCK.mjs.map +0 -1
  94. package/dist/types-DHVk5iAx.d.mts.map +0 -1
  95. package/dist/vitest-file-tasks-D8sOClGX.mjs +0 -149
  96. package/dist/vitest-file-tasks-D8sOClGX.mjs.map +0 -1
  97. package/dist/vitest-tasks-BZ24sghI.mjs +0 -321
  98. package/dist/vitest-tasks-BZ24sghI.mjs.map +0 -1
  99. package/dist/wasm-names-BFtzQCH4.mjs +0 -124
  100. package/dist/wasm-names-BFtzQCH4.mjs.map +0 -1
@@ -1,79 +1,11 @@
1
- import { COVERAGE_PAYLOAD_FORMATS, POOL_ERROR_NAMES, POOL_INTERNAL_PATHS, TEST_ERROR_NAMES } from "./constants-DbxJ3hzg.mjs";
2
- import { createPoolError, createPoolErrorFromAnyError, debug, debugOverride, getSourceCodeFrameString, toPlaintextStackFrameString, toVitestLikeStackFrameString } from "./debug-DtRAL4rM.mjs";
3
- import { createAfterSuiteRunMeta, createSuiteTask, createTestTask, createWebAssemblyCallSite, extractCallStack, failTest, getTaskLogLabel, isSuiteOwnFile, parseSourceMap } from "./vitest-tasks-BZ24sghI.mjs";
4
- import { getShortFunctionName } from "./wasm-names-BFtzQCH4.mjs";
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
- if (userEnvImports) {
169
- userCustomEnvImports = { ...userImports };
170
- delete userCustomEnvImports.env;
171
- }
100
+ userCustomEnvImports = { ...userImports };
101
+ if (userEnvImports) delete userCustomEnvImports.env;
172
102
  } catch (error) {
173
- throw createPoolErrorFromAnyError(`Error creating user WASM Imports`, POOL_ERROR_NAMES.PoolConfigError, error);
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
- const msgAtLoc = `${message}${location ? ` at ${location}` : ""}`;
194
- debug(`${logPrefix} - Unexpected abort during test discovery: ${msgAtLoc}`);
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 createPoolError(`AssemblyScript abort() import called for expected error throw in test "${test.name}"`, POOL_ERROR_NAMES.WASMExecutionAbortError);
186
+ throw abortWASMExecutionOnSuccess();
259
187
  } else {
260
- failureMessage = `expected function to throw "${expectedErrorMsgStr}" error but received "${message}"`;
261
- test.meta.assertionsFailed.push({
188
+ const expected = getExpectedMessageOrAny(expectedErrorMsgStr);
189
+ failureMessage = `expected function to throw error ${expected}, but received error "${message}"`;
190
+ lastFailedAssertion = {
262
191
  message: failureMessage,
263
- typeName: "Error",
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: "${expectedErrorMsgStr}" | Actual: "${message}"`}`);
197
+ };
198
+ debug(`${logPrefix} - Assertion failed: ${`Thrown error does not match expected | Expected: ${expected} | Actual: "${message}"`}`);
269
199
  }
270
- failTest(test, failureMessage, /* @__PURE__ */ new Error(), logPrefix);
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, typeNamePtr, valuesProvided, actualPtr, expectedPtr) {
283
- const errorMsg = liftString(memory, msgPtr);
284
- const assertionValueType = liftString(memory, typeNamePtr);
285
- let actual;
286
- let expected;
287
- const assertionFailure = {
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
- assertionFailure.actual = liftString(memory, actualPtr);
294
- assertionFailure.expected = liftString(memory, expectedPtr);
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
- test.meta.assertionsFailed.push(assertionFailure);
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 !== void 0 ? `"${expectedErrorMsgStr}"` : "<any>"}`);
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}"`, POOL_ERROR_NAMES.WASMExecutionHarnessError);
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 in test "${test.name}"`, POOL_ERROR_NAMES.WASMExecutionHarnessError);
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
- const isAnyErr = !!expectedErrorMsgStr;
313
- const failureMessage = `expected function to throw ${isAnyErr ? `"${expectedErrorMsgStr}"` : "any"} error - did not throw`;
314
- test.meta.assertionsFailed.push({
315
- message: failureMessage,
316
- typeName: "Error",
317
- valuesProvided: !isAnyErr,
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/wasm-errors.ts
338
- const POOL_INTERNAL_PATHS_SET = new Set(POOL_INTERNAL_PATHS);
339
- async function sourceMapRawCallStack(rawCallStack, sourceMap, loggingPrefix) {
340
- const mappedStack = [];
341
- if (!rawCallStack || rawCallStack.length === 0) return mappedStack;
342
- const sourceMapConsumer = await new SourceMapConsumer(sourceMap);
343
- rawCallStack.forEach((callSite) => {
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
- async function processWASMErrorStack(rawCallStack, sourceMap, loggingPrefix) {
359
- const sourceMapObj = parseSourceMap(sourceMap);
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
- parsedStack: parseMappedStack(sourceMappedStack),
364
- parsedSourceMap: sourceMapObj
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(binary, sourceMap, testFileBasename, poolOptions, isBinaryInstrumented, handleLog, file, moduleLabel, threadImports, diffOptions) {
283
+ async function executeWASMDiscovery(compilation, poolOptions, isBinaryInstrumented, handleLog, file, moduleLabel, threadImports) {
411
284
  const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(basename(file.filepath), file)}`;
412
- const wasmModule = await WebAssembly.compile(binary);
413
- const importObject = createDiscoveryImports(createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax), wasmModule, file, handleLog, logPrefix, isBinaryInstrumented ? createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax) : void 0, threadImports.createUserWasmImports);
414
- const exports = new WebAssembly.Instance(wasmModule, importObject).exports;
415
- if (typeof exports._start === "function") try {
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
- const thrownErrAny = error;
419
- if (error instanceof WebAssembly.RuntimeError && thrownErrAny?.message.includes("null function or function signature mismatch")) {
420
- const runtimeError = error;
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);
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
- 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);
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, testFileBasename, poolOptions, collectCoverage, handleLog, moduleLabel, threadImports, diffOptions) {
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 wasmModule = await WebAssembly.compile(compilation.binary);
455
- const memory = createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax);
456
- const coverageMemory = collectCoverage ? createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax) : void 0;
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 createExecutorPoolError(testFileBasename, "executeWASMTest", "no _start() export");
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 createExecutorPoolError(testFileBasename, "executeWASMTest", `Test function at index ${idx} not found in function table`);
468
- } else throw createExecutorPoolError(testFileBasename, "executeWASMTest", "Function table not found in WASM exports (missing --exportTable flag?)");
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
- if (error?.name !== POOL_ERROR_NAMES.WASMExecutionAbortError) throw createExecutorPoolError(testFileBasename, "executeWASMTest", `Unexpected execution error: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`, error?.cause);
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 createExecutorPoolError(testFileBasename, "executeWASMTest", "Coverage memory not created despite collectCoverage=true");
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}] TIMING Imported user WasmImportsFactory in ${(performance.now() - start).toFixed(2)} ms`);
672
- if (typeof createWasmImports !== "function") throw new Error(`User config for \`wasmImportsFactor\` must be the path to a module with a default export matching () => WebAssembly.Imports - Imported: "${typeof createWasmImports}": ${String(createWasmImports)}`);
673
- else return createWasmImports;
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
- if (error["__as_pool__"]) throw error;
676
- throw new Error(`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`, { cause: error });
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-Bx5ZlhSm.mjs.map
569
+ //# sourceMappingURL=load-user-imports-Bcx9NOt9.mjs.map