vitest-pool-assemblyscript 0.2.1 → 0.2.2
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/binding.gyp +4 -4
- package/dist/{compile-runner-8h0dBwG2.mjs → compile-runner-xGvQwgNf.mjs} +2 -2
- package/dist/{compile-runner-8h0dBwG2.mjs.map → compile-runner-xGvQwgNf.mjs.map} +1 -1
- package/dist/{load-user-imports-J9eaAW0_.mjs → load-user-imports-Bbmpaciu.mjs} +5 -4
- package/dist/{load-user-imports-J9eaAW0_.mjs.map → load-user-imports-Bbmpaciu.mjs.map} +1 -1
- package/dist/pool-thread/compile-worker-thread.mjs +2 -2
- package/dist/pool-thread/test-worker-thread.mjs +2 -2
- package/dist/pool-thread/v3-tinypool-thread.mjs +3 -3
- package/dist/{test-runner-B2BpyPNK.mjs → test-runner-BR4XyhMA.mjs} +2 -2
- package/dist/{test-runner-B2BpyPNK.mjs.map → test-runner-BR4XyhMA.mjs.map} +1 -1
- package/package.json +18 -2
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/{linux-arm64/vitest-pool-assemblyscript.glibc.node → linux-x64/vitest-pool-assemblyscript.musl.node} +0 -0
- package/scripts/setup-binaryen.js +253 -79
- package/src/native-instrumentation/addon.cpp +2 -2
package/binding.gyp
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"-lpthread"
|
|
28
28
|
],
|
|
29
29
|
# Enable C++ exceptions (node-gyp disables them by default)
|
|
30
|
-
"cflags_cc": ["-std=c++
|
|
30
|
+
"cflags_cc": ["-std=c++20", "-fexceptions", "-O3"],
|
|
31
31
|
"cflags!": ["-fno-exceptions"],
|
|
32
32
|
"cflags_cc!": ["-fno-exceptions"]
|
|
33
33
|
}],
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"xcode_settings": {
|
|
39
39
|
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
|
40
40
|
"CLANG_CXX_LIBRARY": "libc++",
|
|
41
|
-
# Minimum macOS deployment target for C++
|
|
41
|
+
# Minimum macOS deployment target for C++20 support
|
|
42
42
|
"MACOSX_DEPLOYMENT_TARGET": "10.15",
|
|
43
|
-
"OTHER_CPLUSPLUSFLAGS": ["-std=c++
|
|
43
|
+
"OTHER_CPLUSPLUSFLAGS": ["-std=c++20", "-fexceptions", "-O3"]
|
|
44
44
|
}
|
|
45
45
|
}],
|
|
46
46
|
["OS=='win'", {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"VCCLCompilerTool": {
|
|
53
53
|
# Enable C++ exception handling (/EHsc)
|
|
54
54
|
"ExceptionHandling": 1,
|
|
55
|
-
"AdditionalOptions": ["/std:c++
|
|
55
|
+
"AdditionalOptions": ["/std:c++20"]
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}]
|
|
@@ -2,7 +2,7 @@ import { POOL_ERROR_NAMES, POOL_INTERNAL_PATHS } from "./constants-CA50WBdr.mjs"
|
|
|
2
2
|
import { createPoolErrorFromAnyError, debug, getTestErrorFromPoolError } from "./debug-IeEHsxy0.mjs";
|
|
3
3
|
import { failFile, getFullTaskHierarchy, prepareFileTaskForCollection } from "./vitest-file-tasks-BUwzh375.mjs";
|
|
4
4
|
import { getTaskLogLabel, getTaskLogPrefix } from "./vitest-tasks-BKS7689f.mjs";
|
|
5
|
-
import { executeWASMDiscovery, flushRpcUpdates, reportFileCollected, reportFileError, reportFileQueued, reportUserConsoleLogs } from "./load-user-imports-
|
|
5
|
+
import { executeWASMDiscovery, flushRpcUpdates, reportFileCollected, reportFileError, reportFileQueued, reportUserConsoleLogs } from "./load-user-imports-Bbmpaciu.mjs";
|
|
6
6
|
import { compileAssemblyScript } from "./compiler-CN6BRK_N.mjs";
|
|
7
7
|
import { basename, relative } from "node:path";
|
|
8
8
|
|
|
@@ -77,4 +77,4 @@ async function runCompileAndDiscover(file, logModule, rpc, poolOptions, projectR
|
|
|
77
77
|
|
|
78
78
|
//#endregion
|
|
79
79
|
export { runCompileAndDiscover };
|
|
80
|
-
//# sourceMappingURL=compile-runner-
|
|
80
|
+
//# sourceMappingURL=compile-runner-xGvQwgNf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-runner-
|
|
1
|
+
{"version":3,"file":"compile-runner-xGvQwgNf.mjs","names":[],"sources":["../src/pool-thread/runner/compile-runner.ts"],"sourcesContent":["/**\n * Worker thread test runner logic for AssemblyScript Pool\n */\n\nimport { basename, relative } from 'node:path';\nimport type { File } from '@vitest/runner/types';\nimport type { SerializedDiffOptions } from '@vitest/utils/diff';\n\nimport type {\n AssemblyScriptCompilerOptions,\n AssemblyScriptConsoleLog,\n AssemblyScriptConsoleLogHandler,\n InstrumentationOptions,\n ResolvedAssemblyScriptPoolOptions,\n ThreadImports,\n WASMCompilation,\n WorkerRPC,\n} from '../../types/types.js';\nimport {\n ASSEMBLYSCRIPT_LIB_PREFIX,\n POOL_ERROR_NAMES,\n POOL_INTERNAL_PATHS,\n} from '../../types/constants.js';\nimport { executeWASMDiscovery } from '../../wasm-executor/index.js';\nimport { debug } from '../../util/debug.js';\nimport {\n reportFileQueued,\n reportFileCollected,\n reportUserConsoleLogs,\n flushRpcUpdates,\n reportFileError,\n} from '../rpc-reporter.js';\nimport { createPoolErrorFromAnyError, getTestErrorFromPoolError } from '../../util/pool-errors.js';\nimport { compileAssemblyScript } from '../../compiler/index.js';\nimport {\n getTaskLogLabel,\n getTaskLogPrefix,\n} from '../../util/vitest-tasks.js';\nimport {\n failFile,\n getFullTaskHierarchy,\n prepareFileTaskForCollection,\n} from '../../util/vitest-file-tasks.js';\n\nlet threadCompilationCount: number = 0;\n\nexport async function runCompileAndDiscover(\n file: File,\n logModule: string,\n rpc: WorkerRPC,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n projectRoot: string,\n collectCoverage: boolean,\n relativeUserCoverageExclusions: string[],\n threadImports: ThreadImports,\n diffOptions?: SerializedDiffOptions,\n testNamePattern?: RegExp,\n allowOnly?: boolean,\n): Promise<WASMCompilation | undefined> {\n const base = basename(file.filepath);\n const fileLogPrefix = getTaskLogPrefix(logModule, base, file);\n const fileLogLabel = getTaskLogLabel(base, file);\n\n debug(`${fileLogPrefix} - Beginning runCompileAndDiscover for \"${file.filepath}\" at ${Date.now()}`);\n\n const runStart = performance.now();\n let compilation: WASMCompilation | undefined;\n\n try {\n await reportFileQueued(rpc, file, logModule, fileLogLabel);\n\n // TODO - move to options helpers\n const relativeTestFilePath = relative(projectRoot, file.filepath);\n const instrumentationOptions: InstrumentationOptions = {\n relativeExcludedFiles: [\n relativeTestFilePath,\n ...POOL_INTERNAL_PATHS,\n ...relativeUserCoverageExclusions,\n ],\n excludedLibraryFilePrefix: ASSEMBLYSCRIPT_LIB_PREFIX,\n coverageMemoryPagesMin: poolOptions.coverageMemoryPagesInitial,\n coverageMemoryPagesMax: poolOptions.coverageMemoryPagesMax,\n };\n const compilerOptions: AssemblyScriptCompilerOptions = {\n stripInline: poolOptions.stripInline,\n projectRoot: projectRoot,\n shouldInstrument: collectCoverage,\n instrumentationOptions,\n extraFlags: poolOptions.extraCompilerFlags\n };\n\n const { binary, sourceMap, debugInfo, compileTiming } = await compileAssemblyScript(\n file.filepath,\n compilerOptions,\n logModule,\n fileLogLabel\n );\n file.setupDuration = compileTiming;\n threadCompilationCount++;\n\n debug(`${fileLogPrefix} - TIMING compileAssemblyScript total `\n + `(thread comp # ${threadCompilationCount}): ${compileTiming.toFixed(2)} ms`\n );\n \n const logMessages: AssemblyScriptConsoleLog[] = [];\n const handleLog: AssemblyScriptConsoleLogHandler = (msg: string, isError: boolean = false): void => {\n logMessages.push({ msg, time: Date.now(), isError });\n };\n \n const discoverStart = performance.now();\n\n await executeWASMDiscovery(\n binary,\n sourceMap,\n base,\n poolOptions,\n collectCoverage,\n handleLog,\n file,\n logModule,\n threadImports,\n diffOptions\n );\n\n // set skips when using only and/or user test name pattern, skip file task if all tests skipped\n prepareFileTaskForCollection(file, testNamePattern, allowOnly);\n\n file.collectDuration = performance.now() - discoverStart;\n debug(`${fileLogPrefix} - TIMING Discovery Phase: ${file.collectDuration.toFixed(2)} ms`);\n\n // vitest collect - report discovery results\n await Promise.all([\n // Report user console logs\n reportUserConsoleLogs(rpc, logMessages, logModule, base, file),\n\n // Report onCollected with collected and filtered tasks\n reportFileCollected(rpc, file, logModule, fileLogLabel),\n ]);\n\n debug(() => `${fileLogPrefix} - Collected Test Suite Hierarchy:\\n${getFullTaskHierarchy(file)}`);\n\n const totalTime = performance.now() - runStart;\n debug(`${fileLogPrefix} - TIMING Compilation and Discovery: ${totalTime.toFixed(2)} ms`);\n\n compilation = {\n filePath: file.filepath,\n binary,\n sourceMap,\n debugInfo,\n };\n } catch (error) {\n const poolError = createPoolErrorFromAnyError(\n `${fileLogLabel} - runCompileAndDiscover failure in worker`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n error\n );\n const testError = getTestErrorFromPoolError(poolError);\n\n failFile(file, testError, runStart);\n\n await reportFileQueued(rpc, file, logModule, fileLogLabel);\n await reportFileError(rpc, file, logModule, fileLogLabel);\n\n debug(`${fileLogPrefix} - Reported file error`);\n } finally {\n await flushRpcUpdates(rpc);\n debug(`${fileLogPrefix} - runCompileAndDiscover Completed`);\n }\n\n return compilation;\n}\n"],"mappings":";;;;;;;;;;;;AA4CA,IAAI,yBAAiC;AAErC,eAAsB,sBACpB,MACA,WACA,KACA,aACA,aACA,iBACA,gCACA,eACA,aACA,iBACA,WACsC;CACtC,MAAM,OAAO,SAAS,KAAK,SAAS;CACpC,MAAM,gBAAgB,iBAAiB,WAAW,MAAM,KAAK;CAC7D,MAAM,eAAe,gBAAgB,MAAM,KAAK;AAEhD,OAAM,GAAG,cAAc,0CAA0C,KAAK,SAAS,OAAO,KAAK,KAAK,GAAG;CAEnG,MAAM,WAAW,YAAY,KAAK;CAClC,IAAI;AAEJ,KAAI;AACF,QAAM,iBAAiB,KAAK,MAAM,WAAW,aAAa;EAI1D,MAAM,yBAAiD;GACrD,uBAAuB;IAFI,SAAS,aAAa,KAAK,SAAS;IAI7D,GAAG;IACH,GAAG;IACJ;GACD;GACA,wBAAwB,YAAY;GACpC,wBAAwB,YAAY;GACrC;EACD,MAAM,kBAAiD;GACrD,aAAa,YAAY;GACZ;GACb,kBAAkB;GAClB;GACA,YAAY,YAAY;GACzB;EAED,MAAM,EAAE,QAAQ,WAAW,WAAW,kBAAkB,MAAM,sBAC5D,KAAK,UACL,iBACA,WACA,aACD;AACD,OAAK,gBAAgB;AACrB;AAEA,QAAM,GAAG,cAAc,uDACD,uBAAuB,KAAK,cAAc,QAAQ,EAAE,CAAC,KAC1E;EAED,MAAM,cAA0C,EAAE;EAClD,MAAM,aAA8C,KAAa,UAAmB,UAAgB;AAClG,eAAY,KAAK;IAAE;IAAK,MAAM,KAAK,KAAK;IAAE;IAAS,CAAC;;EAGtD,MAAM,gBAAgB,YAAY,KAAK;AAEvC,QAAM,qBACJ,QACA,WACA,MACA,aACA,iBACA,WACA,MACA,WACA,eACA,YACD;AAGD,+BAA6B,MAAM,iBAAiB,UAAU;AAE9D,OAAK,kBAAkB,YAAY,KAAK,GAAG;AAC3C,QAAM,GAAG,cAAc,6BAA6B,KAAK,gBAAgB,QAAQ,EAAE,CAAC,KAAK;AAGzF,QAAM,QAAQ,IAAI,CAEhB,sBAAsB,KAAK,aAAa,WAAW,MAAM,KAAK,EAG9D,oBAAoB,KAAK,MAAM,WAAW,aAAa,CACxD,CAAC;AAEF,cAAY,GAAG,cAAc,sCAAsC,qBAAqB,KAAK,GAAG;AAGhG,QAAM,GAAG,cAAc,wCADL,YAAY,KAAK,GAAG,UACkC,QAAQ,EAAE,CAAC,KAAK;AAExF,gBAAc;GACZ,UAAU,KAAK;GACf;GACA;GACA;GACD;UACM,OAAO;AAQd,WAAS,MAFS,0BALA,4BAChB,GAAG,aAAa,6CAChB,iBAAiB,2BACjB,MACD,CACqD,EAE5B,SAAS;AAEnC,QAAM,iBAAiB,KAAK,MAAM,WAAW,aAAa;AAC1D,QAAM,gBAAgB,KAAK,MAAM,WAAW,aAAa;AAEzD,QAAM,GAAG,cAAc,wBAAwB;WACvC;AACR,QAAM,gBAAgB,IAAI;AAC1B,QAAM,GAAG,cAAc,oCAAoC;;AAG7D,QAAO"}
|
|
@@ -5,6 +5,7 @@ import { basename, resolve } from "node:path";
|
|
|
5
5
|
import { createBirpc } from "birpc";
|
|
6
6
|
import { diff } from "@vitest/utils/diff";
|
|
7
7
|
import { SourceMapConsumer } from "source-map";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
8
9
|
|
|
9
10
|
//#region src/util/assemblyscript/binding-helpers.ts
|
|
10
11
|
const STRING_EXTRACT_CHUNK_SIZE = 1024;
|
|
@@ -783,19 +784,19 @@ async function flushRpcUpdates(rpc) {
|
|
|
783
784
|
//#region src/pool-thread/load-user-imports.ts
|
|
784
785
|
async function loadUserWasmImportsFactory(relativePath, projectRoot, logModule) {
|
|
785
786
|
if (!relativePath) return;
|
|
786
|
-
const
|
|
787
|
+
const safeUrl = pathToFileURL(resolve(projectRoot, relativePath)).href;
|
|
787
788
|
try {
|
|
788
789
|
const start = performance.now();
|
|
789
|
-
const createWasmImports = (await import(
|
|
790
|
+
const createWasmImports = (await import(safeUrl)).default;
|
|
790
791
|
debug(`[${logModule}] TIMING Imported user WasmImportsFactory in ${(performance.now() - start).toFixed(2)} ms`);
|
|
791
792
|
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)}`);
|
|
792
793
|
else return createWasmImports;
|
|
793
794
|
} catch (error) {
|
|
794
795
|
if (error["__as_pool__"]) throw error;
|
|
795
|
-
throw new Error(`Could not load user WasmImportsFactory from "${
|
|
796
|
+
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 });
|
|
796
797
|
}
|
|
797
798
|
}
|
|
798
799
|
|
|
799
800
|
//#endregion
|
|
800
801
|
export { createRpcClient, executeWASMDiscovery, executeWASMTest, flushRpcUpdates, loadUserWasmImportsFactory, reportFileCollected, reportFileError, reportFileQueued, reportSuiteFinished, reportSuitePrepare, reportTestFinished, reportTestPrepare, reportTestRetried, reportUserConsoleLogs };
|
|
801
|
-
//# sourceMappingURL=load-user-imports-
|
|
802
|
+
//# sourceMappingURL=load-user-imports-Bbmpaciu.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-user-imports-J9eaAW0_.mjs","names":[],"sources":["../src/util/assemblyscript/binding-helpers.ts","../src/wasm-executor/wasm-memory.ts","../src/wasm-executor/wasm-console.ts","../src/wasm-executor/collect-options.ts","../src/wasm-executor/wasm-imports.ts","../src/wasm-executor/wasm-names.ts","../src/wasm-executor/wasm-errors.ts","../src/wasm-executor/index.ts","../src/pool-thread/rpc-reporter.ts","../src/pool-thread/load-user-imports.ts"],"sourcesContent":["const STRING_EXTRACT_CHUNK_SIZE = 1024 as const;\n\n/**\n * Decode an AssemblyScript string from WASM memory, using the length stored at\n * the beginning of the string.\n *\n * This approach is borrowed from AssemblyScript with changes for clarity.\n * AssemblyScript is released under the Apache 2.0 license, included here.\n * \n * When a string argument crosses the boundary to JS, we get a pointer to the\n * string data in WASM memory. WASM strings store their length in the 4 bytes\n * before the string data pointer so we know how much to read from memory.\n *\n * @param memory - WebAssembly memory instance\n * @param pointer - Pointer to the start of the string\n * @returns Decoded string\n */\nexport function liftString(\n memory: WebAssembly.Memory,\n pointer: number,\n): string | undefined {\n if (!pointer) return undefined;\n\n const unsigned = pointer >>> 0;\n \n const lengthPtr = unsigned - 4;\n\n // convert byte-based lengthPtr to uint32-based index for Uint32Array\n // with: bytes / 4 (=== bytes >>> 2) and read length\n const uint32LengthPtr = lengthPtr >>> 2;\n const byteOffsetLength = new Uint32Array(memory.buffer)[uint32LengthPtr];\n\n if (byteOffsetLength === 0) return '';\n \n // calculate end pointer, and convert byte-based start and end pointers\n // to uint16-based indexes for Uint16Array with: bytes / 2 (=== bytes >>> 1) \n const uint16EndPtr = (unsigned + byteOffsetLength!) >>> 1;\n let uint16StartPtr = unsigned >>> 1;\n\n const memoryU16 = new Uint16Array(memory.buffer);\n let string = '';\n\n // extract in 1024-character chunks to avoid hitting spread operator limit\n while (uint16EndPtr - uint16StartPtr > STRING_EXTRACT_CHUNK_SIZE) {\n string += String.fromCharCode(\n ...memoryU16.subarray(uint16StartPtr, uint16StartPtr += STRING_EXTRACT_CHUNK_SIZE)\n );\n }\n\n return string + String.fromCharCode(...memoryU16.subarray(uint16StartPtr, uint16EndPtr));\n}\n","import { liftString } from '../util/assemblyscript/binding-helpers.js';\n\n/**\n * Create a WebAssembly memory instance\n * Used for imported memory pattern (matches --importMemory flag)\n */\nexport function createMemory(initialPages: number, maximumPages?: number): WebAssembly.Memory {\n return new WebAssembly.Memory({ initial: initialPages, maximum: maximumPages });\n}\n\n/**\n * Decode AssemblyScript abort information\n *\n * Helper for handling abort() calls from AssemblyScript runtime.\n * Decodes the error message and file path from WASM memory.\n *\n * @param memory - WebAssembly memory instance\n * @param msgPtr - Pointer to error message string (or 0 if none)\n * @param filePtr - Pointer to file path string (or 0 if none)\n * @param line - Line number where abort occurred\n * @param column - Column number where abort occurred\n * @returns Decoded message and location (null if no meaningful location info)\n */\nexport function decodeAbortInfo(\n memory: WebAssembly.Memory,\n msgPtr: number,\n filePtr: number,\n line: number,\n column: number\n): { message: string; location: string | null } {\n const errorMsg = liftString(memory, msgPtr) ?? 'Unknown error'; \n const filePath = liftString(memory, filePtr);\n\n // Only include location if we have meaningful file info (not null/empty and not at 0:0)\n const hasLocation = filePath && filePath !== 'unknown' && (line !== 0 || column !== 0);\n const location = hasLocation ? `${filePath}:${line}:${column}` : null;\n\n return {\n message: errorMsg,\n location: location,\n };\n}\n","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 { AS_POOL_WASM_IMPORTS_ENV, POOL_ERROR_NAMES, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } from '../util/debug.js';\nimport { createPoolError, createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { liftString } from '../util/assemblyscript/binding-helpers.js';\nimport { extractCallStack } from './source-maps.js';\nimport { decodeAbortInfo } from './wasm-memory.js';\nimport { createWasmConsole } from './wasm-console.js';\nimport { mergeAssemblyScriptTestOptions } from './collect-options.js';\nimport { createSuiteTask, createTestTask, failTest } 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 throw createPoolErrorFromAnyError(\n `Error creating user WASM Imports`,\n POOL_ERROR_NAMES.PoolConfigError,\n error\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 // Create error to capture V8 stack trace and extract V8 call stack before throwing.\n // This gives us WAT line:column positions that can be mapped to AS source\n const rawCallStack = extractCallStack(new Error());\n\n // Send the test error that we will report to vitest in the PoolError's `cause` field.\n // The rawCallStack will be enahnced and deleted by the executor, with the parsed result\n // added to the reported test error.\n const testError: AssemblyScriptTestError = {\n message,\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n };\n\n throw createPoolError(\n msgAtLoc,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n undefined, // stack\n testError, // cause\n rawCallStack\n );\n },\n },\n\n [AS_POOL_WASM_IMPORTS_ENV]: {\n\n ...(coverageMemory ? { __coverage_memory: 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 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 if (isExpectingError) {\n if (!expectedErrorMsgStr || message.includes(expectedErrorMsgStr)) {\n (test.meta as AssemblyScriptTestTaskMeta).assertionsPassedCount++;\n \n debug(`${logPrefix} - Thrown error matches expected - assertion passes`);\n\n throw createPoolError(\n `AssemblyScript abort() import called for expected error throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionAbortError\n );\n } else {\n failureMessage = `expected function to throw \"${expectedErrorMsgStr}\" error but received \"${message}\"`;\n\n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push({\n message: failureMessage,\n typeName: 'Error',\n valuesProvided: true,\n actual: message,\n expected: expectedErrorMsgStr\n } satisfies FailedAssertion);\n\n const errStr = `Thrown error does not match expected | Expected: \"${expectedErrorMsgStr}\" | Actual: \"${message}\"`\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n }\n }\n\n // Create error to capture V8 stack trace and extract V8 call stack before throwing.\n // This gives us WAT line:column positions that can be mapped to AS source\n const capturedError = new Error();\n\n failTest(test, failureMessage, capturedError, logPrefix);\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 // using test.meta.lastError value set in failTest()\n throw createPoolError(\n `AssemblyScript abort() import called during test execution for ${test.name}`,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n );\n },\n },\n\n [AS_POOL_WASM_IMPORTS_ENV]: {\n \n ...(coverageMemory ? { __coverage_memory: 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, typeNamePtr: number, valuesProvided: boolean, actualPtr?: number, expectedPtr?: number) {\n const errorMsg = liftString(memory, msgPtr);\n const assertionValueType = liftString(memory, typeNamePtr);\n let actual: string | undefined;\n let expected: string | undefined;\n \n const assertionFailure: FailedAssertion = {\n message: errorMsg,\n typeName: assertionValueType,\n valuesProvided: Boolean(valuesProvided)\n };\n \n if (valuesProvided && actualPtr && expectedPtr) {\n assertionFailure.actual = liftString(memory, actualPtr);\n assertionFailure.expected = liftString(memory, expectedPtr);\n }\n \n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push(assertionFailure);\n \n const valuesMsg = valuesProvided ? ` | Value Type: ${assertionValueType}`\n + ` | Expected: \\`${expected !== undefined ? expected : ''}\\` | Actual: \\`${actual !== undefined ? actual : ''}\\``\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: ${expectedErrorMsgStr !== undefined\n ? `\"${expectedErrorMsgStr}\"` : '<any>'}`\n );\n\n if (wasmFunctionTable && typeof wasmFunctionTable.get === 'function') {\n const fn = wasmFunctionTable.get(fnIndex);\n if (!fn) {\n throw createPoolError(\n `Could not access function (fnPtr ${fnIndex}) which is expected to throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\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 `Could not access WASM function table to call function expected to throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n );\n }\n },\n\n __end_expect_throw() {\n if (isExpectingError) {\n const isAnyErr: boolean = !!expectedErrorMsgStr;\n const failureMessage = `expected function to throw ${isAnyErr ?\n `\"${expectedErrorMsgStr}\"` : 'any'\n } error - did not throw`;\n\n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push({\n message: failureMessage,\n typeName: 'Error',\n valuesProvided: !isAnyErr,\n actual: undefined,\n expected: expectedErrorMsgStr\n } satisfies FailedAssertion);\n\n const errStr = `Expected thrown error but got none | Expected: \"${expectedErrorMsgStr}\"`\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n\n failTest(test, failureMessage, new Error(), logPrefix);\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 // using test.meta.lastError value set in failTest()\n throw createPoolError(\n `AssemblyScript __end_expect_throw() import called during test execution for ${test.name}`,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n );\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","/**\n * Extracts the short name from a WASM function table name identifier.\n */\nexport function getShortFunctionName(fullName: string): string {\n if (!fullName) {\n return '';\n }\n\n // URL decode first (handle potential decoding errors)\n let decoded: string;\n try {\n decoded = decodeURIComponent(fullName);\n } catch {\n decoded = fullName;\n }\n\n // Find the last '/' that's not inside angle brackets or parens\n let angleBracketDepth = 0;\n let parenDepth = 0;\n let lastSlashOutsideBrackets = -1;\n\n for (let i = 0; i < decoded.length; i++) {\n const char = decoded[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && decoded[i - 1] !== '=') {\n angleBracketDepth--;\n } else if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n } else if (char === '/' && angleBracketDepth === 0 && parenDepth === 0) {\n lastSlashOutsideBrackets = i;\n }\n }\n\n const functionPart = lastSlashOutsideBrackets >= 0\n ? decoded.substring(lastSlashOutsideBrackets + 1)\n : decoded;\n\n // Handle anonymous function case: \"file.as.test~anonymous|1\" → \"anonymous|1\"\n const anonymousMatch = functionPart.match(/^.+~(anonymous\\|\\d+)$/);\n if (anonymousMatch) {\n return anonymousMatch[1]!;\n }\n\n // Process any generics/paths in the function signature\n return shortenTypePart(functionPart);\n}\n\n/**\n * Finds the index of the closing '>' that matches the opening '<' at openIndex.\n */\nfunction findMatchingCloseBracket(str: string, openIndex: number): number {\n let angleBracketDepth = 1;\n\n for (let i = openIndex + 1; i < str.length; i++) {\n const char = str[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n if (angleBracketDepth === 0) return i;\n }\n }\n return str.length - 1;\n}\n\n/**\n * Finds the index of the closing ')' that matches the opening '(' at openIndex.\n */\nfunction findMatchingCloseParen(str: string, openIndex: number): number {\n let parenDepth = 1;\n let angleBracketDepth = 0;\n\n for (let i = openIndex + 1; i < str.length; i++) {\n const char = str[i];\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) return i;\n } else if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n }\n }\n return str.length - 1;\n}\n\n/**\n * Splits a string by commas at the top level (not inside <> or ()).\n */\nfunction splitByTopLevelComma(str: string): string[] {\n const parts: string[] = [];\n let current = '';\n let angleBracketDepth = 0;\n let parenDepth = 0;\n\n for (let i = 0; i < str.length; i++) {\n const char = str[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n } else if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n } else if (char === ',' && angleBracketDepth === 0 && parenDepth === 0) {\n parts.push(current);\n current = '';\n continue;\n }\n current += char;\n }\n parts.push(current);\n return parts;\n}\n\n/**\n * Processes the content inside generic brackets or function args.\n */\nfunction shortenGenericContent(content: string): string {\n const parts = splitByTopLevelComma(content);\n return parts.map(part => shortenTypePart(part.trim())).join(',');\n}\n\n/**\n * Shortens a function type like (args)=>returnType.\n */\nfunction shortenFunctionType(part: string): string {\n const closeParenIndex = findMatchingCloseParen(part, 0);\n const argsContent = part.substring(1, closeParenIndex);\n const afterParen = part.substring(closeParenIndex + 1);\n\n const shortenedArgs = argsContent ? shortenGenericContent(argsContent) : '';\n\n let returnPart = afterParen;\n if (afterParen.startsWith('=>') && afterParen.length > 2) {\n const returnType = afterParen.substring(2);\n returnPart = '=>' + shortenTypePart(returnType);\n }\n\n return '(' + shortenedArgs + ')' + returnPart;\n}\n\n/**\n * Shortens a type/function part, processing paths and generics recursively.\n */\nfunction shortenTypePart(part: string): string {\n // Function types\n if (part.startsWith('(')) {\n return shortenFunctionType(part);\n }\n\n const openBracket = part.indexOf('<');\n\n if (openBracket === -1) {\n // No generics - extract last path segment if present\n if (!part.includes('/')) {\n return part;\n }\n return part.substring(part.lastIndexOf('/') + 1);\n }\n\n // Has generics - extract name and process content\n const namePart = part.substring(0, openBracket);\n const closeBracket = findMatchingCloseBracket(part, openBracket);\n const genericContent = part.substring(openBracket + 1, closeBracket);\n\n const name = namePart.includes('/')\n ? namePart.substring(namePart.lastIndexOf('/') + 1)\n : namePart;\n\n const shortenedContent = shortenGenericContent(genericContent);\n\n return name + '<' + shortenedContent + '>';\n}\n","/**\n * Error Enhancement and Source Mapping\n *\n * This module handles mapping WASM errors to AssemblyScript source locations\n * using source maps. It enhances error messages and stack traces with accurate\n * file:line:column information for better developer experience.\n */\n\nimport { type ParsedStack } from '@vitest/utils';\nimport { diff, type SerializedDiffOptions } from '@vitest/utils/diff';\nimport type { Test, Suite } from '@vitest/runner/types';\nimport { type RawSourceMap, SourceMapConsumer } from 'source-map';\n\nimport type { AssemblyScriptTestError, HighlightFunc, WebAssemblyCallSite } from '../types/types.js';\nimport { debug } from '../util/debug.js';\nimport { POOL_INTERNAL_PATHS, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { createWebAssemblyCallSite, parseSourceMap } from './source-maps.js';\nimport { getShortFunctionName } from './wasm-names.js';\nimport {\n getSourceCodeFrameString,\n toPlaintextStackFrameString,\n toVitestLikeStackFrameString,\n} from '../util/test-error-formatting.js';\n\nconst POOL_INTERNAL_PATHS_SET = new Set(POOL_INTERNAL_PATHS);\n\nasync function sourceMapRawCallStack(\n rawCallStack: NodeJS.CallSite[],\n sourceMap: RawSourceMap,\n loggingPrefix: string,\n): Promise<WebAssemblyCallSite[]> {\n const mappedStack: WebAssemblyCallSite[] = [];\n\n if (!rawCallStack || rawCallStack.length === 0) {\n return mappedStack;\n }\n\n const sourceMapConsumer = await new SourceMapConsumer(sourceMap);\n \n // map stack call sites from raw WASM locations to source locations \n rawCallStack.forEach(callSite => {\n const mappedCallSite = createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix);\n if (mappedCallSite) {\n mappedStack.push(mappedCallSite);\n }\n }); \n \n sourceMapConsumer.destroy();\n\n return mappedStack;\n}\n\n// Parse source-mapped stack array to Vitest TestError reporting format\nfunction parseMappedStack(mappedStack: WebAssemblyCallSite[], isAssertionFailure: boolean): ParsedStack[] {\n return mappedStack\n // if this is an assertion failure, filter out frames for internal assertion framework calls\n // (e.g. assert(), assertEqual(), etc) by known location, for more concise/meaningful error stack report\n .filter(frame => !(isAssertionFailure && POOL_INTERNAL_PATHS_SET.has(frame.location.filePath)))\n \n // map to format that vitest reporter can display\n .map(frame => ({\n method: getShortFunctionName(frame.functionName),\n file: frame.location.filePath,\n line: frame.location.line,\n column: frame.location.column + 1, // Convert from raw 0-indexed to 1-indexed for display\n }));\n}\n\nexport async function processWASMErrorStack(\n rawCallStack: NodeJS.CallSite[],\n sourceMap: string,\n isAssertionFailure: boolean,\n loggingPrefix: string,\n): Promise<{ parsedStack: ParsedStack[], parsedSourceMap: RawSourceMap }> {\n const sourceMapObj = parseSourceMap(sourceMap);\n\n // map stack call sites from WASM locations to source code locations \n const sourceMappedStack = await sourceMapRawCallStack(rawCallStack, sourceMapObj, loggingPrefix);\n\n debug(`${loggingPrefix} - Mapped ${rawCallStack.length} call sites to ${sourceMappedStack.length} source locations`);\n\n return {\n parsedStack: parseMappedStack(sourceMappedStack, isAssertionFailure),\n parsedSourceMap: sourceMapObj,\n };\n}\n\n/**\n * Enhance reportable test error on the provided test result with source mapped stack locations\n * and a formatted diff based on the error type\n */\nexport async function enhanceTestError(\n error: AssemblyScriptTestError,\n task: Test | Suite,\n sourceMap: string,\n valuesProvided: boolean,\n logPrefix: string,\n highlight: HighlightFunc,\n rawCallStack?: NodeJS.CallSite[],\n diffOptions?: SerializedDiffOptions\n): Promise<AssemblyScriptTestError> {\n const isAssertionFailure = error.name === TEST_ERROR_NAMES.AssertionError;\n let expectedVsActualDiffString: string = '';\n\n if (isAssertionFailure && valuesProvided) {\n // remain undefined if there were no expected/actual values provided with the assertion failure\n expectedVsActualDiffString = diff(error.expected, error.actual, diffOptions) ?? '';\n }\n\n // if there's no stack to map, set the expected vs actual diff (if any) and return\n if (!rawCallStack || rawCallStack.length === 0) {\n error.diff = expectedVsActualDiffString;\n\n // stack is used by vitest for error deduplication, so make sure it is set\n error.stack = `${task.name} - ${error.message}`;\n\n return error;\n }\n\n // map stack call sites from WASM locations to source locations\n const { parsedStack, parsedSourceMap } = await processWASMErrorStack(rawCallStack, sourceMap, isAssertionFailure, logPrefix);\n \n // build additional strings to add to test error's `diff` field based on parsed stack contents\n let primaryStackFrameString: string | undefined;\n let highlightedSourceCodeFrameString: string | undefined;\n \n if (parsedStack.length > 0) {\n const primaryStackFrame = parsedStack[0]!;\n \n primaryStackFrameString = toVitestLikeStackFrameString(primaryStackFrame);\n \n // Test error is set to rest of the stack without the first frame.\n // Vitest will report the ParsedError[] on TestError.stacks below the diff we set.\n error.stacks = parsedStack.slice(1);\n\n // get source code diff from source map source content\n highlightedSourceCodeFrameString = getSourceCodeFrameString(parsedSourceMap, primaryStackFrame, highlight);\n\n debug(`${logPrefix} - Enhanced ${error.name} error with parsed source stack`);\n }\n\n // Use the diff field as our way to show all output (other than result.error.stacks)\n if (isAssertionFailure) {\n error.diff = [\n `${expectedVsActualDiffString}${expectedVsActualDiffString ? '\\n\\n' : ''}`,\n `${primaryStackFrameString}\\n`,\n `${highlightedSourceCodeFrameString}`,\n ].join('');\n } else {\n error.diff = [\n `${primaryStackFrameString}\\n`,\n `${highlightedSourceCodeFrameString}`,\n ].join('');\n }\n\n // stack is used by vitest for error deduplication, so make sure it is set\n error.stack = parsedStack.map(toPlaintextStackFrameString).join('\\n');\n \n debug(`[${logPrefix} - Enhanced ${error.name} error with diffs`);\n\n return error;\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 { POOL_ERROR_NAMES, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } 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, createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { getTaskLogLabel } from '../util/vitest-tasks.js';\nimport { extractCallStack } from './source-maps.js';\n\nconst DEBUG_COVERAGE_EXTRACT = false;\nconst SIG_MISMATCH_ERROR_MSG = `WASM RuntimeError indicates function signature type mismatch during test suite collection.`\n + ` This is likely caused by passing a non-void callback to expect().`\n + ` Use braces to ensure it returns void e.g. \\`expect(() => { failingFunction(); }).toThrowError()\\`.`\n + ` Look for the failing expect() within the describe() block indicated in the stack trace.`\n\nfunction covDebug(...args: any[]): void {\n if (DEBUG_COVERAGE_EXTRACT) {\n debug(...args);\n }\n};\n\nfunction createExecutorPoolError(\n testFileBasename: string,\n context: string,\n reason: string,\n cause?: any,\n): AssemblyScriptPoolError {\n return createPoolError(\n `${testFileBasename} - ${context} WASM executor: ${reason}`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n undefined,\n cause\n );\n}\n\n/**\n * Discover tests via test() and suites via describe() registration calls\n */\nexport async function executeWASMDiscovery(\n binary: Uint8Array,\n sourceMap: string,\n testFileBasename: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n isBinaryInstrumented: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n file: File,\n moduleLabel: string,\n threadImports: ThreadImports,\n diffOptions?: SerializedDiffOptions,\n): Promise<void> {\n const base = basename(file.filepath);\n const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(base, file)}`;\n const wasmModule = await WebAssembly.compile(binary as BufferSource);\n const memory = createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax);\n\n // Create coverage memory matching instrumentation expections (from user config).\n // While this memory will not be used, discovery instantiates the same binary,\n // and WebAssembly.Instance will throw if the expected memory sizes don't match\n const coverageMemory = isBinaryInstrumented ?\n createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax)\n : undefined;\n\n const importObject = createDiscoveryImports(\n memory,\n wasmModule,\n file,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createWasmImports\n );\n\n // Instantiate WASM module\n const instance = new WebAssembly.Instance(wasmModule, 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 try {\n exports._start();\n } catch (error) {\n const thrownErrAny: any = error as any;\n\n const isFunctionSignatureMismatch: boolean = error instanceof WebAssembly.RuntimeError\n && thrownErrAny?.message.includes('null function or function signature mismatch');\n if (isFunctionSignatureMismatch) {\n const runtimeError = error as WebAssembly.RuntimeError;\n const stack = extractCallStack(runtimeError);\n const testError = await enhanceTestError(\n {\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n message: runtimeError.message\n } satisfies AssemblyScriptTestError,\n file,\n sourceMap,\n false,\n logPrefix,\n threadImports.highlight,\n stack,\n diffOptions\n );\n\n throw createPoolError(\n `${SIG_MISMATCH_ERROR_MSG}\\n Caused by: ${runtimeError.name}: ${runtimeError.message}`,\n POOL_ERROR_NAMES.PoolSyntaxError,\n undefined,\n testError\n );\n }\n\n // Check to see if error came from the discovery abort() handler\n // For discovery abort, test error is set on PoolError's `cause`,\n // and the raw call stack is on PoolError's `rawCallStack`\n if (\n thrownErrAny?.name === POOL_ERROR_NAMES.WASMExecutionAbortError\n && thrownErrAny?.cause?.name === TEST_ERROR_NAMES.WASMRuntimeError\n && (error as AssemblyScriptPoolError).rawCallStack\n ) {\n const thrownPoolErr = thrownErrAny as AssemblyScriptPoolError;\n thrownPoolErr.cause = await enhanceTestError(\n thrownPoolErr.cause as AssemblyScriptTestError,\n file,\n sourceMap,\n false,\n logPrefix,\n threadImports.highlight,\n thrownPoolErr.rawCallStack,\n diffOptions\n );\n thrownPoolErr.causeIsEnhancedError = true;\n\n // delete the raw stack so vitest doesn't complain about unexpected error values\n delete thrownPoolErr.rawCallStack;\n\n // rethrow it with the enhanced test error\n throw thrownPoolErr;\n } else {\n throw createPoolErrorFromAnyError(\n `${testFileBasename} - Unexpected discovery error`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n error\n );\n }\n }\n } else {\n throw createExecutorPoolError(testFileBasename, 'discoverTests', 'no _start() export');\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 testFileBasename: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n collectCoverage: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n moduleLabel: string,\n threadImports: ThreadImports,\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 // Compile the binary to usable WASM module\n const wasmModule = await WebAssembly.compile(compilation.binary as BufferSource);\n\n // Create fresh memory for this test instance\n const memory = createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax);\n\n // Create coverage memory if collecting coverage (instrumented binary)\n const coverageMemory = collectCoverage ?\n createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax)\n : undefined;\n\n // Create import object with pool-side functions for capturing test execution results\n const { imports, provideFunctionTable } = createTestExecutionImports(\n memory,\n wasmModule,\n test,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createWasmImports\n );\n\n // Instantiate fresh WASM instance for this test\n const instance = new WebAssembly.Instance(wasmModule, 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 createExecutorPoolError(testFileBasename, 'executeWASMTest', 'no _start() export');\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 createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n `Test function at index ${idx} not found in function table`\n );\n }\n } else {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\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) {\n testTimings.execEnd = performance.now();\n\n const thrownErrAny = error as any;\n // If this is NOT a WASMExecutionAbort error, it means it did NOT originate from the\n // wasm abort() import and is unexpected, so we throw as a PoolError.\n //\n // Otherwise this IS a WASMExecutionAbort error and the wasm abort() import threw it as a\n // known test error (assertion or wasm runtime), so we continue to prepare the test result \n const isUnexpectedError = thrownErrAny?.name !== POOL_ERROR_NAMES.WASMExecutionAbortError;\n\n if (isUnexpectedError) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n `Unexpected execution error: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`,\n (error as any)?.cause\n );\n }\n }\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n \n // If error is present, apply source mapping to make stack locations\n // useful, and add nicely-formatted diffs for reporting through vitest\n if (meta.lastError) {\n const enhancedError = await enhanceTestError(\n meta.lastError,\n test,\n compilation.sourceMap,\n meta.lastErrorValuesProvided ?? false,\n logPrefix,\n threadImports.highlight,\n meta.lastErrorRawCallStack,\n diffOptions\n );\n\n if (test.result) {\n if (test.result.errors) {\n test.result.errors.push(enhancedError);\n } else {\n test.result.errors = [enhancedError];\n }\n }\n\n delete meta.lastError;\n delete meta.lastErrorValuesProvided;\n delete meta.lastErrorRawCallStack;\n }\n\n // Extract coverage hits from coverage memory\n if (collectCoverage) {\n if (!coverageMemory) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n 'Coverage memory not created despite collectCoverage=true'\n );\n }\n\n if (!compilation.debugInfo) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n 'debugInfo is required when 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, funcInfo] of Object.entries(debugFunctions)) {\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\n if (coverage.hitCountsByFileAndPosition[filePath][positionKey] !== undefined) {\n debug(`${logPrefix} - WARNING: DUPLICATE POSITION`\n + ` - func \"${funcInfo.name}\" (${positionKey}) already extracted to coverage for ${filePath}`\n );\n }\n // Position key is already the position (line:column) from functionsByFileAndPosition\n coverage.hitCountsByFileAndPosition[filePath][positionKey] = hitCount;\n\n if (hitCount > 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, isDebugModeEnabled } 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// const DEBUG_RPC = false;\nconst DEBUG_RPC = isDebugModeEnabled();\n\nfunction rpcDebug(...args: any[]): void {\n if (DEBUG_RPC) {\n debug(...args);\n }\n};\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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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';\n\nimport type { WasmImportsFactory } from '../types/types.js';\nimport { debug } from '../util/debug.js';\nimport { AS_POOL_ERROR_TYPE_FLAG } from '../types/constants.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\n try {\n const start = performance.now();\n const createWasmImports = (await import(path)).default;\n debug(`[${logModule}] TIMING Imported user WasmImportsFactory in ${(performance.now() - start).toFixed(2)} ms`);\n\n if (typeof createWasmImports !== 'function') {\n throw new Error(\n `User config for \\`wasmImportsFactor\\` must be the path to a module with a default export matching () => WebAssembly.Imports `\n + `- Imported: \"${typeof createWasmImports}\": ${String(createWasmImports)}`\n );\n } else {\n return createWasmImports;\n }\n } catch (error) {\n if ((error as any)[AS_POOL_ERROR_TYPE_FLAG]) {\n throw error;\n }\n \n throw new Error(\n `Could not load user WasmImportsFactory from \"${path}\".`\n + ` Ensure that your module path is relative to the project root (location of shallowest vitest config),`\n + ` and that it has a default export matching () => WebAssembly.Imports`,\n { cause: error }\n );\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"load-user-imports-Bbmpaciu.mjs","names":[],"sources":["../src/util/assemblyscript/binding-helpers.ts","../src/wasm-executor/wasm-memory.ts","../src/wasm-executor/wasm-console.ts","../src/wasm-executor/collect-options.ts","../src/wasm-executor/wasm-imports.ts","../src/wasm-executor/wasm-names.ts","../src/wasm-executor/wasm-errors.ts","../src/wasm-executor/index.ts","../src/pool-thread/rpc-reporter.ts","../src/pool-thread/load-user-imports.ts"],"sourcesContent":["const STRING_EXTRACT_CHUNK_SIZE = 1024 as const;\n\n/**\n * Decode an AssemblyScript string from WASM memory, using the length stored at\n * the beginning of the string.\n *\n * This approach is borrowed from AssemblyScript with changes for clarity.\n * AssemblyScript is released under the Apache 2.0 license, included here.\n * \n * When a string argument crosses the boundary to JS, we get a pointer to the\n * string data in WASM memory. WASM strings store their length in the 4 bytes\n * before the string data pointer so we know how much to read from memory.\n *\n * @param memory - WebAssembly memory instance\n * @param pointer - Pointer to the start of the string\n * @returns Decoded string\n */\nexport function liftString(\n memory: WebAssembly.Memory,\n pointer: number,\n): string | undefined {\n if (!pointer) return undefined;\n\n const unsigned = pointer >>> 0;\n \n const lengthPtr = unsigned - 4;\n\n // convert byte-based lengthPtr to uint32-based index for Uint32Array\n // with: bytes / 4 (=== bytes >>> 2) and read length\n const uint32LengthPtr = lengthPtr >>> 2;\n const byteOffsetLength = new Uint32Array(memory.buffer)[uint32LengthPtr];\n\n if (byteOffsetLength === 0) return '';\n \n // calculate end pointer, and convert byte-based start and end pointers\n // to uint16-based indexes for Uint16Array with: bytes / 2 (=== bytes >>> 1) \n const uint16EndPtr = (unsigned + byteOffsetLength!) >>> 1;\n let uint16StartPtr = unsigned >>> 1;\n\n const memoryU16 = new Uint16Array(memory.buffer);\n let string = '';\n\n // extract in 1024-character chunks to avoid hitting spread operator limit\n while (uint16EndPtr - uint16StartPtr > STRING_EXTRACT_CHUNK_SIZE) {\n string += String.fromCharCode(\n ...memoryU16.subarray(uint16StartPtr, uint16StartPtr += STRING_EXTRACT_CHUNK_SIZE)\n );\n }\n\n return string + String.fromCharCode(...memoryU16.subarray(uint16StartPtr, uint16EndPtr));\n}\n","import { liftString } from '../util/assemblyscript/binding-helpers.js';\n\n/**\n * Create a WebAssembly memory instance\n * Used for imported memory pattern (matches --importMemory flag)\n */\nexport function createMemory(initialPages: number, maximumPages?: number): WebAssembly.Memory {\n return new WebAssembly.Memory({ initial: initialPages, maximum: maximumPages });\n}\n\n/**\n * Decode AssemblyScript abort information\n *\n * Helper for handling abort() calls from AssemblyScript runtime.\n * Decodes the error message and file path from WASM memory.\n *\n * @param memory - WebAssembly memory instance\n * @param msgPtr - Pointer to error message string (or 0 if none)\n * @param filePtr - Pointer to file path string (or 0 if none)\n * @param line - Line number where abort occurred\n * @param column - Column number where abort occurred\n * @returns Decoded message and location (null if no meaningful location info)\n */\nexport function decodeAbortInfo(\n memory: WebAssembly.Memory,\n msgPtr: number,\n filePtr: number,\n line: number,\n column: number\n): { message: string; location: string | null } {\n const errorMsg = liftString(memory, msgPtr) ?? 'Unknown error'; \n const filePath = liftString(memory, filePtr);\n\n // Only include location if we have meaningful file info (not null/empty and not at 0:0)\n const hasLocation = filePath && filePath !== 'unknown' && (line !== 0 || column !== 0);\n const location = hasLocation ? `${filePath}:${line}:${column}` : null;\n\n return {\n message: errorMsg,\n location: location,\n };\n}\n","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 { AS_POOL_WASM_IMPORTS_ENV, POOL_ERROR_NAMES, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } from '../util/debug.js';\nimport { createPoolError, createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { liftString } from '../util/assemblyscript/binding-helpers.js';\nimport { extractCallStack } from './source-maps.js';\nimport { decodeAbortInfo } from './wasm-memory.js';\nimport { createWasmConsole } from './wasm-console.js';\nimport { mergeAssemblyScriptTestOptions } from './collect-options.js';\nimport { createSuiteTask, createTestTask, failTest } 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 throw createPoolErrorFromAnyError(\n `Error creating user WASM Imports`,\n POOL_ERROR_NAMES.PoolConfigError,\n error\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 // Create error to capture V8 stack trace and extract V8 call stack before throwing.\n // This gives us WAT line:column positions that can be mapped to AS source\n const rawCallStack = extractCallStack(new Error());\n\n // Send the test error that we will report to vitest in the PoolError's `cause` field.\n // The rawCallStack will be enahnced and deleted by the executor, with the parsed result\n // added to the reported test error.\n const testError: AssemblyScriptTestError = {\n message,\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n };\n\n throw createPoolError(\n msgAtLoc,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n undefined, // stack\n testError, // cause\n rawCallStack\n );\n },\n },\n\n [AS_POOL_WASM_IMPORTS_ENV]: {\n\n ...(coverageMemory ? { __coverage_memory: 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 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 if (isExpectingError) {\n if (!expectedErrorMsgStr || message.includes(expectedErrorMsgStr)) {\n (test.meta as AssemblyScriptTestTaskMeta).assertionsPassedCount++;\n \n debug(`${logPrefix} - Thrown error matches expected - assertion passes`);\n\n throw createPoolError(\n `AssemblyScript abort() import called for expected error throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionAbortError\n );\n } else {\n failureMessage = `expected function to throw \"${expectedErrorMsgStr}\" error but received \"${message}\"`;\n\n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push({\n message: failureMessage,\n typeName: 'Error',\n valuesProvided: true,\n actual: message,\n expected: expectedErrorMsgStr\n } satisfies FailedAssertion);\n\n const errStr = `Thrown error does not match expected | Expected: \"${expectedErrorMsgStr}\" | Actual: \"${message}\"`\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n }\n }\n\n // Create error to capture V8 stack trace and extract V8 call stack before throwing.\n // This gives us WAT line:column positions that can be mapped to AS source\n const capturedError = new Error();\n\n failTest(test, failureMessage, capturedError, logPrefix);\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 // using test.meta.lastError value set in failTest()\n throw createPoolError(\n `AssemblyScript abort() import called during test execution for ${test.name}`,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n );\n },\n },\n\n [AS_POOL_WASM_IMPORTS_ENV]: {\n \n ...(coverageMemory ? { __coverage_memory: 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, typeNamePtr: number, valuesProvided: boolean, actualPtr?: number, expectedPtr?: number) {\n const errorMsg = liftString(memory, msgPtr);\n const assertionValueType = liftString(memory, typeNamePtr);\n let actual: string | undefined;\n let expected: string | undefined;\n \n const assertionFailure: FailedAssertion = {\n message: errorMsg,\n typeName: assertionValueType,\n valuesProvided: Boolean(valuesProvided)\n };\n \n if (valuesProvided && actualPtr && expectedPtr) {\n assertionFailure.actual = liftString(memory, actualPtr);\n assertionFailure.expected = liftString(memory, expectedPtr);\n }\n \n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push(assertionFailure);\n \n const valuesMsg = valuesProvided ? ` | Value Type: ${assertionValueType}`\n + ` | Expected: \\`${expected !== undefined ? expected : ''}\\` | Actual: \\`${actual !== undefined ? actual : ''}\\``\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: ${expectedErrorMsgStr !== undefined\n ? `\"${expectedErrorMsgStr}\"` : '<any>'}`\n );\n\n if (wasmFunctionTable && typeof wasmFunctionTable.get === 'function') {\n const fn = wasmFunctionTable.get(fnIndex);\n if (!fn) {\n throw createPoolError(\n `Could not access function (fnPtr ${fnIndex}) which is expected to throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\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 `Could not access WASM function table to call function expected to throw in test \"${test.name}\"`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n );\n }\n },\n\n __end_expect_throw() {\n if (isExpectingError) {\n const isAnyErr: boolean = !!expectedErrorMsgStr;\n const failureMessage = `expected function to throw ${isAnyErr ?\n `\"${expectedErrorMsgStr}\"` : 'any'\n } error - did not throw`;\n\n (test.meta as AssemblyScriptTestTaskMeta).assertionsFailed.push({\n message: failureMessage,\n typeName: 'Error',\n valuesProvided: !isAnyErr,\n actual: undefined,\n expected: expectedErrorMsgStr\n } satisfies FailedAssertion);\n\n const errStr = `Expected thrown error but got none | Expected: \"${expectedErrorMsgStr}\"`\n debug(`${logPrefix} - Assertion failed: ${errStr}`);\n\n failTest(test, failureMessage, new Error(), logPrefix);\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 // using test.meta.lastError value set in failTest()\n throw createPoolError(\n `AssemblyScript __end_expect_throw() import called during test execution for ${test.name}`,\n POOL_ERROR_NAMES.WASMExecutionAbortError,\n );\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","/**\n * Extracts the short name from a WASM function table name identifier.\n */\nexport function getShortFunctionName(fullName: string): string {\n if (!fullName) {\n return '';\n }\n\n // URL decode first (handle potential decoding errors)\n let decoded: string;\n try {\n decoded = decodeURIComponent(fullName);\n } catch {\n decoded = fullName;\n }\n\n // Find the last '/' that's not inside angle brackets or parens\n let angleBracketDepth = 0;\n let parenDepth = 0;\n let lastSlashOutsideBrackets = -1;\n\n for (let i = 0; i < decoded.length; i++) {\n const char = decoded[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && decoded[i - 1] !== '=') {\n angleBracketDepth--;\n } else if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n } else if (char === '/' && angleBracketDepth === 0 && parenDepth === 0) {\n lastSlashOutsideBrackets = i;\n }\n }\n\n const functionPart = lastSlashOutsideBrackets >= 0\n ? decoded.substring(lastSlashOutsideBrackets + 1)\n : decoded;\n\n // Handle anonymous function case: \"file.as.test~anonymous|1\" → \"anonymous|1\"\n const anonymousMatch = functionPart.match(/^.+~(anonymous\\|\\d+)$/);\n if (anonymousMatch) {\n return anonymousMatch[1]!;\n }\n\n // Process any generics/paths in the function signature\n return shortenTypePart(functionPart);\n}\n\n/**\n * Finds the index of the closing '>' that matches the opening '<' at openIndex.\n */\nfunction findMatchingCloseBracket(str: string, openIndex: number): number {\n let angleBracketDepth = 1;\n\n for (let i = openIndex + 1; i < str.length; i++) {\n const char = str[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n if (angleBracketDepth === 0) return i;\n }\n }\n return str.length - 1;\n}\n\n/**\n * Finds the index of the closing ')' that matches the opening '(' at openIndex.\n */\nfunction findMatchingCloseParen(str: string, openIndex: number): number {\n let parenDepth = 1;\n let angleBracketDepth = 0;\n\n for (let i = openIndex + 1; i < str.length; i++) {\n const char = str[i];\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) return i;\n } else if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n }\n }\n return str.length - 1;\n}\n\n/**\n * Splits a string by commas at the top level (not inside <> or ()).\n */\nfunction splitByTopLevelComma(str: string): string[] {\n const parts: string[] = [];\n let current = '';\n let angleBracketDepth = 0;\n let parenDepth = 0;\n\n for (let i = 0; i < str.length; i++) {\n const char = str[i];\n if (char === '<') {\n angleBracketDepth++;\n } else if (char === '>' && str[i - 1] !== '=') {\n angleBracketDepth--;\n } else if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n } else if (char === ',' && angleBracketDepth === 0 && parenDepth === 0) {\n parts.push(current);\n current = '';\n continue;\n }\n current += char;\n }\n parts.push(current);\n return parts;\n}\n\n/**\n * Processes the content inside generic brackets or function args.\n */\nfunction shortenGenericContent(content: string): string {\n const parts = splitByTopLevelComma(content);\n return parts.map(part => shortenTypePart(part.trim())).join(',');\n}\n\n/**\n * Shortens a function type like (args)=>returnType.\n */\nfunction shortenFunctionType(part: string): string {\n const closeParenIndex = findMatchingCloseParen(part, 0);\n const argsContent = part.substring(1, closeParenIndex);\n const afterParen = part.substring(closeParenIndex + 1);\n\n const shortenedArgs = argsContent ? shortenGenericContent(argsContent) : '';\n\n let returnPart = afterParen;\n if (afterParen.startsWith('=>') && afterParen.length > 2) {\n const returnType = afterParen.substring(2);\n returnPart = '=>' + shortenTypePart(returnType);\n }\n\n return '(' + shortenedArgs + ')' + returnPart;\n}\n\n/**\n * Shortens a type/function part, processing paths and generics recursively.\n */\nfunction shortenTypePart(part: string): string {\n // Function types\n if (part.startsWith('(')) {\n return shortenFunctionType(part);\n }\n\n const openBracket = part.indexOf('<');\n\n if (openBracket === -1) {\n // No generics - extract last path segment if present\n if (!part.includes('/')) {\n return part;\n }\n return part.substring(part.lastIndexOf('/') + 1);\n }\n\n // Has generics - extract name and process content\n const namePart = part.substring(0, openBracket);\n const closeBracket = findMatchingCloseBracket(part, openBracket);\n const genericContent = part.substring(openBracket + 1, closeBracket);\n\n const name = namePart.includes('/')\n ? namePart.substring(namePart.lastIndexOf('/') + 1)\n : namePart;\n\n const shortenedContent = shortenGenericContent(genericContent);\n\n return name + '<' + shortenedContent + '>';\n}\n","/**\n * Error Enhancement and Source Mapping\n *\n * This module handles mapping WASM errors to AssemblyScript source locations\n * using source maps. It enhances error messages and stack traces with accurate\n * file:line:column information for better developer experience.\n */\n\nimport { type ParsedStack } from '@vitest/utils';\nimport { diff, type SerializedDiffOptions } from '@vitest/utils/diff';\nimport type { Test, Suite } from '@vitest/runner/types';\nimport { type RawSourceMap, SourceMapConsumer } from 'source-map';\n\nimport type { AssemblyScriptTestError, HighlightFunc, WebAssemblyCallSite } from '../types/types.js';\nimport { debug } from '../util/debug.js';\nimport { POOL_INTERNAL_PATHS, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { createWebAssemblyCallSite, parseSourceMap } from './source-maps.js';\nimport { getShortFunctionName } from './wasm-names.js';\nimport {\n getSourceCodeFrameString,\n toPlaintextStackFrameString,\n toVitestLikeStackFrameString,\n} from '../util/test-error-formatting.js';\n\nconst POOL_INTERNAL_PATHS_SET = new Set(POOL_INTERNAL_PATHS);\n\nasync function sourceMapRawCallStack(\n rawCallStack: NodeJS.CallSite[],\n sourceMap: RawSourceMap,\n loggingPrefix: string,\n): Promise<WebAssemblyCallSite[]> {\n const mappedStack: WebAssemblyCallSite[] = [];\n\n if (!rawCallStack || rawCallStack.length === 0) {\n return mappedStack;\n }\n\n const sourceMapConsumer = await new SourceMapConsumer(sourceMap);\n \n // map stack call sites from raw WASM locations to source locations \n rawCallStack.forEach(callSite => {\n const mappedCallSite = createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix);\n if (mappedCallSite) {\n mappedStack.push(mappedCallSite);\n }\n }); \n \n sourceMapConsumer.destroy();\n\n return mappedStack;\n}\n\n// Parse source-mapped stack array to Vitest TestError reporting format\nfunction parseMappedStack(mappedStack: WebAssemblyCallSite[], isAssertionFailure: boolean): ParsedStack[] {\n return mappedStack\n // if this is an assertion failure, filter out frames for internal assertion framework calls\n // (e.g. assert(), assertEqual(), etc) by known location, for more concise/meaningful error stack report\n .filter(frame => !(isAssertionFailure && POOL_INTERNAL_PATHS_SET.has(frame.location.filePath)))\n \n // map to format that vitest reporter can display\n .map(frame => ({\n method: getShortFunctionName(frame.functionName),\n file: frame.location.filePath,\n line: frame.location.line,\n column: frame.location.column + 1, // Convert from raw 0-indexed to 1-indexed for display\n }));\n}\n\nexport async function processWASMErrorStack(\n rawCallStack: NodeJS.CallSite[],\n sourceMap: string,\n isAssertionFailure: boolean,\n loggingPrefix: string,\n): Promise<{ parsedStack: ParsedStack[], parsedSourceMap: RawSourceMap }> {\n const sourceMapObj = parseSourceMap(sourceMap);\n\n // map stack call sites from WASM locations to source code locations \n const sourceMappedStack = await sourceMapRawCallStack(rawCallStack, sourceMapObj, loggingPrefix);\n\n debug(`${loggingPrefix} - Mapped ${rawCallStack.length} call sites to ${sourceMappedStack.length} source locations`);\n\n return {\n parsedStack: parseMappedStack(sourceMappedStack, isAssertionFailure),\n parsedSourceMap: sourceMapObj,\n };\n}\n\n/**\n * Enhance reportable test error on the provided test result with source mapped stack locations\n * and a formatted diff based on the error type\n */\nexport async function enhanceTestError(\n error: AssemblyScriptTestError,\n task: Test | Suite,\n sourceMap: string,\n valuesProvided: boolean,\n logPrefix: string,\n highlight: HighlightFunc,\n rawCallStack?: NodeJS.CallSite[],\n diffOptions?: SerializedDiffOptions\n): Promise<AssemblyScriptTestError> {\n const isAssertionFailure = error.name === TEST_ERROR_NAMES.AssertionError;\n let expectedVsActualDiffString: string = '';\n\n if (isAssertionFailure && valuesProvided) {\n // remain undefined if there were no expected/actual values provided with the assertion failure\n expectedVsActualDiffString = diff(error.expected, error.actual, diffOptions) ?? '';\n }\n\n // if there's no stack to map, set the expected vs actual diff (if any) and return\n if (!rawCallStack || rawCallStack.length === 0) {\n error.diff = expectedVsActualDiffString;\n\n // stack is used by vitest for error deduplication, so make sure it is set\n error.stack = `${task.name} - ${error.message}`;\n\n return error;\n }\n\n // map stack call sites from WASM locations to source locations\n const { parsedStack, parsedSourceMap } = await processWASMErrorStack(rawCallStack, sourceMap, isAssertionFailure, logPrefix);\n \n // build additional strings to add to test error's `diff` field based on parsed stack contents\n let primaryStackFrameString: string | undefined;\n let highlightedSourceCodeFrameString: string | undefined;\n \n if (parsedStack.length > 0) {\n const primaryStackFrame = parsedStack[0]!;\n \n primaryStackFrameString = toVitestLikeStackFrameString(primaryStackFrame);\n \n // Test error is set to rest of the stack without the first frame.\n // Vitest will report the ParsedError[] on TestError.stacks below the diff we set.\n error.stacks = parsedStack.slice(1);\n\n // get source code diff from source map source content\n highlightedSourceCodeFrameString = getSourceCodeFrameString(parsedSourceMap, primaryStackFrame, highlight);\n\n debug(`${logPrefix} - Enhanced ${error.name} error with parsed source stack`);\n }\n\n // Use the diff field as our way to show all output (other than result.error.stacks)\n if (isAssertionFailure) {\n error.diff = [\n `${expectedVsActualDiffString}${expectedVsActualDiffString ? '\\n\\n' : ''}`,\n `${primaryStackFrameString}\\n`,\n `${highlightedSourceCodeFrameString}`,\n ].join('');\n } else {\n error.diff = [\n `${primaryStackFrameString}\\n`,\n `${highlightedSourceCodeFrameString}`,\n ].join('');\n }\n\n // stack is used by vitest for error deduplication, so make sure it is set\n error.stack = parsedStack.map(toPlaintextStackFrameString).join('\\n');\n \n debug(`[${logPrefix} - Enhanced ${error.name} error with diffs`);\n\n return error;\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 { POOL_ERROR_NAMES, TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } 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, createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { getTaskLogLabel } from '../util/vitest-tasks.js';\nimport { extractCallStack } from './source-maps.js';\n\nconst DEBUG_COVERAGE_EXTRACT = false;\nconst SIG_MISMATCH_ERROR_MSG = `WASM RuntimeError indicates function signature type mismatch during test suite collection.`\n + ` This is likely caused by passing a non-void callback to expect().`\n + ` Use braces to ensure it returns void e.g. \\`expect(() => { failingFunction(); }).toThrowError()\\`.`\n + ` Look for the failing expect() within the describe() block indicated in the stack trace.`\n\nfunction covDebug(...args: any[]): void {\n if (DEBUG_COVERAGE_EXTRACT) {\n debug(...args);\n }\n};\n\nfunction createExecutorPoolError(\n testFileBasename: string,\n context: string,\n reason: string,\n cause?: any,\n): AssemblyScriptPoolError {\n return createPoolError(\n `${testFileBasename} - ${context} WASM executor: ${reason}`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n undefined,\n cause\n );\n}\n\n/**\n * Discover tests via test() and suites via describe() registration calls\n */\nexport async function executeWASMDiscovery(\n binary: Uint8Array,\n sourceMap: string,\n testFileBasename: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n isBinaryInstrumented: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n file: File,\n moduleLabel: string,\n threadImports: ThreadImports,\n diffOptions?: SerializedDiffOptions,\n): Promise<void> {\n const base = basename(file.filepath);\n const logPrefix = `[${moduleLabel} Exec] ${getTaskLogLabel(base, file)}`;\n const wasmModule = await WebAssembly.compile(binary as BufferSource);\n const memory = createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax);\n\n // Create coverage memory matching instrumentation expections (from user config).\n // While this memory will not be used, discovery instantiates the same binary,\n // and WebAssembly.Instance will throw if the expected memory sizes don't match\n const coverageMemory = isBinaryInstrumented ?\n createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax)\n : undefined;\n\n const importObject = createDiscoveryImports(\n memory,\n wasmModule,\n file,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createWasmImports\n );\n\n // Instantiate WASM module\n const instance = new WebAssembly.Instance(wasmModule, 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 try {\n exports._start();\n } catch (error) {\n const thrownErrAny: any = error as any;\n\n const isFunctionSignatureMismatch: boolean = error instanceof WebAssembly.RuntimeError\n && thrownErrAny?.message.includes('null function or function signature mismatch');\n if (isFunctionSignatureMismatch) {\n const runtimeError = error as WebAssembly.RuntimeError;\n const stack = extractCallStack(runtimeError);\n const testError = await enhanceTestError(\n {\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n message: runtimeError.message\n } satisfies AssemblyScriptTestError,\n file,\n sourceMap,\n false,\n logPrefix,\n threadImports.highlight,\n stack,\n diffOptions\n );\n\n throw createPoolError(\n `${SIG_MISMATCH_ERROR_MSG}\\n Caused by: ${runtimeError.name}: ${runtimeError.message}`,\n POOL_ERROR_NAMES.PoolSyntaxError,\n undefined,\n testError\n );\n }\n\n // Check to see if error came from the discovery abort() handler\n // For discovery abort, test error is set on PoolError's `cause`,\n // and the raw call stack is on PoolError's `rawCallStack`\n if (\n thrownErrAny?.name === POOL_ERROR_NAMES.WASMExecutionAbortError\n && thrownErrAny?.cause?.name === TEST_ERROR_NAMES.WASMRuntimeError\n && (error as AssemblyScriptPoolError).rawCallStack\n ) {\n const thrownPoolErr = thrownErrAny as AssemblyScriptPoolError;\n thrownPoolErr.cause = await enhanceTestError(\n thrownPoolErr.cause as AssemblyScriptTestError,\n file,\n sourceMap,\n false,\n logPrefix,\n threadImports.highlight,\n thrownPoolErr.rawCallStack,\n diffOptions\n );\n thrownPoolErr.causeIsEnhancedError = true;\n\n // delete the raw stack so vitest doesn't complain about unexpected error values\n delete thrownPoolErr.rawCallStack;\n\n // rethrow it with the enhanced test error\n throw thrownPoolErr;\n } else {\n throw createPoolErrorFromAnyError(\n `${testFileBasename} - Unexpected discovery error`,\n POOL_ERROR_NAMES.WASMExecutionHarnessError,\n error\n );\n }\n }\n } else {\n throw createExecutorPoolError(testFileBasename, 'discoverTests', 'no _start() export');\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 testFileBasename: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n collectCoverage: boolean,\n handleLog: AssemblyScriptConsoleLogHandler,\n moduleLabel: string,\n threadImports: ThreadImports,\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 // Compile the binary to usable WASM module\n const wasmModule = await WebAssembly.compile(compilation.binary as BufferSource);\n\n // Create fresh memory for this test instance\n const memory = createMemory(poolOptions.testMemoryPagesInitial, poolOptions.testMemoryPagesMax);\n\n // Create coverage memory if collecting coverage (instrumented binary)\n const coverageMemory = collectCoverage ?\n createMemory(poolOptions.coverageMemoryPagesInitial, poolOptions.coverageMemoryPagesMax)\n : undefined;\n\n // Create import object with pool-side functions for capturing test execution results\n const { imports, provideFunctionTable } = createTestExecutionImports(\n memory,\n wasmModule,\n test,\n handleLog,\n logPrefix,\n coverageMemory,\n threadImports.createWasmImports\n );\n\n // Instantiate fresh WASM instance for this test\n const instance = new WebAssembly.Instance(wasmModule, 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 createExecutorPoolError(testFileBasename, 'executeWASMTest', 'no _start() export');\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 createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n `Test function at index ${idx} not found in function table`\n );\n }\n } else {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\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) {\n testTimings.execEnd = performance.now();\n\n const thrownErrAny = error as any;\n // If this is NOT a WASMExecutionAbort error, it means it did NOT originate from the\n // wasm abort() import and is unexpected, so we throw as a PoolError.\n //\n // Otherwise this IS a WASMExecutionAbort error and the wasm abort() import threw it as a\n // known test error (assertion or wasm runtime), so we continue to prepare the test result \n const isUnexpectedError = thrownErrAny?.name !== POOL_ERROR_NAMES.WASMExecutionAbortError;\n\n if (isUnexpectedError) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n `Unexpected execution error: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`,\n (error as any)?.cause\n );\n }\n }\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n \n // If error is present, apply source mapping to make stack locations\n // useful, and add nicely-formatted diffs for reporting through vitest\n if (meta.lastError) {\n const enhancedError = await enhanceTestError(\n meta.lastError,\n test,\n compilation.sourceMap,\n meta.lastErrorValuesProvided ?? false,\n logPrefix,\n threadImports.highlight,\n meta.lastErrorRawCallStack,\n diffOptions\n );\n\n if (test.result) {\n if (test.result.errors) {\n test.result.errors.push(enhancedError);\n } else {\n test.result.errors = [enhancedError];\n }\n }\n\n delete meta.lastError;\n delete meta.lastErrorValuesProvided;\n delete meta.lastErrorRawCallStack;\n }\n\n // Extract coverage hits from coverage memory\n if (collectCoverage) {\n if (!coverageMemory) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n 'Coverage memory not created despite collectCoverage=true'\n );\n }\n\n if (!compilation.debugInfo) {\n throw createExecutorPoolError(\n testFileBasename,\n 'executeWASMTest',\n 'debugInfo is required when 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, funcInfo] of Object.entries(debugFunctions)) {\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\n if (coverage.hitCountsByFileAndPosition[filePath][positionKey] !== undefined) {\n debug(`${logPrefix} - WARNING: DUPLICATE POSITION`\n + ` - func \"${funcInfo.name}\" (${positionKey}) already extracted to coverage for ${filePath}`\n );\n }\n // Position key is already the position (line:column) from functionsByFileAndPosition\n coverage.hitCountsByFileAndPosition[filePath][positionKey] = hitCount;\n\n if (hitCount > 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, isDebugModeEnabled } 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// const DEBUG_RPC = false;\nconst DEBUG_RPC = isDebugModeEnabled();\n\nfunction rpcDebug(...args: any[]): void {\n if (DEBUG_RPC) {\n debug(...args);\n }\n};\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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`${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 rpcDebug(`[${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 rpcDebug(`[${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 rpcDebug(`[${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 { AS_POOL_ERROR_TYPE_FLAG } from '../types/constants.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}] TIMING Imported user WasmImportsFactory in ${(performance.now() - start).toFixed(2)} ms`);\n\n if (typeof createWasmImports !== 'function') {\n throw new Error(\n `User config for \\`wasmImportsFactor\\` must be the path to a module with a default export matching () => WebAssembly.Imports `\n + `- Imported: \"${typeof createWasmImports}\": ${String(createWasmImports)}`\n );\n } else {\n return createWasmImports;\n }\n } catch (error) {\n if ((error as any)[AS_POOL_ERROR_TYPE_FLAG]) {\n throw error;\n }\n \n throw new Error(\n `Could not load user WasmImportsFactory from \"${safeUrl}\".`\n + ` Ensure that your module path is relative to the project root (location of shallowest vitest config),`\n + ` and that it has a default export matching () => WebAssembly.Imports`,\n { cause: error }\n );\n }\n};\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { debug, setGlobalDebugMode } from "../debug-IeEHsxy0.mjs";
|
|
2
2
|
import "../vitest-file-tasks-BUwzh375.mjs";
|
|
3
3
|
import "../vitest-tasks-BKS7689f.mjs";
|
|
4
|
-
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-
|
|
4
|
+
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-Bbmpaciu.mjs";
|
|
5
5
|
import "../compiler-CN6BRK_N.mjs";
|
|
6
|
-
import { runCompileAndDiscover } from "../compile-runner-
|
|
6
|
+
import { runCompileAndDiscover } from "../compile-runner-xGvQwgNf.mjs";
|
|
7
7
|
import { threadId, workerData } from "node:worker_threads";
|
|
8
8
|
import { highlight } from "@vitest/utils/highlight";
|
|
9
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { debug, setGlobalDebugMode } from "../debug-IeEHsxy0.mjs";
|
|
2
2
|
import "../vitest-tasks-BKS7689f.mjs";
|
|
3
|
-
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-
|
|
4
|
-
import { runSuite } from "../test-runner-
|
|
3
|
+
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-Bbmpaciu.mjs";
|
|
4
|
+
import { runSuite } from "../test-runner-BR4XyhMA.mjs";
|
|
5
5
|
import { basename } from "node:path";
|
|
6
6
|
import { threadId, workerData } from "node:worker_threads";
|
|
7
7
|
import { highlight } from "@vitest/utils/highlight";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { debug, setGlobalDebugMode } from "../debug-IeEHsxy0.mjs";
|
|
2
2
|
import "../vitest-file-tasks-BUwzh375.mjs";
|
|
3
3
|
import "../vitest-tasks-BKS7689f.mjs";
|
|
4
|
-
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-
|
|
4
|
+
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-Bbmpaciu.mjs";
|
|
5
5
|
import "../compiler-CN6BRK_N.mjs";
|
|
6
|
-
import { runCompileAndDiscover } from "../compile-runner-
|
|
7
|
-
import { runSuite } from "../test-runner-
|
|
6
|
+
import { runCompileAndDiscover } from "../compile-runner-xGvQwgNf.mjs";
|
|
7
|
+
import { runSuite } from "../test-runner-BR4XyhMA.mjs";
|
|
8
8
|
import { basename } from "node:path";
|
|
9
9
|
import { workerId } from "tinypool";
|
|
10
10
|
import { threadId, workerData } from "node:worker_threads";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { debug } from "./debug-IeEHsxy0.mjs";
|
|
2
2
|
import { checkFailsAndInvertResult, finalizeSuiteResult, flagTestFinalized, getRunnableTasks, getTaskLogPrefix, isSuiteOwnFile, resetTestForRetry, setSuitePrepareResult, setTestResultForTestPrepare, shouldRetryTask, updateSuiteFinishedResult, updateTestResultAfterRun } from "./vitest-tasks-BKS7689f.mjs";
|
|
3
|
-
import { executeWASMTest, reportSuiteFinished, reportSuitePrepare, reportTestFinished, reportTestPrepare, reportTestRetried, reportUserConsoleLogs } from "./load-user-imports-
|
|
3
|
+
import { executeWASMTest, reportSuiteFinished, reportSuitePrepare, reportTestFinished, reportTestPrepare, reportTestRetried, reportUserConsoleLogs } from "./load-user-imports-Bbmpaciu.mjs";
|
|
4
4
|
import { mergeCoverageData } from "./coverage-merge-0WqdC-dq.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/pool-thread/runner/test-runner.ts
|
|
@@ -139,4 +139,4 @@ async function runSuite(rpc, port, base, collectCoverage, compilation, suite, lo
|
|
|
139
139
|
|
|
140
140
|
//#endregion
|
|
141
141
|
export { runSuite };
|
|
142
|
-
//# sourceMappingURL=test-runner-
|
|
142
|
+
//# sourceMappingURL=test-runner-BR4XyhMA.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-runner-B2BpyPNK.mjs","names":[],"sources":["../src/pool-thread/runner/test-runner.ts"],"sourcesContent":["/**\n * Worker thread test runner logic for AssemblyScript Pool\n */\n\nimport type { MessagePort } from 'node:worker_threads';\nimport type { File, Suite, Task, Test } from '@vitest/runner/types';\nimport type { SerializedDiffOptions } from '@vitest/utils/diff';\n\nimport type {\n AssemblyScriptConsoleLog,\n AssemblyScriptConsoleLogHandler,\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestTaskMeta,\n ResolvedAssemblyScriptPoolOptions,\n TestExecutionEnd,\n TestExecutionStart,\n ThreadImports,\n VitestVersion,\n WASMCompilation,\n WorkerRPC,\n} from '../../types/types.js';\nimport { AS_POOL_WORKER_MSG_FLAG } from '../../types/constants.js';\nimport { executeWASMTest } from '../../wasm-executor/index.js';\nimport { debug } from '../../util/debug.js';\nimport {\n reportTestPrepare,\n reportTestFinished,\n reportTestRetried,\n reportUserConsoleLogs,\n reportSuitePrepare,\n reportSuiteFinished,\n} from '../rpc-reporter.js';\nimport {\n checkFailsAndInvertResult,\n finalizeSuiteResult,\n flagTestFinalized,\n getRunnableTasks,\n getTaskLogPrefix,\n resetTestForRetry,\n setSuitePrepareResult,\n setTestResultForTestPrepare,\n shouldRetryTask,\n updateSuiteFinishedResult,\n updateTestResultAfterRun,\n isSuiteOwnFile\n} from '../../util/vitest-tasks.js';\nimport { mergeCoverageData } from '../../coverage-provider/coverage-merge.js';\n\nasync function bailIfNeeded(\n rpc: WorkerRPC,\n bailConfig: number | undefined,\n testWithResult: Test,\n logPrefix: string,\n logModule: string,\n): Promise<void> {\n if (bailConfig && testWithResult.result?.state !== 'pass') {\n const previousFailures = await rpc.getCountOfFailedTests();\n const currentFailures = 1 + previousFailures;\n\n if (currentFailures >= bailConfig) {\n debug(`${logPrefix} bailing: ${currentFailures} failures >= ${bailConfig} to bail`);\n debug(`[${logModule}] -------- BAIL! ${currentFailures} failures >= ${bailConfig} to bail --------`);\n return rpc.onCancel('test-failure');\n }\n }\n}\n\nasync function postProcessTestResult(\n rpc: WorkerRPC,\n bailConfig: number | undefined,\n testWithResult: Test,\n logPrefix: string,\n logModule: string,\n): Promise<void> {\n // invert result if test configured as 'fails'\n checkFailsAndInvertResult(testWithResult, logPrefix);\n\n // bail now if this is a failed test above bail threshold\n return bailIfNeeded(rpc, bailConfig, testWithResult, logPrefix, logModule);\n}\n\nfunction notifyTestStart(port: MessagePort, test: Test): void {\n port.postMessage({\n executionStart: Date.now(),\n test,\n type: 'execution-start',\n [AS_POOL_WORKER_MSG_FLAG]: true\n } satisfies TestExecutionStart);\n}\n\nfunction notifyTestEnd(port: MessagePort, test: Test): void {\n port.postMessage({\n executionEnd: Date.now(),\n testTaskId: test.id,\n type: 'execution-end',\n [AS_POOL_WORKER_MSG_FLAG]: true\n } satisfies TestExecutionEnd);\n}\n\nasync function runTest(\n rpc: WorkerRPC,\n port: MessagePort,\n base: string,\n collectCoverage: boolean,\n compilation: WASMCompilation,\n test: Test,\n logModule: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n threadImports: ThreadImports,\n bail?: number,\n diffOptions?: SerializedDiffOptions,\n): Promise<void> {\n const testLogPrefix = getTaskLogPrefix(logModule, base, test);\n const logMessages: AssemblyScriptConsoleLog[] = [];\n const handleLog: AssemblyScriptConsoleLogHandler = (msg: string, isError: boolean = false): void => {\n logMessages.push({ msg, time: Date.now(), isError });\n };\n\n const executionStart = Date.now();\n\n let thisRunIsARetry: boolean = false;\n let testPreparePromise: Promise<void> = Promise.resolve();\n \n if (!test.retry || !test.result) {\n debug(`${testLogPrefix} - Beginning test run`);\n\n // first/only attempt: create test result and report test-prepare\n setTestResultForTestPrepare(test, executionStart);\n testPreparePromise = reportTestPrepare(rpc, test, logModule, base);\n } else if (test.retry && test.result ) {\n debug(`${testLogPrefix} - Beginning test retry run`);\n thisRunIsARetry = true;\n\n // this is a retry, reset the result state and meta\n resetTestForRetry(test, executionStart);\n }\n \n // inform pool of test task start so it can enforce timeouts\n notifyTestStart(port, test);\n\n const [_reported, { testTimings }] = await Promise.all([\n testPreparePromise,\n executeWASMTest(\n test,\n compilation,\n base,\n poolOptions,\n collectCoverage,\n handleLog,\n logModule,\n threadImports,\n diffOptions\n )\n ]);\n\n // inform pool of test task end to stop timeout if under threshold\n notifyTestEnd(port, test);\n\n // update run->pass if appropriate, accumulate duration using executor timings\n updateTestResultAfterRun(test, testTimings);\n\n let willRetry = shouldRetryTask(test);\n\n await Promise.all([\n reportUserConsoleLogs(rpc, logMessages, logModule, base, test),\n\n willRetry ? reportTestRetried(rpc, test, logModule, base) : Promise.resolve(),\n ]);\n\n if (thisRunIsARetry) {\n debug(`${testLogPrefix} - Completed test retry run`);\n return;\n }\n\n // non-timeout retry handling\n while (willRetry) {\n // increment the retry count\n test.result!.retryCount = (test.result?.retryCount ?? 0) + 1;\n\n debug(`${testLogPrefix} - Retrying after failure`\n + ` | Retry ${test.result?.retryCount || 0} / ${test.retry} ` \n + ` | ${test.result?.errors?.length ?? 0} errors`\n );\n\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n test, logModule, poolOptions, threadImports, bail, diffOptions\n );\n\n willRetry = shouldRetryTask(test);\n\n if (!willRetry) {\n debug(`${testLogPrefix} - Max retries ${test.result?.retryCount || 0} / ${test.retry} ` \n + ` | ${test.result?.errors?.length ?? 0} errors`\n );\n }\n }\n\n await Promise.all([\n // as needed: invert if `fails`, bail\n postProcessTestResult(rpc, bail, test, testLogPrefix, logModule),\n\n reportTestFinished(rpc, test, logModule, base),\n ]);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n flagTestFinalized(test);\n\n debug(`${testLogPrefix} - Completed test run`);\n}\n\nexport async function runSuite(\n rpc: WorkerRPC,\n port: MessagePort,\n base: string,\n collectCoverage: boolean,\n compilation: WASMCompilation,\n suite: Suite | File,\n logModule: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n threadImports: ThreadImports,\n vitestVersion: VitestVersion,\n bail?: number,\n diffOptions?: SerializedDiffOptions,\n timedOutTest?: Test,\n): Promise<Suite> {\n const suiteStart = performance.now();\n const suiteMeta = suite.meta as AssemblyScriptSuiteTaskMeta;\n const suiteLogPrefix = getTaskLogPrefix(logModule, base, suite);\n const isTimedOutTestInSuite: boolean = timedOutTest?.suite?.id === suite.id;\n\n if (suiteMeta.resultFinal) {\n debug(`${suiteLogPrefix} - Skipping completed suite | state: \"${suite.result?.state}\"`);\n\n return suite;\n } else {\n const threadRestartTime = Date.now() - ((timedOutTest?.meta as AssemblyScriptTestTaskMeta)?.lastTimeoutTerminationTime ?? 0);\n const showRestart = !!timedOutTest && isSuiteOwnFile(suite)\n debug(`${showRestart ? `(thread resumed in ${threadRestartTime} ms) ` : ''}${suiteLogPrefix} - runSuite ${!!timedOutTest\n ? `resuming after timeout \"${timedOutTest.name}\" | isTestInSuite: ${isTimedOutTestInSuite}`\n : 'beginning'\n }`);\n }\n\n if (!suiteMeta.suitePreparedSent) {\n setSuitePrepareResult(suite);\n await reportSuitePrepare(rpc, suite, logModule, base);\n\n // ensure suite-prepare will only be sent once if a test\n // times out and the file worker thread gets re-launched\n suiteMeta.suitePreparedSent = true;\n }\n\n // restore suite coverage collected so far from the timed out test, if provided.\n // otherwise create a suite-level coverage data object to aggregate all subtask coverage\n if (isTimedOutTestInSuite) {\n suiteMeta.coverageData = (timedOutTest!.suite!.meta as AssemblyScriptSuiteTaskMeta).coverageData;\n \n const coverageKeys: number = Object.keys(suiteMeta.coverageData ?? {}).length;\n debug(`${suiteLogPrefix} - Restored suite coverage data after timeout (${coverageKeys} unique positions)`);\n } {\n // initialize aggregated coverage data for suite, which gets updated as each subtask completes\n suiteMeta.coverageData = { hitCountsByFileAndPosition: {} };\n }\n\n let tasksToRun: Task[] = getRunnableTasks(suite);\n debug(`${suiteLogPrefix} - Runnable tasks:`, tasksToRun.length);\n\n for (const task of tasksToRun) {\n if (task.type === 'suite') {\n const suiteTaskMeta = task.meta as AssemblyScriptSuiteTaskMeta;\n\n await runSuite(\n rpc, port, base, collectCoverage, compilation, task, logModule,\n poolOptions, threadImports, vitestVersion, bail, diffOptions, timedOutTest\n );\n\n // merge suite task coverage into parent suite coverage\n if (suiteMeta.coverageData && suiteTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, suiteTaskMeta.coverageData);\n }\n \n } else {\n const testLogPrefix = getTaskLogPrefix(logModule, base, task);\n const testTaskMeta = task.meta as AssemblyScriptTestTaskMeta;\n\n const testCompleted = testTaskMeta.resultFinal;\n const testTimedOutPreviously = !!timedOutTest && task.id === timedOutTest.id;\n\n if (testCompleted) {\n debug(`${testLogPrefix} - Skipping completed test | state: \"${task.result?.state}\"`);\n } else if (testTimedOutPreviously) {\n if (shouldRetryTask(task)) {\n const previousRetryCount = task.result?.retryCount ?? 0;\n const newRetryCount = previousRetryCount + 1;\n\n debug(`${testLogPrefix} - Retrying after test timeout`\n + ` | retry attempt ${newRetryCount} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n \n // report retried for the previous timeout failure, which won't\n // have been reported because the thread was killed to timeout\n await reportTestRetried(rpc, task, logModule, base);\n\n // increment the retry count (after reporting retried)\n task.result!.retryCount = newRetryCount;\n \n // retry timed out test\n // - if it passes, process as normal\n // - if it fails again, it will end up in the else block below\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n } else {\n debug(`${testLogPrefix} - Timed-out test has no retries left`\n + ` | retries attempted ${task.result?.retryCount || 0} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n\n await Promise.all([\n // as needed: invert if `fails`, bail\n postProcessTestResult(rpc, bail, task, testLogPrefix, logModule),\n \n reportTestFinished(rpc, task, logModule, base),\n ]);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n flagTestFinalized(task);\n\n debug(`${testLogPrefix} - Completed timed out test run`);\n }\n } else {\n debug(`${testLogPrefix} - Running test task | state: \"${task.result?.state}\"`);\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n }\n\n // merge test coverage into suite coverage\n if (suiteMeta.coverageData && testTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, testTaskMeta.coverageData);\n }\n }\n }\n\n // update suite result based on its tasks, report coverage data, report suite task result\n updateSuiteFinishedResult(suite, suiteLogPrefix);\n await reportSuiteFinished(rpc, suite, logModule, base, vitestVersion);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n finalizeSuiteResult(suite);\n\n const suiteTime = performance.now() - suiteStart;\n debug(`${suiteLogPrefix} - Suite Run Complete | TIMING ${suiteTime.toFixed(2)} ms`);\n\n return suite;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test-runner-BR4XyhMA.mjs","names":[],"sources":["../src/pool-thread/runner/test-runner.ts"],"sourcesContent":["/**\n * Worker thread test runner logic for AssemblyScript Pool\n */\n\nimport type { MessagePort } from 'node:worker_threads';\nimport type { File, Suite, Task, Test } from '@vitest/runner/types';\nimport type { SerializedDiffOptions } from '@vitest/utils/diff';\n\nimport type {\n AssemblyScriptConsoleLog,\n AssemblyScriptConsoleLogHandler,\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestTaskMeta,\n ResolvedAssemblyScriptPoolOptions,\n TestExecutionEnd,\n TestExecutionStart,\n ThreadImports,\n VitestVersion,\n WASMCompilation,\n WorkerRPC,\n} from '../../types/types.js';\nimport { AS_POOL_WORKER_MSG_FLAG } from '../../types/constants.js';\nimport { executeWASMTest } from '../../wasm-executor/index.js';\nimport { debug } from '../../util/debug.js';\nimport {\n reportTestPrepare,\n reportTestFinished,\n reportTestRetried,\n reportUserConsoleLogs,\n reportSuitePrepare,\n reportSuiteFinished,\n} from '../rpc-reporter.js';\nimport {\n checkFailsAndInvertResult,\n finalizeSuiteResult,\n flagTestFinalized,\n getRunnableTasks,\n getTaskLogPrefix,\n resetTestForRetry,\n setSuitePrepareResult,\n setTestResultForTestPrepare,\n shouldRetryTask,\n updateSuiteFinishedResult,\n updateTestResultAfterRun,\n isSuiteOwnFile\n} from '../../util/vitest-tasks.js';\nimport { mergeCoverageData } from '../../coverage-provider/coverage-merge.js';\n\nasync function bailIfNeeded(\n rpc: WorkerRPC,\n bailConfig: number | undefined,\n testWithResult: Test,\n logPrefix: string,\n logModule: string,\n): Promise<void> {\n if (bailConfig && testWithResult.result?.state !== 'pass') {\n const previousFailures = await rpc.getCountOfFailedTests();\n const currentFailures = 1 + previousFailures;\n\n if (currentFailures >= bailConfig) {\n debug(`${logPrefix} bailing: ${currentFailures} failures >= ${bailConfig} to bail`);\n debug(`[${logModule}] -------- BAIL! ${currentFailures} failures >= ${bailConfig} to bail --------`);\n return rpc.onCancel('test-failure');\n }\n }\n}\n\nasync function postProcessTestResult(\n rpc: WorkerRPC,\n bailConfig: number | undefined,\n testWithResult: Test,\n logPrefix: string,\n logModule: string,\n): Promise<void> {\n // invert result if test configured as 'fails'\n checkFailsAndInvertResult(testWithResult, logPrefix);\n\n // bail now if this is a failed test above bail threshold\n return bailIfNeeded(rpc, bailConfig, testWithResult, logPrefix, logModule);\n}\n\nfunction notifyTestStart(port: MessagePort, test: Test): void {\n port.postMessage({\n executionStart: Date.now(),\n test,\n type: 'execution-start',\n [AS_POOL_WORKER_MSG_FLAG]: true\n } satisfies TestExecutionStart);\n}\n\nfunction notifyTestEnd(port: MessagePort, test: Test): void {\n port.postMessage({\n executionEnd: Date.now(),\n testTaskId: test.id,\n type: 'execution-end',\n [AS_POOL_WORKER_MSG_FLAG]: true\n } satisfies TestExecutionEnd);\n}\n\nasync function runTest(\n rpc: WorkerRPC,\n port: MessagePort,\n base: string,\n collectCoverage: boolean,\n compilation: WASMCompilation,\n test: Test,\n logModule: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n threadImports: ThreadImports,\n bail?: number,\n diffOptions?: SerializedDiffOptions,\n): Promise<void> {\n const testLogPrefix = getTaskLogPrefix(logModule, base, test);\n const logMessages: AssemblyScriptConsoleLog[] = [];\n const handleLog: AssemblyScriptConsoleLogHandler = (msg: string, isError: boolean = false): void => {\n logMessages.push({ msg, time: Date.now(), isError });\n };\n\n const executionStart = Date.now();\n\n let thisRunIsARetry: boolean = false;\n let testPreparePromise: Promise<void> = Promise.resolve();\n \n if (!test.retry || !test.result) {\n debug(`${testLogPrefix} - Beginning test run`);\n\n // first/only attempt: create test result and report test-prepare\n setTestResultForTestPrepare(test, executionStart);\n testPreparePromise = reportTestPrepare(rpc, test, logModule, base);\n } else if (test.retry && test.result ) {\n debug(`${testLogPrefix} - Beginning test retry run`);\n thisRunIsARetry = true;\n\n // this is a retry, reset the result state and meta\n resetTestForRetry(test, executionStart);\n }\n \n // inform pool of test task start so it can enforce timeouts\n notifyTestStart(port, test);\n\n const [_reported, { testTimings }] = await Promise.all([\n testPreparePromise,\n executeWASMTest(\n test,\n compilation,\n base,\n poolOptions,\n collectCoverage,\n handleLog,\n logModule,\n threadImports,\n diffOptions\n )\n ]);\n\n // inform pool of test task end to stop timeout if under threshold\n notifyTestEnd(port, test);\n\n // update run->pass if appropriate, accumulate duration using executor timings\n updateTestResultAfterRun(test, testTimings);\n\n let willRetry = shouldRetryTask(test);\n\n await Promise.all([\n reportUserConsoleLogs(rpc, logMessages, logModule, base, test),\n\n willRetry ? reportTestRetried(rpc, test, logModule, base) : Promise.resolve(),\n ]);\n\n if (thisRunIsARetry) {\n debug(`${testLogPrefix} - Completed test retry run`);\n return;\n }\n\n // non-timeout retry handling\n while (willRetry) {\n // increment the retry count\n test.result!.retryCount = (test.result?.retryCount ?? 0) + 1;\n\n debug(`${testLogPrefix} - Retrying after failure`\n + ` | Retry ${test.result?.retryCount || 0} / ${test.retry} ` \n + ` | ${test.result?.errors?.length ?? 0} errors`\n );\n\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n test, logModule, poolOptions, threadImports, bail, diffOptions\n );\n\n willRetry = shouldRetryTask(test);\n\n if (!willRetry) {\n debug(`${testLogPrefix} - Max retries ${test.result?.retryCount || 0} / ${test.retry} ` \n + ` | ${test.result?.errors?.length ?? 0} errors`\n );\n }\n }\n\n await Promise.all([\n // as needed: invert if `fails`, bail\n postProcessTestResult(rpc, bail, test, testLogPrefix, logModule),\n\n reportTestFinished(rpc, test, logModule, base),\n ]);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n flagTestFinalized(test);\n\n debug(`${testLogPrefix} - Completed test run`);\n}\n\nexport async function runSuite(\n rpc: WorkerRPC,\n port: MessagePort,\n base: string,\n collectCoverage: boolean,\n compilation: WASMCompilation,\n suite: Suite | File,\n logModule: string,\n poolOptions: ResolvedAssemblyScriptPoolOptions,\n threadImports: ThreadImports,\n vitestVersion: VitestVersion,\n bail?: number,\n diffOptions?: SerializedDiffOptions,\n timedOutTest?: Test,\n): Promise<Suite> {\n const suiteStart = performance.now();\n const suiteMeta = suite.meta as AssemblyScriptSuiteTaskMeta;\n const suiteLogPrefix = getTaskLogPrefix(logModule, base, suite);\n const isTimedOutTestInSuite: boolean = timedOutTest?.suite?.id === suite.id;\n\n if (suiteMeta.resultFinal) {\n debug(`${suiteLogPrefix} - Skipping completed suite | state: \"${suite.result?.state}\"`);\n\n return suite;\n } else {\n const threadRestartTime = Date.now() - ((timedOutTest?.meta as AssemblyScriptTestTaskMeta)?.lastTimeoutTerminationTime ?? 0);\n const showRestart = !!timedOutTest && isSuiteOwnFile(suite)\n debug(`${showRestart ? `(thread resumed in ${threadRestartTime} ms) ` : ''}${suiteLogPrefix} - runSuite ${!!timedOutTest\n ? `resuming after timeout \"${timedOutTest.name}\" | isTestInSuite: ${isTimedOutTestInSuite}`\n : 'beginning'\n }`);\n }\n\n if (!suiteMeta.suitePreparedSent) {\n setSuitePrepareResult(suite);\n await reportSuitePrepare(rpc, suite, logModule, base);\n\n // ensure suite-prepare will only be sent once if a test\n // times out and the file worker thread gets re-launched\n suiteMeta.suitePreparedSent = true;\n }\n\n // restore suite coverage collected so far from the timed out test, if provided.\n // otherwise create a suite-level coverage data object to aggregate all subtask coverage\n if (isTimedOutTestInSuite) {\n suiteMeta.coverageData = (timedOutTest!.suite!.meta as AssemblyScriptSuiteTaskMeta).coverageData;\n \n const coverageKeys: number = Object.keys(suiteMeta.coverageData ?? {}).length;\n debug(`${suiteLogPrefix} - Restored suite coverage data after timeout (${coverageKeys} unique positions)`);\n } {\n // initialize aggregated coverage data for suite, which gets updated as each subtask completes\n suiteMeta.coverageData = { hitCountsByFileAndPosition: {} };\n }\n\n let tasksToRun: Task[] = getRunnableTasks(suite);\n debug(`${suiteLogPrefix} - Runnable tasks:`, tasksToRun.length);\n\n for (const task of tasksToRun) {\n if (task.type === 'suite') {\n const suiteTaskMeta = task.meta as AssemblyScriptSuiteTaskMeta;\n\n await runSuite(\n rpc, port, base, collectCoverage, compilation, task, logModule,\n poolOptions, threadImports, vitestVersion, bail, diffOptions, timedOutTest\n );\n\n // merge suite task coverage into parent suite coverage\n if (suiteMeta.coverageData && suiteTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, suiteTaskMeta.coverageData);\n }\n \n } else {\n const testLogPrefix = getTaskLogPrefix(logModule, base, task);\n const testTaskMeta = task.meta as AssemblyScriptTestTaskMeta;\n\n const testCompleted = testTaskMeta.resultFinal;\n const testTimedOutPreviously = !!timedOutTest && task.id === timedOutTest.id;\n\n if (testCompleted) {\n debug(`${testLogPrefix} - Skipping completed test | state: \"${task.result?.state}\"`);\n } else if (testTimedOutPreviously) {\n if (shouldRetryTask(task)) {\n const previousRetryCount = task.result?.retryCount ?? 0;\n const newRetryCount = previousRetryCount + 1;\n\n debug(`${testLogPrefix} - Retrying after test timeout`\n + ` | retry attempt ${newRetryCount} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n \n // report retried for the previous timeout failure, which won't\n // have been reported because the thread was killed to timeout\n await reportTestRetried(rpc, task, logModule, base);\n\n // increment the retry count (after reporting retried)\n task.result!.retryCount = newRetryCount;\n \n // retry timed out test\n // - if it passes, process as normal\n // - if it fails again, it will end up in the else block below\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n } else {\n debug(`${testLogPrefix} - Timed-out test has no retries left`\n + ` | retries attempted ${task.result?.retryCount || 0} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n\n await Promise.all([\n // as needed: invert if `fails`, bail\n postProcessTestResult(rpc, bail, task, testLogPrefix, logModule),\n \n reportTestFinished(rpc, task, logModule, base),\n ]);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n flagTestFinalized(task);\n\n debug(`${testLogPrefix} - Completed timed out test run`);\n }\n } else {\n debug(`${testLogPrefix} - Running test task | state: \"${task.result?.state}\"`);\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n }\n\n // merge test coverage into suite coverage\n if (suiteMeta.coverageData && testTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, testTaskMeta.coverageData);\n }\n }\n }\n\n // update suite result based on its tasks, report coverage data, report suite task result\n updateSuiteFinishedResult(suite, suiteLogPrefix);\n await reportSuiteFinished(rpc, suite, logModule, base, vitestVersion);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n finalizeSuiteResult(suite);\n\n const suiteTime = performance.now() - suiteStart;\n debug(`${suiteLogPrefix} - Suite Run Complete | TIMING ${suiteTime.toFixed(2)} ms`);\n\n return suite;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-pool-assemblyscript",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "AssemblyScript testing with Vitest - Simple, fast, familiar, AS-native, with full coverage output",
|
|
5
|
+
"author": "Matt Ritter <matthew.d.ritter@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"assemblyscript",
|
|
9
|
+
"vitest",
|
|
10
|
+
"unit test",
|
|
11
|
+
"unit testing",
|
|
12
|
+
"webassembly",
|
|
13
|
+
"wasm",
|
|
14
|
+
"testing",
|
|
15
|
+
"testing framework",
|
|
16
|
+
"test runner",
|
|
17
|
+
"compile-to-wasm",
|
|
18
|
+
"custom pool",
|
|
19
|
+
"vitest plugin"
|
|
20
|
+
],
|
|
5
21
|
"type": "module",
|
|
6
22
|
"main": "./dist/index.mjs",
|
|
7
23
|
"types": "./dist/index.d.mts",
|
|
@@ -67,7 +83,7 @@
|
|
|
67
83
|
"//------------ Native Addon ------------": "",
|
|
68
84
|
"setup-binaryen": "node scripts/setup-binaryen.js",
|
|
69
85
|
"build:native": "node-gyp rebuild",
|
|
70
|
-
"build:
|
|
86
|
+
"build:prebuild": "prebuildify --napi --strip --tag-libc",
|
|
71
87
|
"install": "node scripts/install.js"
|
|
72
88
|
},
|
|
73
89
|
"dependencies": {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
import https from 'https';
|
|
4
5
|
import { execSync } from 'child_process';
|
|
@@ -9,7 +10,9 @@ const BINARYEN_VERSION = fs.readFileSync(
|
|
|
9
10
|
'utf8'
|
|
10
11
|
).trim();
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
const IS_MACOS = process.platform === 'darwin';
|
|
14
|
+
|
|
15
|
+
// Detect platform for prebuilt binaries (non-macOS only)
|
|
13
16
|
function detectPlatform() {
|
|
14
17
|
const platform = process.platform;
|
|
15
18
|
const arch = process.arch;
|
|
@@ -31,6 +34,36 @@ function detectPlatform() {
|
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
// Map Node.js arch to CMake OSX architecture identifier
|
|
38
|
+
function getCmakeOsxArch() {
|
|
39
|
+
if (process.arch === 'arm64') return 'arm64';
|
|
40
|
+
if (process.arch === 'x64') return 'x86_64';
|
|
41
|
+
throw new Error(`Unsupported macOS architecture: ${process.arch}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Run a command quietly, but print its output if it fails
|
|
45
|
+
function execQuiet(command) {
|
|
46
|
+
try {
|
|
47
|
+
execSync(command, { stdio: 'pipe' });
|
|
48
|
+
} catch (err) {
|
|
49
|
+
const output = err.stderr?.toString() || err.stdout?.toString() || '';
|
|
50
|
+
if (output) {
|
|
51
|
+
console.error(output);
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Check if a command is available on PATH
|
|
58
|
+
function isCommandAvailable(command) {
|
|
59
|
+
try {
|
|
60
|
+
execSync(`which ${command}`, { stdio: 'pipe' });
|
|
61
|
+
return true;
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
34
67
|
const PLATFORM = detectPlatform();
|
|
35
68
|
const PREBUILT_URL = `https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-${PLATFORM}.tar.gz`;
|
|
36
69
|
const SOURCE_URL = `https://github.com/WebAssembly/binaryen/archive/refs/tags/${BINARYEN_VERSION}.tar.gz`;
|
|
@@ -42,88 +75,162 @@ const TEMP_DIR = path.join(THIRD_PARTY_DIR, 'binaryen-temp');
|
|
|
42
75
|
|
|
43
76
|
console.log(`Setting up Binaryen ${BINARYEN_VERSION}...`);
|
|
44
77
|
console.log(`Platform: ${PLATFORM}`);
|
|
78
|
+
|
|
79
|
+
if (IS_MACOS) {
|
|
80
|
+
console.log('macOS detected: will build static library from source');
|
|
81
|
+
}
|
|
82
|
+
|
|
45
83
|
console.log('');
|
|
46
84
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
85
|
+
if (IS_MACOS) {
|
|
86
|
+
// macOS: Build Binaryen from source to produce libbinaryen.a
|
|
87
|
+
// The official macOS prebuilt release only ships libbinaryen.dylib (shared),
|
|
88
|
+
// which cannot be statically linked into our .node addon. Building from source
|
|
89
|
+
// with BUILD_STATIC_LIB=ON produces the .a file our binding.gyp expects.
|
|
90
|
+
setupMacOS();
|
|
91
|
+
} else {
|
|
92
|
+
// Linux/Windows: Download prebuilt static library + source headers
|
|
93
|
+
setupWithPrebuilt();
|
|
94
|
+
}
|
|
53
95
|
|
|
54
|
-
|
|
55
|
-
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// macOS: build from source
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
function setupMacOS() {
|
|
101
|
+
if (!isCommandAvailable('cmake')) {
|
|
102
|
+
console.error('Error: cmake is required to build Binaryen on macOS but was not found.');
|
|
103
|
+
console.error('Install it with: brew install cmake');
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log('Step 1: Downloading source code...');
|
|
56
108
|
console.log(`URL: ${SOURCE_URL}`);
|
|
57
109
|
downloadFile(SOURCE_URL, SOURCE_ARCHIVE, () => {
|
|
58
110
|
console.log('✓ Source code downloaded');
|
|
59
111
|
console.log('');
|
|
60
|
-
|
|
61
|
-
extractAndCombine();
|
|
112
|
+
extractAndBuildFromSource();
|
|
62
113
|
});
|
|
63
|
-
}
|
|
114
|
+
}
|
|
64
115
|
|
|
65
|
-
function
|
|
66
|
-
|
|
116
|
+
function extractAndBuildFromSource() {
|
|
117
|
+
console.log('Step 2: Extracting source code...');
|
|
67
118
|
|
|
68
|
-
|
|
69
|
-
response.pipe(file);
|
|
70
|
-
file.on('finish', () => {
|
|
71
|
-
file.close(() => {
|
|
72
|
-
response.destroy();
|
|
73
|
-
callback();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
file.on('error', (err) => {
|
|
77
|
-
response.destroy();
|
|
78
|
-
if (fs.existsSync(dest)) {
|
|
79
|
-
fs.unlinkSync(dest);
|
|
80
|
-
}
|
|
81
|
-
console.error(`File write failed: ${err.message}`);
|
|
82
|
-
process.exit(1);
|
|
83
|
-
});
|
|
84
|
-
};
|
|
119
|
+
ensureCleanDirs();
|
|
85
120
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (fs.existsSync(dest)) {
|
|
93
|
-
fs.unlinkSync(dest);
|
|
94
|
-
}
|
|
95
|
-
console.error(`Download failed: ${err.message}`);
|
|
96
|
-
process.exit(1);
|
|
97
|
-
});
|
|
98
|
-
} else {
|
|
99
|
-
handleResponse(response);
|
|
121
|
+
try {
|
|
122
|
+
execSync(`tar -xzf "${SOURCE_ARCHIVE}" -C "${TEMP_DIR}"`, { stdio: 'pipe' });
|
|
123
|
+
const sourceDir = path.join(TEMP_DIR, `binaryen-${BINARYEN_VERSION}`);
|
|
124
|
+
|
|
125
|
+
if (!fs.existsSync(sourceDir)) {
|
|
126
|
+
throw new Error(`Expected source directory not found: ${sourceDir}`);
|
|
100
127
|
}
|
|
101
|
-
});
|
|
102
128
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
129
|
+
console.log('✓ Source code extracted');
|
|
130
|
+
console.log('');
|
|
131
|
+
|
|
132
|
+
// Build static library with cmake
|
|
133
|
+
console.log('Step 3: Building static library with cmake...');
|
|
134
|
+
|
|
135
|
+
const buildDir = path.join(sourceDir, 'build');
|
|
136
|
+
const osxArch = getCmakeOsxArch();
|
|
137
|
+
const cpuCount = os.cpus().length;
|
|
138
|
+
const useNinja = isCommandAvailable('ninja');
|
|
139
|
+
const generatorArgs = useNinja ? ['-G', 'Ninja'] : [];
|
|
140
|
+
|
|
141
|
+
console.log(` Architecture: ${osxArch}`);
|
|
142
|
+
console.log(` Generator: ${useNinja ? 'Ninja' : 'Unix Makefiles (default)'}`);
|
|
143
|
+
console.log(` Parallel jobs: ${cpuCount}`);
|
|
144
|
+
console.log('');
|
|
145
|
+
|
|
146
|
+
// Configure
|
|
147
|
+
console.log(' Configuring...');
|
|
148
|
+
const configureArgs = [
|
|
149
|
+
'cmake',
|
|
150
|
+
'-S', sourceDir,
|
|
151
|
+
'-B', buildDir,
|
|
152
|
+
...generatorArgs,
|
|
153
|
+
'-DCMAKE_BUILD_TYPE=Release',
|
|
154
|
+
'-DBUILD_STATIC_LIB=ON',
|
|
155
|
+
'-DBUILD_TESTS=OFF',
|
|
156
|
+
'-DBUILD_TOOLS=OFF',
|
|
157
|
+
'-DENABLE_WERROR=OFF',
|
|
158
|
+
`-DCMAKE_OSX_ARCHITECTURES=${osxArch}`,
|
|
159
|
+
];
|
|
160
|
+
execQuiet(configureArgs.join(' '));
|
|
161
|
+
console.log(' ✓ Configure complete');
|
|
162
|
+
|
|
163
|
+
// Build (only the binaryen library target, not CLI tools)
|
|
164
|
+
console.log(' Building (this may take several minutes)...');
|
|
165
|
+
execQuiet(`cmake --build "${buildDir}" --target binaryen -j${cpuCount}`);
|
|
166
|
+
console.log(' ✓ Build complete');
|
|
167
|
+
console.log('');
|
|
168
|
+
|
|
169
|
+
// Assemble third_party/binaryen/ with lib/ and src/
|
|
170
|
+
console.log('Step 4: Installing to third_party/binaryen/...');
|
|
171
|
+
|
|
172
|
+
fs.mkdirSync(BINARYEN_DIR, { recursive: true });
|
|
173
|
+
|
|
174
|
+
// Copy static library
|
|
175
|
+
const builtLib = path.join(buildDir, 'lib', 'libbinaryen.a');
|
|
176
|
+
if (!fs.existsSync(builtLib)) {
|
|
177
|
+
throw new Error(`Built static library not found at ${builtLib}`);
|
|
106
178
|
}
|
|
107
|
-
|
|
179
|
+
const destLibDir = path.join(BINARYEN_DIR, 'lib');
|
|
180
|
+
fs.mkdirSync(destLibDir, { recursive: true });
|
|
181
|
+
fs.cpSync(builtLib, path.join(destLibDir, 'libbinaryen.a'));
|
|
182
|
+
console.log(' ✓ Copied libbinaryen.a');
|
|
183
|
+
|
|
184
|
+
// Copy C++ headers from source
|
|
185
|
+
const sourceSrcDir = path.join(sourceDir, 'src');
|
|
186
|
+
const destSrcDir = path.join(BINARYEN_DIR, 'src');
|
|
187
|
+
if (fs.existsSync(sourceSrcDir)) {
|
|
188
|
+
fs.cpSync(sourceSrcDir, destSrcDir, { recursive: true });
|
|
189
|
+
console.log(' ✓ Copied C++ headers');
|
|
190
|
+
} else {
|
|
191
|
+
throw new Error('Source src/ directory not found');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Clean up
|
|
195
|
+
console.log(' Cleaning up...');
|
|
196
|
+
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
|
197
|
+
fs.unlinkSync(SOURCE_ARCHIVE);
|
|
198
|
+
|
|
199
|
+
printResult();
|
|
200
|
+
} catch (err) {
|
|
201
|
+
console.error('macOS source build failed:', err.message);
|
|
202
|
+
console.error('Ensure cmake is installed: brew install cmake');
|
|
203
|
+
console.error('For faster builds, also install ninja: brew install ninja');
|
|
108
204
|
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// Linux/Windows: download prebuilt static library + source headers
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
function setupWithPrebuilt() {
|
|
213
|
+
console.log('Step 1: Downloading prebuilt binaries...');
|
|
214
|
+
console.log(`URL: ${PREBUILT_URL}`);
|
|
215
|
+
downloadFile(PREBUILT_URL, PREBUILT_ARCHIVE, () => {
|
|
216
|
+
console.log('✓ Prebuilt binaries downloaded');
|
|
217
|
+
console.log('');
|
|
218
|
+
|
|
219
|
+
console.log('Step 2: Downloading source code for headers...');
|
|
220
|
+
console.log(`URL: ${SOURCE_URL}`);
|
|
221
|
+
downloadFile(SOURCE_URL, SOURCE_ARCHIVE, () => {
|
|
222
|
+
console.log('✓ Source code downloaded');
|
|
223
|
+
console.log('');
|
|
224
|
+
|
|
225
|
+
extractAndCombine();
|
|
226
|
+
});
|
|
109
227
|
});
|
|
110
228
|
}
|
|
111
229
|
|
|
112
230
|
function extractAndCombine() {
|
|
113
231
|
console.log('Step 3: Extracting and combining...');
|
|
114
232
|
|
|
115
|
-
|
|
116
|
-
if (!fs.existsSync(THIRD_PARTY_DIR)) {
|
|
117
|
-
fs.mkdirSync(THIRD_PARTY_DIR, { recursive: true });
|
|
118
|
-
}
|
|
119
|
-
if (!fs.existsSync(TEMP_DIR)) {
|
|
120
|
-
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Remove existing binaryen directory if it exists
|
|
124
|
-
if (fs.existsSync(BINARYEN_DIR)) {
|
|
125
|
-
fs.rmSync(BINARYEN_DIR, { recursive: true, force: true });
|
|
126
|
-
}
|
|
233
|
+
ensureCleanDirs();
|
|
127
234
|
|
|
128
235
|
try {
|
|
129
236
|
// Extract prebuilt binaries
|
|
@@ -154,26 +261,93 @@ function extractAndCombine() {
|
|
|
154
261
|
fs.unlinkSync(PREBUILT_ARCHIVE);
|
|
155
262
|
fs.unlinkSync(SOURCE_ARCHIVE);
|
|
156
263
|
|
|
157
|
-
|
|
158
|
-
console.log(`✓ Binaryen ${BINARYEN_VERSION} installed to third_party/binaryen`);
|
|
159
|
-
console.log('');
|
|
160
|
-
console.log('Contents:');
|
|
161
|
-
const contents = fs.readdirSync(BINARYEN_DIR);
|
|
162
|
-
console.log(contents.map(f => ` ${f}`).join('\n'));
|
|
163
|
-
|
|
164
|
-
const libDir = path.join(BINARYEN_DIR, 'lib');
|
|
165
|
-
if (fs.existsSync(libDir)) {
|
|
166
|
-
console.log('');
|
|
167
|
-
console.log('Library files:');
|
|
168
|
-
const libFiles = fs.readdirSync(libDir);
|
|
169
|
-
console.log(libFiles.map(f => ` ${f}`).join('\n'));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
console.log('');
|
|
173
|
-
console.log('Setup complete!');
|
|
264
|
+
printResult();
|
|
174
265
|
} catch (err) {
|
|
175
266
|
console.error('Extraction/combination failed:', err.message);
|
|
176
267
|
console.error('Make sure tar is available on your system.');
|
|
177
268
|
process.exit(1);
|
|
178
269
|
}
|
|
179
270
|
}
|
|
271
|
+
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Shared helpers
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
|
|
276
|
+
function ensureCleanDirs() {
|
|
277
|
+
if (!fs.existsSync(THIRD_PARTY_DIR)) {
|
|
278
|
+
fs.mkdirSync(THIRD_PARTY_DIR, { recursive: true });
|
|
279
|
+
}
|
|
280
|
+
if (!fs.existsSync(TEMP_DIR)) {
|
|
281
|
+
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
282
|
+
}
|
|
283
|
+
if (fs.existsSync(BINARYEN_DIR)) {
|
|
284
|
+
fs.rmSync(BINARYEN_DIR, { recursive: true, force: true });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function printResult() {
|
|
289
|
+
console.log('');
|
|
290
|
+
console.log(`✓ Binaryen ${BINARYEN_VERSION} installed to third_party/binaryen`);
|
|
291
|
+
console.log('');
|
|
292
|
+
console.log('Contents:');
|
|
293
|
+
const contents = fs.readdirSync(BINARYEN_DIR);
|
|
294
|
+
console.log(contents.map(f => ` ${f}`).join('\n'));
|
|
295
|
+
|
|
296
|
+
const libDir = path.join(BINARYEN_DIR, 'lib');
|
|
297
|
+
if (fs.existsSync(libDir)) {
|
|
298
|
+
console.log('');
|
|
299
|
+
console.log('Library files:');
|
|
300
|
+
const libFiles = fs.readdirSync(libDir);
|
|
301
|
+
console.log(libFiles.map(f => ` ${f}`).join('\n'));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
console.log('');
|
|
305
|
+
console.log('Setup complete!');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function downloadFile(url, dest, callback) {
|
|
309
|
+
const file = fs.createWriteStream(dest);
|
|
310
|
+
|
|
311
|
+
const handleResponse = (response) => {
|
|
312
|
+
response.pipe(file);
|
|
313
|
+
file.on('finish', () => {
|
|
314
|
+
file.close(() => {
|
|
315
|
+
response.destroy();
|
|
316
|
+
callback();
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
file.on('error', (err) => {
|
|
320
|
+
response.destroy();
|
|
321
|
+
if (fs.existsSync(dest)) {
|
|
322
|
+
fs.unlinkSync(dest);
|
|
323
|
+
}
|
|
324
|
+
console.error(`File write failed: ${err.message}`);
|
|
325
|
+
process.exit(1);
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const request = https.get(url, (response) => {
|
|
330
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
331
|
+
// Follow redirect
|
|
332
|
+
response.destroy();
|
|
333
|
+
const redirectRequest = https.get(response.headers.location, handleResponse);
|
|
334
|
+
redirectRequest.on('error', (err) => {
|
|
335
|
+
if (fs.existsSync(dest)) {
|
|
336
|
+
fs.unlinkSync(dest);
|
|
337
|
+
}
|
|
338
|
+
console.error(`Download failed: ${err.message}`);
|
|
339
|
+
process.exit(1);
|
|
340
|
+
});
|
|
341
|
+
} else {
|
|
342
|
+
handleResponse(response);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
request.on('error', (err) => {
|
|
347
|
+
if (fs.existsSync(dest)) {
|
|
348
|
+
fs.unlinkSync(dest);
|
|
349
|
+
}
|
|
350
|
+
console.error(`Download failed: ${err.message}`);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
@@ -258,7 +258,7 @@ SourceDebugLocation getRepresentativeLocationInBlockBody(
|
|
|
258
258
|
Block* blockBody,
|
|
259
259
|
const std::unordered_map<wasm::Expression*, std::optional<wasm::Function::DebugLocation>> debugLocations
|
|
260
260
|
) {
|
|
261
|
-
SourceDebugLocation repLoc = { exists
|
|
261
|
+
SourceDebugLocation repLoc = { .exists = false, .fileIndex = 0, .lineNumber = 0, .columnNumber = 0 };
|
|
262
262
|
|
|
263
263
|
if (DEBUG) {
|
|
264
264
|
std::cout << LOG_PREFIX << " - Checking func Block body: " << blockBody->list.size() << " body expressions" << std::endl;
|
|
@@ -296,7 +296,7 @@ SourceDebugLocation getRepresentativeLocationInBlockBody(
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
SourceDebugLocation getRepresentativeLocation(Function* func) {
|
|
299
|
-
SourceDebugLocation repLoc = { exists
|
|
299
|
+
SourceDebugLocation repLoc = { .exists = false, .fileIndex = 0, .lineNumber = 0, .columnNumber = 0 };
|
|
300
300
|
|
|
301
301
|
// Get body expression debug location
|
|
302
302
|
Expression* body = func->body;
|