vitest-pool-assemblyscript 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/dist/{ast-visitor-lTahoS9R.mjs → ast-visitor-DJLJd5dt.mjs} +2 -2
- package/dist/{ast-visitor-lTahoS9R.mjs.map → ast-visitor-DJLJd5dt.mjs.map} +1 -1
- package/dist/{compile-runner-C2eh_xLp.mjs → compile-runner-BJ_ZF3Ma.mjs} +11 -8
- package/dist/compile-runner-BJ_ZF3Ma.mjs.map +1 -0
- package/dist/compiler/transforms/strip-inline.mjs +2 -2
- package/dist/{compiler-BaNECXMW.mjs → compiler-CscxCJw3.mjs} +78 -38
- package/dist/compiler-CscxCJw3.mjs.map +1 -0
- package/dist/config/index-v3.d.mts +2 -2
- package/dist/config/index.d.mts +3 -3
- package/dist/config/index.mjs +5 -5
- package/dist/{constants-DX9yo-el.mjs → constants-DuBLuMjt.mjs} +9 -9
- package/dist/constants-DuBLuMjt.mjs.map +1 -0
- package/dist/{coverage-merge-0WqdC-dq.mjs → coverage-merge-DCEwyjMy.mjs} +1 -1
- package/dist/{coverage-merge-0WqdC-dq.mjs.map → coverage-merge-DCEwyjMy.mjs.map} +1 -1
- package/dist/coverage-provider/index.mjs +35 -28
- package/dist/coverage-provider/index.mjs.map +1 -1
- package/dist/{custom-provider-options-CVLz0nAp.d.mts → custom-provider-options-i_O0OSTV.d.mts} +2 -2
- package/dist/{custom-provider-options-CVLz0nAp.d.mts.map → custom-provider-options-i_O0OSTV.d.mts.map} +1 -1
- package/dist/{debug-Cf2jt1kg.mjs → debug-Cm1VFmaz.mjs} +16 -13
- package/dist/{debug-Cf2jt1kg.mjs.map → debug-Cm1VFmaz.mjs.map} +1 -1
- package/dist/index-internal.d.mts +1 -14
- package/dist/index-internal.d.mts.map +1 -1
- package/dist/index-internal.mjs +3 -3
- package/dist/index-v3.mjs +4 -4
- package/dist/index-v3.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +5 -5
- package/dist/{load-user-imports-eGZuxeNp.mjs → load-user-imports-CYTTU22Q.mjs} +30 -149
- package/dist/load-user-imports-CYTTU22Q.mjs.map +1 -0
- package/dist/node-check-CooGQMLH.mjs +16 -0
- package/dist/node-check-CooGQMLH.mjs.map +1 -0
- package/dist/{pool-runner-init-Cdpz_B-F.mjs → pool-runner-init-D1QamWkS.mjs} +5 -5
- package/dist/{pool-runner-init-Cdpz_B-F.mjs.map → pool-runner-init-D1QamWkS.mjs.map} +1 -1
- package/dist/{pool-runner-init-8vx-5Pb4.d.mts → pool-runner-init-D56aVMMD.d.mts} +2 -2
- package/dist/pool-runner-init-D56aVMMD.d.mts.map +1 -0
- package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
- package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -1
- package/dist/pool-thread/compile-worker-thread.mjs +11 -9
- package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
- package/dist/pool-thread/test-worker-thread.d.mts +1 -1
- package/dist/pool-thread/test-worker-thread.d.mts.map +1 -1
- package/dist/pool-thread/test-worker-thread.mjs +10 -8
- package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
- package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
- package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -1
- package/dist/pool-thread/v3-tinypool-thread.mjs +14 -12
- package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
- package/dist/{resolve-config-BKjJQyy5.mjs → resolve-config-BFNr7LW7.mjs} +9 -3
- package/dist/resolve-config-BFNr7LW7.mjs.map +1 -0
- package/dist/{test-runner-vGpTcXsw.mjs → test-runner-CfhzcYNS.mjs} +5 -5
- package/dist/{test-runner-vGpTcXsw.mjs.map → test-runner-CfhzcYNS.mjs.map} +1 -1
- package/dist/{types-DasF0_PX.d.mts → types-DmyeERkL.d.mts} +15 -5
- package/dist/types-DmyeERkL.d.mts.map +1 -0
- package/dist/{vitest-tasks-Cbri6MWZ.mjs → vitest-tasks-ByPK8DvF.mjs} +3 -3
- package/dist/{vitest-tasks-Cbri6MWZ.mjs.map → vitest-tasks-ByPK8DvF.mjs.map} +1 -1
- package/dist/wasm-names-CydfYzQK.mjs +124 -0
- package/dist/wasm-names-CydfYzQK.mjs.map +1 -0
- package/package.json +11 -5
- package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
- package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/src/native-instrumentation/addon.cpp +28 -2
- package/dist/compile-runner-C2eh_xLp.mjs.map +0 -1
- package/dist/compiler-BaNECXMW.mjs.map +0 -1
- package/dist/constants-DX9yo-el.mjs.map +0 -1
- package/dist/load-user-imports-eGZuxeNp.mjs.map +0 -1
- package/dist/pool-runner-init-8vx-5Pb4.d.mts.map +0 -1
- package/dist/resolve-config-BKjJQyy5.mjs.map +0 -1
- package/dist/types-DasF0_PX.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-runner-vGpTcXsw.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-CfhzcYNS.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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"}
|
|
@@ -12,6 +12,10 @@ import { File, Test } from "@vitest/runner/types";
|
|
|
12
12
|
interface AssemblyScriptPoolOptions {
|
|
13
13
|
/** Enable verbose debug logging */
|
|
14
14
|
debug?: boolean;
|
|
15
|
+
debugNative?: boolean;
|
|
16
|
+
debugCoverageExtract?: boolean;
|
|
17
|
+
/** enable to collect coverage instrumentation on the pool's assembly/* files */
|
|
18
|
+
_instrumentPoolInternals?: boolean;
|
|
15
19
|
/**
|
|
16
20
|
* Strip `@inline` decorators during compilation to improve error message and coverage accuracy
|
|
17
21
|
*
|
|
@@ -43,6 +47,7 @@ interface AssemblyScriptPoolOptions {
|
|
|
43
47
|
interface HybridProviderOptions {
|
|
44
48
|
provider: "custom";
|
|
45
49
|
customProviderModule: string;
|
|
50
|
+
debugIstanbul?: boolean;
|
|
46
51
|
/**
|
|
47
52
|
* Glob patterns for AssemblyScript source files to include in coverage.
|
|
48
53
|
* Used to build the complete AS coverage map.
|
|
@@ -82,11 +87,15 @@ interface AssemblyScriptCompilerResult {
|
|
|
82
87
|
compileTiming: number;
|
|
83
88
|
}
|
|
84
89
|
interface InstrumentationOptions {
|
|
90
|
+
/** Project root for resolving source map paths to absolute paths */
|
|
91
|
+
projectRoot: string;
|
|
85
92
|
/** List of relative file paths to exclude from instrumentation */
|
|
86
93
|
relativeExcludedFiles: string[];
|
|
87
94
|
excludedLibraryFilePrefix: string;
|
|
88
95
|
coverageMemoryPagesMin: number;
|
|
89
96
|
coverageMemoryPagesMax: number;
|
|
97
|
+
excludedLibraryFileOverridePrefix?: string;
|
|
98
|
+
debug?: boolean;
|
|
90
99
|
}
|
|
91
100
|
/**
|
|
92
101
|
* Source location in original AssemblyScript code (a point, not a range)
|
|
@@ -95,7 +104,7 @@ interface InstrumentationOptions {
|
|
|
95
104
|
* Conversion to 0-based columns happens at Istanbul output boundary.
|
|
96
105
|
*/
|
|
97
106
|
interface SourceLocation {
|
|
98
|
-
/**
|
|
107
|
+
/** Absolute file path (normalized from source map during debug info extraction) */
|
|
99
108
|
filePath: string;
|
|
100
109
|
line: number;
|
|
101
110
|
column: number;
|
|
@@ -179,10 +188,11 @@ interface BinaryDebugInfo {
|
|
|
179
188
|
/** All source files represented in extracted debug info (directly or inlined) */
|
|
180
189
|
debugSourceFiles: string[];
|
|
181
190
|
/**
|
|
182
|
-
* Functions grouped by file path, then keyed by position ("line:column")
|
|
183
|
-
* Position key enables stable identity across compilations
|
|
191
|
+
* Functions grouped by file path, then keyed by position ("line:column").
|
|
192
|
+
* Position key enables stable identity across compilations.
|
|
193
|
+
* Array value accommodates generic monomorphizations that share a source position.
|
|
184
194
|
*/
|
|
185
|
-
functionsByFileAndPosition: Record<string, Record<string, FunctionDebugInfo>>;
|
|
195
|
+
functionsByFileAndPosition: Record<string, Record<string, FunctionDebugInfo[]>>;
|
|
186
196
|
instrumentedFunctionCount: number;
|
|
187
197
|
}
|
|
188
198
|
interface WASMCompilation {
|
|
@@ -224,4 +234,4 @@ interface ProcessPoolRunFileTask {
|
|
|
224
234
|
}
|
|
225
235
|
//#endregion
|
|
226
236
|
export { AssemblyScriptCompilerOptions, AssemblyScriptCompilerResult, AssemblyScriptPoolOptions, HybridProviderOptions, ProcessPoolRunFileTask, RunCompileAndDiscoverTask, RunTestsTask, ThreadSpec, WasmImportsFactory, WasmImportsFactoryInfo };
|
|
227
|
-
//# sourceMappingURL=types-
|
|
237
|
+
//# sourceMappingURL=types-DmyeERkL.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-DmyeERkL.d.mts","names":[],"sources":["../src/types/types.ts"],"mappings":";;;;;;;;;;;UA0DiB,yBAAA;EAmEjB;EAjEE,KAAA;EACA,WAAA;EACA,oBAAA;;EAGA,wBAAA;;;;;;;;;;EAWA,WAAA;EAyDU;;;;;;;EAhDV,YAAA;EAEA,0BAAA;EACA,sBAAA;EAEA,sBAAA;EACA,kBAAA;EAEA,kBAAA;EAEA,kBAAA;AAAA;;;;UAMe,qBAAA;EACf,QAAA;EACA,oBAAA;EAEA,aAAA;EA2Ge;;;;;;;;EAjGf,qBAAA;;;;AAyGF;;EAlGE,qBAAA;AAAA;AAAA,UAGe,sBAAA;EACf,MAAA,EAAQ,WAAA,CAAY,MAAA;EACpB,MAAA,EAAQ,WAAA,CAAY,MAAA;EACpB,KAAA;IACE,UAAA,GAAa,SAAA;EAAA;AAAA;AAAA,KAIL,kBAAA,IAAsB,UAAA,EAAY,sBAAA,KAA2B,WAAA,CAAY,OAAA;AAAA,UAuEpE,6BAAA;EACf,gBAAA;EACA,WAAA;EACA,sBAAA,GAAyB,sBAAA;EACzB,WAAA;EACA,UAAA;AAAA;AAAA,UAGe,4BAAA;EACf,MAAA,EAAQ,UAAA;EACR,SAAA;EACA,SAAA,GAAY,eAAA;EACZ,cAAA;EACA,aAAA;AAAA;AAAA,UAGe,sBAAA;;EAEf,WAAA;;EAEA,qBAAA;EACA,yBAAA;EACA,sBAAA;EACA,sBAAA;EACA,iCAAA;EACA,KAAA;AAAA;;;AAiZF;;;;UAxXiB,cAAA;;EAEf,QAAA;EACA,IAAA;EACA,MAAA;AAAA;;;;UAoEe,mBAAA;;EAEf,gBAAA;;EAEA,qBAAA;AAAA;;;;;AAkVF;;UAzUiB,mBAAA;;EAEf,IAAA;;EAEA,QAAA,GAAW,cAAA;;EAEX,QAAA;EA0UsB;EAxUtB,WAAA;;;;;EAKA,mBAAA;AAAA;;;;;;;UASe,mBAAA;;EAEf,KAAA;;EAEA,iBAAA;;EAEA,QAAA,EAAU,mBAAA;;;;;EAKV,mBAAA;AAAA;;;;UAMe,iBAAA;;EAEf,SAAA;;EAEA,IAAA;;;;;EAKA,sBAAA,EAAwB,cAAA;;EAExB,mBAAA;;EAEA,WAAA,EAAa,mBAAA;;EAEb,WAAA,EAAa,mBAAA;AAAA;;;;;;;UASE,eAAA;;EAEf,gBAAA;;;;;;EAMA,0BAAA,EAA4B,MAAA,SAAe,MAAA,SAAe,iBAAA;EAE1D,yBAAA;AAAA;AAAA,UA0Ne,eAAA;EACf,QAAA;EACA,MAAA,EAAQ,UAAA;EACR,SAAA;EACA,SAAA,GAAY,eAAA;AAAA;AAAA,UASG,UAAA;EACf,IAAA,EAAM,IAAA;EACN,WAAA,GAAc,eAAA;AAAA;AAAA,UAGC,yBAAA;EACf,aAAA;EACA,QAAA;EACA,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,IAAA;EACN,MAAA,EAAQ,gBAAA;EACR,kBAAA;AAAA;AAAA,UAGe,YAAA;EACf,aAAA;EACA,QAAA;EACA,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,IAAA;EACN,WAAA,EAAa,eAAA;EACb,MAAA,EAAQ,gBAAA;EACR,kBAAA;EACA,YAAA,GAAe,IAAA;AAAA;AAAA,UAGA,sBAAA;EACf,aAAA;EACA,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,IAAA;EACN,MAAA,EAAQ,gBAAA;EACR,kBAAA;EACA,YAAA,GAAe,IAAA;EACf,mBAAA,GAAsB,eAAA;AAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { POOL_ERROR_NAMES, TEST_ERROR_NAMES } from "./constants-
|
|
2
|
-
import { createPoolErrorFromAnyError, createTestExpectedToFailError, createTestTimeoutError, debug } from "./debug-
|
|
1
|
+
import { POOL_ERROR_NAMES, TEST_ERROR_NAMES } from "./constants-DuBLuMjt.mjs";
|
|
2
|
+
import { createPoolErrorFromAnyError, createTestExpectedToFailError, createTestTimeoutError, debug } from "./debug-Cm1VFmaz.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/wasm-executor/source-maps.ts
|
|
5
5
|
function parseSourceMap(sourceMap) {
|
|
@@ -316,4 +316,4 @@ function resetTestForRetry(test, startTime) {
|
|
|
316
316
|
|
|
317
317
|
//#endregion
|
|
318
318
|
export { checkFailsAndInvertResult, createAfterSuiteRunMeta, createSuiteTask, createTestTask, createWebAssemblyCallSite, extractCallStack, failTest, failTestWithTimeoutError, finalizeSuiteResult, flagTestFinalized, flagTestTerminated, getRunnableTasks, getTaskLogLabel, getTaskLogPrefix, isSuiteOwnFile, parseSourceMap, resetTestForRetry, setSuitePrepareResult, setTestResultForTestPrepare, shouldRetryTask, updateSuiteFinishedResult, updateTestResultAfterRun };
|
|
319
|
-
//# sourceMappingURL=vitest-tasks-
|
|
319
|
+
//# sourceMappingURL=vitest-tasks-ByPK8DvF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitest-tasks-Cbri6MWZ.mjs","names":[],"sources":["../src/wasm-executor/source-maps.ts","../src/util/vitest-tasks.ts"],"sourcesContent":["/**\n * Source Map Utilities\n *\n * Maps WASM errors to AssemblyScript source locations using V8 stack traces + source maps.\n *\n * Approach: V8's Error.prepareStackTrace provides WAT (WebAssembly Text) line:column positions,\n * which can be mapped to AS source using the source maps generated by AS compiler.\n */\n\nimport { type RawSourceMap, SourceMapConsumer } from 'source-map';\n\nimport { debug } from '../util/debug.js';\nimport type { WebAssemblyCallSite } from '../types/types.js';\nimport { createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { POOL_ERROR_NAMES } from '../types/constants.js';\n\nexport function parseSourceMap(sourceMap: string): RawSourceMap {\n // Remove sourceRoot if present to prevent source-map library from prepending it to paths\n // AS compiler sets sourceRoot: \"./output\" which would make paths like \"output/tests/...\"\n // instead of \"tests/...\" - these paths don't exist and won't be found by Vitest\n try {\n const sourceMapObj: RawSourceMap = JSON.parse(sourceMap);\n delete sourceMapObj.sourceRoot;\n return sourceMapObj;\n }\n catch (err) {\n throw createPoolErrorFromAnyError(\n `parseSourceMap error`,\n POOL_ERROR_NAMES.PoolError,\n err\n )\n }\n}\n\n/**\n * Extract structured call stack from V8 using Error.prepareStackTrace\n *\n * V8 provides a special API to access structured stack traces with line:column info.\n * This gives us WAT text positions which can be mapped to AS source via source maps.\n *\n * @param capturedError - Error object to extract stack from\n * @returns Array of V8 CallSite objects\n */\nexport function extractCallStack(capturedError: Error): NodeJS.CallSite[] {\n let stackTrace: NodeJS.CallSite[] = [];\n\n const originalPrepareStackTrace = Error.prepareStackTrace;\n Error.prepareStackTrace = (_err: Error, structuredStackTrace: NodeJS.CallSite[]) => {\n stackTrace = structuredStackTrace;\n return ''; // Return empty string to avoid modifying error.stack\n };\n\n // Access error.stack to trigger prepareStackTrace (result unused, just triggers callback)\n capturedError.stack;\n\n // Restore original\n Error.prepareStackTrace = originalPrepareStackTrace;\n\n return stackTrace;\n}\n\n/**\n * Create WebAssembly call site with source mapping\n *\n * Takes a V8 CallSite and maps it to AS source location if possible.\n *\n * @param callSite - V8 CallSite object from Error.prepareStackTrace\n * @param sourceMapJson - Source map consumer initialized with WASM source map\n * @returns Mapped call site or null if not a WASM call site\n */\nexport function createWebAssemblyCallSite(\n callSite: NodeJS.CallSite,\n sourceMapConsumer: SourceMapConsumer,\n loggingPrefix: string,\n): WebAssemblyCallSite | null {\n const fileName = callSite.getFileName();\n\n // Only process WASM call sites\n if (!fileName || !fileName.startsWith('wasm://')) {\n return null;\n }\n\n const watLine = callSite.getLineNumber();\n const watColumn = callSite.getColumnNumber();\n const functionName = callSite.getFunctionName() || 'wasm-function[unknown]';\n const debugString = `function: \"${functionName}\" | wasm: ${fileName}:${watLine}:${watColumn}`;\n\n // Try to map to source\n if (watLine && watColumn) {\n const original = sourceMapConsumer.originalPositionFor({\n line: watLine,\n column: watColumn\n });\n \n if (!original.source || original.line === null || original.column === null) {\n debug(`${loggingPrefix} - Failed to source-map stack location: ${debugString}`);\n return null;\n }\n\n debug(`${loggingPrefix} - Source-mapped stack location: ${debugString} → ${original.source}:${original.line}:${original.column}`);\n \n const callSite: WebAssemblyCallSite = {\n functionName,\n location: {\n filePath: original.source,\n line: original.line,\n column: original.column\n }\n };\n\n return callSite;\n }\n\n debug(`${loggingPrefix} - Failed to source-map stack-location: ${debugString}`);\n\n // Fallback to WAT position\n return {\n functionName,\n location: {\n filePath: fileName,\n line: watLine || -1,\n column: watColumn || -1\n }\n };\n}\n","import type { File, RunMode, Suite, Task, Test } from '@vitest/runner/types';\n\nimport type {\n AssemblyScriptCoveragePayload,\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestError,\n AssemblyScriptTestOptions,\n AssemblyScriptTestTaskMeta,\n FailedAssertion,\n VitestVersion,\n WASMExecutorPerfTimings\n} from '../types/types.js';\nimport { TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } from './debug.js';\nimport { createTestExpectedToFailError, createTestTimeoutError } from './pool-errors.js';\nimport { extractCallStack } from '../wasm-executor/source-maps.js';\n\n// ============================================================================\n// Util\n// ============================================================================\n\nfunction positiveSum<T>(items: T[], getSummableValue: (_next: T) => number | undefined): number {\n return items.reduce((total, next) => {\n return total + Math.max(getSummableValue(next) || 0, 0)\n }, 0);\n}\n\nfunction hasNonFileParentSuite(suite: Suite): boolean {\n return !!suite.suite?.id && suite.suite.id !== suite.file.id;\n}\n\nfunction getSuiteHierarchyName(suite: Suite): string {\n let name = suite.name;\n let currentSuite = suite;\n \n while (hasNonFileParentSuite(currentSuite)) {\n name = `${currentSuite.suite!.name} > ${name}`;\n currentSuite = currentSuite.suite!;\n }\n \n return name;\n}\n\nexport function isSuiteOwnFile(suite: Suite): boolean {\n return suite.file.id === suite.id;\n}\n\nexport function getTaskLogLabel(base: string, task: Task): string {\n if (task.type === 'suite') {\n return isSuiteOwnFile(task) ?\n `${base}`\n : `${base} - \"${getSuiteHierarchyName(task)}\"`;\n } else {\n return `${base} - \"${getSuiteHierarchyName(task.suite!)} > ${task.name}\"`;\n }\n}\n\nexport function getTaskLogPrefix(logModule: string, base: string, task: Task): string {\n return `[${logModule}] ${getTaskLogLabel(base, task)}`;\n}\n\nexport function createAfterSuiteRunMeta(\n coverage: AssemblyScriptCoveragePayload,\n testFiles: string[],\n projectName: string = '',\n vitestVersion: VitestVersion = 'v4',\n): any {\n const base = { coverage, testFiles, projectName };\n\n if (vitestVersion) {\n return { ...base, transformMode: 'ssr' as const };\n } else {\n return { ...base, environment: 'node' as const };\n }\n}\n\n// ============================================================================\n// Task Creation\n// ============================================================================\n\nexport function getInitialTaskMode(options: AssemblyScriptTestOptions): RunMode {\n if (options.skip) {\n return 'skip';\n } else if (options.only) {\n return 'only';\n } else {\n return 'run';\n }\n}\n\nexport function getInitialTestTaskMeta(\n fnIndex: number,\n parentAfterAddingTask: Suite,\n): AssemblyScriptTestTaskMeta {\n return {\n fnIndex,\n idxInParentTasks: parentAfterAddingTask.tasks.length - 1,\n assertionsPassedCount: 0,\n assertionsFailed: [],\n resultFinal: false,\n };\n}\n\nexport function getInitialSuiteTaskMeta(\n parentAfterAddingTask: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n): AssemblyScriptSuiteTaskMeta {\n return {\n idxInParentTasks: parentAfterAddingTask.tasks.length - 1,\n defaultTestOptions: mergedOptions,\n suitePreparedSent: false,\n resultFinal: false,\n };\n}\n\n\nfunction createTaskName(names: readonly (string | undefined)[], separator: string = ' > '): string {\n return names.filter(name => name !== undefined).join(separator);\n}\n\nexport function createTestTask(\n name: string,\n fnIndex: number,\n file: File,\n parent: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n vitestVersion: VitestVersion = 'v4',\n): Test {\n const test: Test = {\n type: 'test',\n name,\n fullName: createTaskName([\n parent?.fullName ?? file?.fullName,\n name,\n ]),\n fullTestName: createTaskName([parent?.fullTestName, name]),\n id: '',\n file,\n suite: parent,\n context: {} as any,\n annotations: [],\n artifacts: [],\n meta: {},\n mode: getInitialTaskMode(mergedOptions),\n timeout: mergedOptions.timeout,\n retry: mergedOptions.retry,\n fails: mergedOptions.fails,\n };\n\n if (vitestVersion === 'v3') {\n // @ts-ignore\n delete test.fullName;\n // @ts-ignore\n delete test.fullTestName;\n // @ts-ignore\n delete test.artifacts;\n }\n\n parent.tasks.push(test);\n\n // use custom TaskMeta to capture fnIndex, parent task index, etc\n test.meta = getInitialTestTaskMeta(fnIndex, parent);\n\n return test;\n}\n\nexport function createSuiteTask(\n name: string,\n file: File,\n parent: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n vitestVersion: VitestVersion = 'v4',\n): Suite {\n // const suiteIsFile = parent.file.id === parent.id;\n // const prefix = suiteIsFile ? parent.name : `${file.filepath}_${parent.name}`;\n const suite: Suite = {\n type: 'suite',\n name,\n fullName: createTaskName([\n parent?.fullName ?? file?.fullName,\n name,\n ]),\n fullTestName: createTaskName([parent?.fullTestName, name]),\n id: '',\n file,\n suite: parent,\n meta: {},\n tasks: [],\n mode: getInitialTaskMode(mergedOptions),\n };\n\n if (vitestVersion === 'v3') {\n // @ts-ignore\n delete suite.fullName;\n // @ts-ignore\n delete suite.fullTestName;\n }\n\n parent.tasks.push(suite);\n\n // use custom TaskMeta to capture parent task index and default options\n suite.meta = getInitialSuiteTaskMeta(parent, mergedOptions);\n\n return suite;\n}\n\n\n// ============================================================================\n// Dispatch Helpers\n// ============================================================================\n\nexport function getRunnableTasks(suite: Suite): Task[] {\n return suite.tasks.filter(t => t.mode === 'queued' || t.mode === 'run');\n}\n\n\n// ============================================================================\n// Result Handling Helpers\n// ============================================================================\n\nexport function shouldRetryTask(task: Task): boolean {\n return task.result?.state === 'fail'\n && task.retry !== undefined\n && task.retry > 0\n && (\n task.result.retryCount === undefined\n || task.result.retryCount === 0\n || (task.result.retryCount < task.retry)\n );\n}\n\n/**\n * Invert result if test configured as 'fails'.\n */\nexport function checkFailsAndInvertResult(test: Test, logPrefix: string): void {\n if (test.fails) {\n if (test.result?.state === 'pass') {\n test.result.state = 'fail';\n\n debug(`${logPrefix} - Has 'fails' option set - inverted \"pass\" to \"fail\"`);\n\n const err = createTestExpectedToFailError(test);\n if (test.result.errors) {\n test.result.errors.push(err);\n } else {\n test.result.errors = [err];\n }\n } else if (test.result?.state === 'fail') {\n test.result.state = 'pass';\n test.result.errors = [];\n\n debug(`${logPrefix} - Has 'fails' option set - inverted \"fail\" to \"pass\"`);\n }\n }\n}\n\nexport function setTestResultForTestPrepare(test: Test, startTime: number): void {\n test.result = {\n state: 'run',\n startTime,\n retryCount: 0\n };\n};\n\nexport function updateTestResultAfterRun(test: Test, testTimings?: WASMExecutorPerfTimings): void {\n // while failed tests are actively set to failed, a passed test\n // will still be in the prepared result state (run), so set it to pass\n if (test.result?.state === 'run') {\n test.result.state = 'pass';\n }\n \n if (test.result && testTimings) {\n // accumulate duration for any retries that may be done\n test.result.duration = (test.result.duration ?? 0) + (testTimings.execEnd - testTimings.execStart);\n }\n}\n\nexport function flagTestTerminated(test: Test): void {\n (test.meta as AssemblyScriptTestTaskMeta).lastTimeoutTerminationTime = Date.now();\n}\n\nexport function flagTestFinalized(test: Test): void {\n (test.meta as AssemblyScriptTestTaskMeta).resultFinal = true;\n}\n\nexport function failTest(\n test: Test,\n errorMessage: string,\n capturedError: Error,\n logPrefix: string,\n): void {\n if (test.result) {\n test.result.state = 'fail';\n } else {\n test.result = { state: 'fail' };\n }\n\n const testError: AssemblyScriptTestError = {\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n message: errorMessage\n };\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n \n // determine if this was an assertion failure\n if (meta.assertionsFailed?.length > 0) {\n testError.name = TEST_ERROR_NAMES.AssertionError;\n\n const assertion: FailedAssertion = meta.assertionsFailed[meta.assertionsFailed.length - 1]!;\n\n // set actual and expected values as strings, if provided\n if (assertion.valuesProvided) {\n meta.lastErrorValuesProvided = true;\n testError.expected = assertion.expected !== undefined ? String(assertion.expected) : undefined;\n testError.actual = assertion.actual !== undefined ? String(assertion.actual) : undefined;\n }\n }\n \n // Set error to report to vitest on the test meta.\n // Stack gets updated when executor enhances/source-maps the error, post-abort\n meta.lastError = testError;\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 meta.lastErrorRawCallStack = extractCallStack(capturedError);\n\n debug(`${logPrefix} - Captured raw V8 call stack with ${meta.lastErrorRawCallStack.length} frames`);\n}\n\nexport function failTestWithTimeoutError (test: Test, startTime: number, duration: number): void {\n const timeoutErr = createTestTimeoutError(test);\n\n if (test.result) {\n test.result.state = 'fail';\n test.result.startTime = startTime;\n \n // accumulate duration for any retries that may be done\n test.result.duration = (test.result.duration ?? 0) + duration;\n\n if (test.result.errors) {\n test.result.errors.push(timeoutErr)\n } else {\n test.result.errors = [timeoutErr];\n }\n } else {\n test.result = {\n state: 'fail',\n startTime,\n duration,\n errors: [timeoutErr],\n retryCount: 0,\n };\n }\n}\n\nexport function setSuitePrepareResult(suite: Suite): void {\n if (suite.mode === 'skip') {\n suite.result = {\n state: 'skip',\n duration: 0,\n };\n } else {\n suite.result = {\n state: 'run',\n startTime: Date.now(),\n };\n }\n}\n\nexport function updateSuiteFinishedResult(suite: Suite, logPrefix: string): void {\n if (suite.mode === 'skip') {\n suite.result = {\n state: 'skip',\n duration: 0,\n };\n } else {\n // update suite final result based on sub-task results\n const hasFailures = suite.tasks.some(({ result }) => result?.state === 'fail' );\n \n if (suite.result) {\n suite.result.duration = positiveSum(suite.tasks, t => t.result?.duration);\n suite.result.state = hasFailures ? 'fail' : 'pass';\n \n debug(`${logPrefix} - Set suite result: \"${suite.result.state}\" (hasFailures: ${hasFailures})`);\n }\n }\n}\n\nexport function finalizeSuiteResult(suite: Suite): void {\n (suite.meta as AssemblyScriptSuiteTaskMeta).resultFinal = true;\n}\n\nexport function resetTestForRetry(test: Test, startTime: number): void {\n if (test.result) {\n test.result!.state = 'run';\n test.result!.startTime = startTime;\n }\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n\n // clear any custom metadata associated with the immediate last run\n meta.assertionsPassedCount = 0;\n meta.assertionsFailed = [];\n delete meta.lastError;\n delete meta.lastErrorValuesProvided;\n delete meta.lastErrorRawCallStack;\n delete meta.lastTimeoutTerminationTime;\n delete meta.coverageData;\n}\n\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vitest-tasks-ByPK8DvF.mjs","names":[],"sources":["../src/wasm-executor/source-maps.ts","../src/util/vitest-tasks.ts"],"sourcesContent":["/**\n * Source Map Utilities\n *\n * Maps WASM errors to AssemblyScript source locations using V8 stack traces + source maps.\n *\n * Approach: V8's Error.prepareStackTrace provides WAT (WebAssembly Text) line:column positions,\n * which can be mapped to AS source using the source maps generated by AS compiler.\n */\n\nimport { type RawSourceMap, SourceMapConsumer } from 'source-map';\n\nimport { debug } from '../util/debug.js';\nimport type { WebAssemblyCallSite } from '../types/types.js';\nimport { createPoolErrorFromAnyError } from '../util/pool-errors.js';\nimport { POOL_ERROR_NAMES } from '../types/constants.js';\n\nexport function parseSourceMap(sourceMap: string): RawSourceMap {\n // Remove sourceRoot if present to prevent source-map library from prepending it to paths\n // AS compiler sets sourceRoot: \"./output\" which would make paths like \"output/tests/...\"\n // instead of \"tests/...\" - these paths don't exist and won't be found by Vitest\n try {\n const sourceMapObj: RawSourceMap = JSON.parse(sourceMap);\n delete sourceMapObj.sourceRoot;\n return sourceMapObj;\n }\n catch (err) {\n throw createPoolErrorFromAnyError(\n `parseSourceMap error`,\n POOL_ERROR_NAMES.PoolError,\n err\n )\n }\n}\n\n/**\n * Extract structured call stack from V8 using Error.prepareStackTrace\n *\n * V8 provides a special API to access structured stack traces with line:column info.\n * This gives us WAT text positions which can be mapped to AS source via source maps.\n *\n * @param capturedError - Error object to extract stack from\n * @returns Array of V8 CallSite objects\n */\nexport function extractCallStack(capturedError: Error): NodeJS.CallSite[] {\n let stackTrace: NodeJS.CallSite[] = [];\n\n const originalPrepareStackTrace = Error.prepareStackTrace;\n Error.prepareStackTrace = (_err: Error, structuredStackTrace: NodeJS.CallSite[]) => {\n stackTrace = structuredStackTrace;\n return ''; // Return empty string to avoid modifying error.stack\n };\n\n // Access error.stack to trigger prepareStackTrace (result unused, just triggers callback)\n capturedError.stack;\n\n // Restore original\n Error.prepareStackTrace = originalPrepareStackTrace;\n\n return stackTrace;\n}\n\n/**\n * Create WebAssembly call site with source mapping\n *\n * Takes a V8 CallSite and maps it to AS source location if possible.\n *\n * @param callSite - V8 CallSite object from Error.prepareStackTrace\n * @param sourceMapJson - Source map consumer initialized with WASM source map\n * @returns Mapped call site or null if not a WASM call site\n */\nexport function createWebAssemblyCallSite(\n callSite: NodeJS.CallSite,\n sourceMapConsumer: SourceMapConsumer,\n loggingPrefix: string,\n): WebAssemblyCallSite | null {\n const fileName = callSite.getFileName();\n\n // Only process WASM call sites\n if (!fileName || !fileName.startsWith('wasm://')) {\n return null;\n }\n\n const watLine = callSite.getLineNumber();\n const watColumn = callSite.getColumnNumber();\n const functionName = callSite.getFunctionName() || 'wasm-function[unknown]';\n const debugString = `function: \"${functionName}\" | wasm: ${fileName}:${watLine}:${watColumn}`;\n\n // Try to map to source\n if (watLine && watColumn) {\n const original = sourceMapConsumer.originalPositionFor({\n line: watLine,\n column: watColumn\n });\n \n if (!original.source || original.line === null || original.column === null) {\n debug(`${loggingPrefix} - Failed to source-map stack location: ${debugString}`);\n return null;\n }\n\n debug(`${loggingPrefix} - Source-mapped stack location: ${debugString} → ${original.source}:${original.line}:${original.column}`);\n \n const callSite: WebAssemblyCallSite = {\n functionName,\n location: {\n filePath: original.source,\n line: original.line,\n column: original.column\n }\n };\n\n return callSite;\n }\n\n debug(`${loggingPrefix} - Failed to source-map stack-location: ${debugString}`);\n\n // Fallback to WAT position\n return {\n functionName,\n location: {\n filePath: fileName,\n line: watLine || -1,\n column: watColumn || -1\n }\n };\n}\n","import type { File, RunMode, Suite, Task, Test } from '@vitest/runner/types';\n\nimport type {\n AssemblyScriptCoveragePayload,\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestError,\n AssemblyScriptTestOptions,\n AssemblyScriptTestTaskMeta,\n FailedAssertion,\n VitestVersion,\n WASMExecutorPerfTimings\n} from '../types/types.js';\nimport { TEST_ERROR_NAMES } from '../types/constants.js';\nimport { debug } from './debug.js';\nimport { createTestExpectedToFailError, createTestTimeoutError } from './pool-errors.js';\nimport { extractCallStack } from '../wasm-executor/source-maps.js';\n\n// ============================================================================\n// Util\n// ============================================================================\n\nfunction positiveSum<T>(items: T[], getSummableValue: (_next: T) => number | undefined): number {\n return items.reduce((total, next) => {\n return total + Math.max(getSummableValue(next) || 0, 0)\n }, 0);\n}\n\nfunction hasNonFileParentSuite(suite: Suite): boolean {\n return !!suite.suite?.id && suite.suite.id !== suite.file.id;\n}\n\nfunction getSuiteHierarchyName(suite: Suite): string {\n let name = suite.name;\n let currentSuite = suite;\n \n while (hasNonFileParentSuite(currentSuite)) {\n name = `${currentSuite.suite!.name} > ${name}`;\n currentSuite = currentSuite.suite!;\n }\n \n return name;\n}\n\nexport function isSuiteOwnFile(suite: Suite): boolean {\n return suite.file.id === suite.id;\n}\n\nexport function getTaskLogLabel(base: string, task: Task): string {\n if (task.type === 'suite') {\n return isSuiteOwnFile(task) ?\n `${base}`\n : `${base} - \"${getSuiteHierarchyName(task)}\"`;\n } else {\n return `${base} - \"${getSuiteHierarchyName(task.suite!)} > ${task.name}\"`;\n }\n}\n\nexport function getTaskLogPrefix(logModule: string, base: string, task: Task): string {\n return `[${logModule}] ${getTaskLogLabel(base, task)}`;\n}\n\nexport function createAfterSuiteRunMeta(\n coverage: AssemblyScriptCoveragePayload,\n testFiles: string[],\n projectName: string = '',\n vitestVersion: VitestVersion = 'v4',\n): any {\n const base = { coverage, testFiles, projectName };\n\n if (vitestVersion) {\n return { ...base, transformMode: 'ssr' as const };\n } else {\n return { ...base, environment: 'node' as const };\n }\n}\n\n// ============================================================================\n// Task Creation\n// ============================================================================\n\nexport function getInitialTaskMode(options: AssemblyScriptTestOptions): RunMode {\n if (options.skip) {\n return 'skip';\n } else if (options.only) {\n return 'only';\n } else {\n return 'run';\n }\n}\n\nexport function getInitialTestTaskMeta(\n fnIndex: number,\n parentAfterAddingTask: Suite,\n): AssemblyScriptTestTaskMeta {\n return {\n fnIndex,\n idxInParentTasks: parentAfterAddingTask.tasks.length - 1,\n assertionsPassedCount: 0,\n assertionsFailed: [],\n resultFinal: false,\n };\n}\n\nexport function getInitialSuiteTaskMeta(\n parentAfterAddingTask: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n): AssemblyScriptSuiteTaskMeta {\n return {\n idxInParentTasks: parentAfterAddingTask.tasks.length - 1,\n defaultTestOptions: mergedOptions,\n suitePreparedSent: false,\n resultFinal: false,\n };\n}\n\n\nfunction createTaskName(names: readonly (string | undefined)[], separator: string = ' > '): string {\n return names.filter(name => name !== undefined).join(separator);\n}\n\nexport function createTestTask(\n name: string,\n fnIndex: number,\n file: File,\n parent: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n vitestVersion: VitestVersion = 'v4',\n): Test {\n const test: Test = {\n type: 'test',\n name,\n fullName: createTaskName([\n parent?.fullName ?? file?.fullName,\n name,\n ]),\n fullTestName: createTaskName([parent?.fullTestName, name]),\n id: '',\n file,\n suite: parent,\n context: {} as any,\n annotations: [],\n artifacts: [],\n meta: {},\n mode: getInitialTaskMode(mergedOptions),\n timeout: mergedOptions.timeout,\n retry: mergedOptions.retry,\n fails: mergedOptions.fails,\n };\n\n if (vitestVersion === 'v3') {\n // @ts-ignore\n delete test.fullName;\n // @ts-ignore\n delete test.fullTestName;\n // @ts-ignore\n delete test.artifacts;\n }\n\n parent.tasks.push(test);\n\n // use custom TaskMeta to capture fnIndex, parent task index, etc\n test.meta = getInitialTestTaskMeta(fnIndex, parent);\n\n return test;\n}\n\nexport function createSuiteTask(\n name: string,\n file: File,\n parent: Suite,\n mergedOptions: AssemblyScriptTestOptions,\n vitestVersion: VitestVersion = 'v4',\n): Suite {\n // const suiteIsFile = parent.file.id === parent.id;\n // const prefix = suiteIsFile ? parent.name : `${file.filepath}_${parent.name}`;\n const suite: Suite = {\n type: 'suite',\n name,\n fullName: createTaskName([\n parent?.fullName ?? file?.fullName,\n name,\n ]),\n fullTestName: createTaskName([parent?.fullTestName, name]),\n id: '',\n file,\n suite: parent,\n meta: {},\n tasks: [],\n mode: getInitialTaskMode(mergedOptions),\n };\n\n if (vitestVersion === 'v3') {\n // @ts-ignore\n delete suite.fullName;\n // @ts-ignore\n delete suite.fullTestName;\n }\n\n parent.tasks.push(suite);\n\n // use custom TaskMeta to capture parent task index and default options\n suite.meta = getInitialSuiteTaskMeta(parent, mergedOptions);\n\n return suite;\n}\n\n\n// ============================================================================\n// Dispatch Helpers\n// ============================================================================\n\nexport function getRunnableTasks(suite: Suite): Task[] {\n return suite.tasks.filter(t => t.mode === 'queued' || t.mode === 'run');\n}\n\n\n// ============================================================================\n// Result Handling Helpers\n// ============================================================================\n\nexport function shouldRetryTask(task: Task): boolean {\n return task.result?.state === 'fail'\n && task.retry !== undefined\n && task.retry > 0\n && (\n task.result.retryCount === undefined\n || task.result.retryCount === 0\n || (task.result.retryCount < task.retry)\n );\n}\n\n/**\n * Invert result if test configured as 'fails'.\n */\nexport function checkFailsAndInvertResult(test: Test, logPrefix: string): void {\n if (test.fails) {\n if (test.result?.state === 'pass') {\n test.result.state = 'fail';\n\n debug(`${logPrefix} - Has 'fails' option set - inverted \"pass\" to \"fail\"`);\n\n const err = createTestExpectedToFailError(test);\n if (test.result.errors) {\n test.result.errors.push(err);\n } else {\n test.result.errors = [err];\n }\n } else if (test.result?.state === 'fail') {\n test.result.state = 'pass';\n test.result.errors = [];\n\n debug(`${logPrefix} - Has 'fails' option set - inverted \"fail\" to \"pass\"`);\n }\n }\n}\n\nexport function setTestResultForTestPrepare(test: Test, startTime: number): void {\n test.result = {\n state: 'run',\n startTime,\n retryCount: 0\n };\n};\n\nexport function updateTestResultAfterRun(test: Test, testTimings?: WASMExecutorPerfTimings): void {\n // while failed tests are actively set to failed, a passed test\n // will still be in the prepared result state (run), so set it to pass\n if (test.result?.state === 'run') {\n test.result.state = 'pass';\n }\n \n if (test.result && testTimings) {\n // accumulate duration for any retries that may be done\n test.result.duration = (test.result.duration ?? 0) + (testTimings.execEnd - testTimings.execStart);\n }\n}\n\nexport function flagTestTerminated(test: Test): void {\n (test.meta as AssemblyScriptTestTaskMeta).lastTimeoutTerminationTime = Date.now();\n}\n\nexport function flagTestFinalized(test: Test): void {\n (test.meta as AssemblyScriptTestTaskMeta).resultFinal = true;\n}\n\nexport function failTest(\n test: Test,\n errorMessage: string,\n capturedError: Error,\n logPrefix: string,\n): void {\n if (test.result) {\n test.result.state = 'fail';\n } else {\n test.result = { state: 'fail' };\n }\n\n const testError: AssemblyScriptTestError = {\n name: TEST_ERROR_NAMES.WASMRuntimeError,\n message: errorMessage\n };\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n \n // determine if this was an assertion failure\n if (meta.assertionsFailed?.length > 0) {\n testError.name = TEST_ERROR_NAMES.AssertionError;\n\n const assertion: FailedAssertion = meta.assertionsFailed[meta.assertionsFailed.length - 1]!;\n\n // set actual and expected values as strings, if provided\n if (assertion.valuesProvided) {\n meta.lastErrorValuesProvided = true;\n testError.expected = assertion.expected !== undefined ? String(assertion.expected) : undefined;\n testError.actual = assertion.actual !== undefined ? String(assertion.actual) : undefined;\n }\n }\n \n // Set error to report to vitest on the test meta.\n // Stack gets updated when executor enhances/source-maps the error, post-abort\n meta.lastError = testError;\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 meta.lastErrorRawCallStack = extractCallStack(capturedError);\n\n debug(`${logPrefix} - Captured raw V8 call stack with ${meta.lastErrorRawCallStack.length} frames`);\n}\n\nexport function failTestWithTimeoutError (test: Test, startTime: number, duration: number): void {\n const timeoutErr = createTestTimeoutError(test);\n\n if (test.result) {\n test.result.state = 'fail';\n test.result.startTime = startTime;\n \n // accumulate duration for any retries that may be done\n test.result.duration = (test.result.duration ?? 0) + duration;\n\n if (test.result.errors) {\n test.result.errors.push(timeoutErr)\n } else {\n test.result.errors = [timeoutErr];\n }\n } else {\n test.result = {\n state: 'fail',\n startTime,\n duration,\n errors: [timeoutErr],\n retryCount: 0,\n };\n }\n}\n\nexport function setSuitePrepareResult(suite: Suite): void {\n if (suite.mode === 'skip') {\n suite.result = {\n state: 'skip',\n duration: 0,\n };\n } else {\n suite.result = {\n state: 'run',\n startTime: Date.now(),\n };\n }\n}\n\nexport function updateSuiteFinishedResult(suite: Suite, logPrefix: string): void {\n if (suite.mode === 'skip') {\n suite.result = {\n state: 'skip',\n duration: 0,\n };\n } else {\n // update suite final result based on sub-task results\n const hasFailures = suite.tasks.some(({ result }) => result?.state === 'fail' );\n \n if (suite.result) {\n suite.result.duration = positiveSum(suite.tasks, t => t.result?.duration);\n suite.result.state = hasFailures ? 'fail' : 'pass';\n \n debug(`${logPrefix} - Set suite result: \"${suite.result.state}\" (hasFailures: ${hasFailures})`);\n }\n }\n}\n\nexport function finalizeSuiteResult(suite: Suite): void {\n (suite.meta as AssemblyScriptSuiteTaskMeta).resultFinal = true;\n}\n\nexport function resetTestForRetry(test: Test, startTime: number): void {\n if (test.result) {\n test.result!.state = 'run';\n test.result!.startTime = startTime;\n }\n\n const meta = test.meta as AssemblyScriptTestTaskMeta;\n\n // clear any custom metadata associated with the immediate last run\n meta.assertionsPassedCount = 0;\n meta.assertionsFailed = [];\n delete meta.lastError;\n delete meta.lastErrorValuesProvided;\n delete meta.lastErrorRawCallStack;\n delete meta.lastTimeoutTerminationTime;\n delete meta.coverageData;\n}\n\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//#region src/wasm-executor/wasm-names.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the short name from a WASM function table name identifier.
|
|
4
|
+
*/
|
|
5
|
+
function getShortFunctionName(fullName) {
|
|
6
|
+
if (!fullName) return "";
|
|
7
|
+
let decoded;
|
|
8
|
+
try {
|
|
9
|
+
decoded = decodeURIComponent(fullName);
|
|
10
|
+
decoded = decoded.replace("\\2c", ",");
|
|
11
|
+
} catch {
|
|
12
|
+
decoded = fullName;
|
|
13
|
+
}
|
|
14
|
+
let angleBracketDepth = 0;
|
|
15
|
+
let parenDepth = 0;
|
|
16
|
+
let lastSlashOutsideBrackets = -1;
|
|
17
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
18
|
+
const char = decoded[i];
|
|
19
|
+
if (char === "<") angleBracketDepth++;
|
|
20
|
+
else if (char === ">" && decoded[i - 1] !== "=") angleBracketDepth--;
|
|
21
|
+
else if (char === "(") parenDepth++;
|
|
22
|
+
else if (char === ")") parenDepth--;
|
|
23
|
+
else if (char === "/" && angleBracketDepth === 0 && parenDepth === 0) lastSlashOutsideBrackets = i;
|
|
24
|
+
}
|
|
25
|
+
const functionPart = lastSlashOutsideBrackets >= 0 ? decoded.substring(lastSlashOutsideBrackets + 1) : decoded;
|
|
26
|
+
const anonymousMatch = functionPart.match(/^.+~(anonymous\|\d+)$/);
|
|
27
|
+
if (anonymousMatch) return anonymousMatch[1];
|
|
28
|
+
return shortenTypePart(functionPart);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Finds the index of the closing '>' that matches the opening '<' at openIndex.
|
|
32
|
+
*/
|
|
33
|
+
function findMatchingCloseBracket(str, openIndex) {
|
|
34
|
+
let angleBracketDepth = 1;
|
|
35
|
+
for (let i = openIndex + 1; i < str.length; i++) {
|
|
36
|
+
const char = str[i];
|
|
37
|
+
if (char === "<") angleBracketDepth++;
|
|
38
|
+
else if (char === ">" && str[i - 1] !== "=") {
|
|
39
|
+
angleBracketDepth--;
|
|
40
|
+
if (angleBracketDepth === 0) return i;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return str.length - 1;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Finds the index of the closing ')' that matches the opening '(' at openIndex.
|
|
47
|
+
*/
|
|
48
|
+
function findMatchingCloseParen(str, openIndex) {
|
|
49
|
+
let parenDepth = 1;
|
|
50
|
+
let angleBracketDepth = 0;
|
|
51
|
+
for (let i = openIndex + 1; i < str.length; i++) {
|
|
52
|
+
const char = str[i];
|
|
53
|
+
if (char === "(") parenDepth++;
|
|
54
|
+
else if (char === ")") {
|
|
55
|
+
parenDepth--;
|
|
56
|
+
if (parenDepth === 0) return i;
|
|
57
|
+
} else if (char === "<") angleBracketDepth++;
|
|
58
|
+
else if (char === ">" && str[i - 1] !== "=") angleBracketDepth--;
|
|
59
|
+
}
|
|
60
|
+
return str.length - 1;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Splits a string by commas at the top level (not inside <> or ()).
|
|
64
|
+
*/
|
|
65
|
+
function splitByTopLevelComma(str) {
|
|
66
|
+
const parts = [];
|
|
67
|
+
let current = "";
|
|
68
|
+
let angleBracketDepth = 0;
|
|
69
|
+
let parenDepth = 0;
|
|
70
|
+
for (let i = 0; i < str.length; i++) {
|
|
71
|
+
const char = str[i];
|
|
72
|
+
if (char === "<") angleBracketDepth++;
|
|
73
|
+
else if (char === ">" && str[i - 1] !== "=") angleBracketDepth--;
|
|
74
|
+
else if (char === "(") parenDepth++;
|
|
75
|
+
else if (char === ")") parenDepth--;
|
|
76
|
+
else if (char === "," && angleBracketDepth === 0 && parenDepth === 0) {
|
|
77
|
+
parts.push(current);
|
|
78
|
+
current = "";
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
current += char;
|
|
82
|
+
}
|
|
83
|
+
parts.push(current);
|
|
84
|
+
return parts;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Processes the content inside generic brackets or function args.
|
|
88
|
+
*/
|
|
89
|
+
function shortenGenericContent(content) {
|
|
90
|
+
return splitByTopLevelComma(content).map((part) => shortenTypePart(part.trim())).join(",");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Shortens a function type like (args)=>returnType.
|
|
94
|
+
*/
|
|
95
|
+
function shortenFunctionType(part) {
|
|
96
|
+
const closeParenIndex = findMatchingCloseParen(part, 0);
|
|
97
|
+
const argsContent = part.substring(1, closeParenIndex);
|
|
98
|
+
const afterParen = part.substring(closeParenIndex + 1);
|
|
99
|
+
const shortenedArgs = argsContent ? shortenGenericContent(argsContent) : "";
|
|
100
|
+
let returnPart = afterParen;
|
|
101
|
+
if (afterParen.startsWith("=>") && afterParen.length > 2) returnPart = "=>" + shortenTypePart(afterParen.substring(2));
|
|
102
|
+
return "(" + shortenedArgs + ")" + returnPart;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Shortens a type/function part, processing paths and generics recursively.
|
|
106
|
+
*/
|
|
107
|
+
function shortenTypePart(part) {
|
|
108
|
+
if (part.startsWith("(")) return shortenFunctionType(part);
|
|
109
|
+
const openBracket = part.indexOf("<");
|
|
110
|
+
if (openBracket === -1) {
|
|
111
|
+
if (!part.includes("/")) return part;
|
|
112
|
+
return part.substring(part.lastIndexOf("/") + 1);
|
|
113
|
+
}
|
|
114
|
+
const namePart = part.substring(0, openBracket);
|
|
115
|
+
const closeBracket = findMatchingCloseBracket(part, openBracket);
|
|
116
|
+
const genericContent = part.substring(openBracket + 1, closeBracket);
|
|
117
|
+
const name = namePart.includes("/") ? namePart.substring(namePart.lastIndexOf("/") + 1) : namePart;
|
|
118
|
+
const shortenedContent = shortenGenericContent(genericContent);
|
|
119
|
+
return name + "<" + shortenedContent + ">";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//#endregion
|
|
123
|
+
export { getShortFunctionName };
|
|
124
|
+
//# sourceMappingURL=wasm-names-CydfYzQK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm-names-CydfYzQK.mjs","names":[],"sources":["../src/wasm-executor/wasm-names.ts"],"sourcesContent":["/**\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 \n // handle AS encoding quirk in generics\n // e.g. \"closeTo<bool\\2cbool>\" -> \"closeTo<bool,bool>\"\n decoded = decoded.replace('\\\\2c', ',');\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"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-pool-assemblyscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "AssemblyScript testing with Vitest - Simple, fast, familiar, AS-native, with full coverage output",
|
|
5
5
|
"author": "Matt Ritter <matthew.d.ritter@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -74,12 +74,19 @@
|
|
|
74
74
|
"homepage": "https://github.com/themattspiral/vitest-pool-assemblyscript#readme",
|
|
75
75
|
"scripts": {
|
|
76
76
|
"build": "tsdown",
|
|
77
|
-
"tc": "tsc --noEmit",
|
|
78
77
|
"//------------ Testing ------------": "",
|
|
78
|
+
"tc": "tsc --noEmit",
|
|
79
79
|
"test": "vitest run",
|
|
80
|
+
"ctest": "npm run build && vitest run",
|
|
81
|
+
"tctest": "npm run tc && npm run build && vitest run",
|
|
80
82
|
"test:watch": "vitest",
|
|
81
83
|
"test:fixtures": "npm run testf",
|
|
82
|
-
"
|
|
84
|
+
"ftest": "vitest run -c test-fixtures/vitest.config.ts",
|
|
85
|
+
"test:external:setup": "node scripts/setup-test-external.js",
|
|
86
|
+
"test:external:run": "node scripts/run-test-external.js",
|
|
87
|
+
"test:external": "node scripts/setup-test-external.js && node scripts/run-test-external.js",
|
|
88
|
+
"test:external:no-coverage": "node scripts/setup-test-external.js && node scripts/run-test-external.js --coverage.enabled=false",
|
|
89
|
+
"etest": "npm run build && npm run test:external",
|
|
83
90
|
"//------------ Native Addon ------------": "",
|
|
84
91
|
"setup-binaryen": "node scripts/setup-binaryen.js",
|
|
85
92
|
"build:native": "node-gyp rebuild",
|
|
@@ -91,7 +98,7 @@
|
|
|
91
98
|
"node-addon-api": "^8.5.0",
|
|
92
99
|
"node-gyp-build": "^4.8.0",
|
|
93
100
|
"source-map": "^0.7.6",
|
|
94
|
-
"
|
|
101
|
+
"tinyglobby": "^0.2.15",
|
|
95
102
|
"tinypool": "^2.1.0",
|
|
96
103
|
"tinyrainbow": "^3.0.3"
|
|
97
104
|
},
|
|
@@ -110,7 +117,6 @@
|
|
|
110
117
|
"@types/node": "22.19.1",
|
|
111
118
|
"@types/semver": "^7.7.1",
|
|
112
119
|
"@types/source-map": "^0.5.2",
|
|
113
|
-
"@types/test-exclude": "^6.0.2",
|
|
114
120
|
"@vitest/coverage-v8": "^4.0.18",
|
|
115
121
|
"@vitest/runner": "^4.0.18",
|
|
116
122
|
"@vitest/utils": "^4.0.18",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -213,7 +213,7 @@ bool startsWith(const std::string& str, const std::string& prefix) {
|
|
|
213
213
|
/**
|
|
214
214
|
* Check if a function should be instrumented for coverage
|
|
215
215
|
*/
|
|
216
|
-
bool shouldInstrumentFunction(Function* func, std::string& excludedLibraryFilePrefix) {
|
|
216
|
+
bool shouldInstrumentFunction(Function* func, std::string& excludedLibraryFilePrefix, std::string& excludedLibraryFileOverridePrefix) {
|
|
217
217
|
const std::string& name = func->name.toString();
|
|
218
218
|
|
|
219
219
|
// Skip functions without a body
|
|
@@ -234,6 +234,20 @@ bool shouldInstrumentFunction(Function* func, std::string& excludedLibraryFilePr
|
|
|
234
234
|
|
|
235
235
|
// Skip library functions
|
|
236
236
|
if (excludedLibraryFilePrefix.length() > 0 && startsWith(name, excludedLibraryFilePrefix)) {
|
|
237
|
+
if (excludedLibraryFileOverridePrefix.length() != 0) {
|
|
238
|
+
if (startsWith(name, excludedLibraryFileOverridePrefix)) {
|
|
239
|
+
if (DEBUG) {
|
|
240
|
+
std::cout << LOG_PREFIX << " - Library file but overriding skip to include" << std::endl;
|
|
241
|
+
}
|
|
242
|
+
return true;
|
|
243
|
+
} else {
|
|
244
|
+
if (DEBUG) {
|
|
245
|
+
std::cout << LOG_PREFIX << " - Skip Reason: Library file" << std::endl;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
237
251
|
if (DEBUG) {
|
|
238
252
|
std::cout << LOG_PREFIX << " - Skip Reason: Library file" << std::endl;
|
|
239
253
|
}
|
|
@@ -408,6 +422,7 @@ Napi::Object InstrumentForCoverage(const Napi::CallbackInfo& info) {
|
|
|
408
422
|
// Extracted options
|
|
409
423
|
std::unordered_set<std::string> excludedFiles;
|
|
410
424
|
std::string excludedLibraryFilePrefix;
|
|
425
|
+
std::string excludedLibraryFileOverridePrefix = "";
|
|
411
426
|
// 1 page = 64KB / 4bytes (32bits) each = 16384 counters
|
|
412
427
|
uint32_t coverageMemoryPagesMin = 1;
|
|
413
428
|
// 4 pages = 256KB / 4bytes (32bits) each = 65536 counters
|
|
@@ -468,6 +483,17 @@ Napi::Object InstrumentForCoverage(const Napi::CallbackInfo& info) {
|
|
|
468
483
|
}
|
|
469
484
|
}
|
|
470
485
|
|
|
486
|
+
if (options.Has("excludedLibraryFileOverridePrefix")) {
|
|
487
|
+
Napi::Value libraryFileOverridePrefixProperty = options.Get("excludedLibraryFileOverridePrefix");
|
|
488
|
+
if (libraryFileOverridePrefixProperty.IsString()) {
|
|
489
|
+
excludedLibraryFileOverridePrefix = libraryFileOverridePrefixProperty.As<Napi::String>().Utf8Value();
|
|
490
|
+
|
|
491
|
+
if (DEBUG) {
|
|
492
|
+
std::cout << LOG_PREFIX << " - OPTIONS - Excluded Library File Override Prefix: \"" << excludedLibraryFileOverridePrefix << "\"" << std::endl;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
471
497
|
if (options.Has("coverageMemoryPagesMin")) {
|
|
472
498
|
Napi::Value coverageMinProperty = options.Get("coverageMemoryPagesMin");
|
|
473
499
|
if (coverageMinProperty.IsNumber()) {
|
|
@@ -549,7 +575,7 @@ Napi::Object InstrumentForCoverage(const Napi::CallbackInfo& info) {
|
|
|
549
575
|
}
|
|
550
576
|
|
|
551
577
|
// Check if this function should be instrumented
|
|
552
|
-
if (!shouldInstrumentFunction(func, excludedLibraryFilePrefix)) {
|
|
578
|
+
if (!shouldInstrumentFunction(func, excludedLibraryFilePrefix, excludedLibraryFileOverridePrefix)) {
|
|
553
579
|
if (DEBUG) {
|
|
554
580
|
std::cout << LOG_PREFIX << " - SKIP function (quick filtered): \"" << funcName << "\"" << std::endl;
|
|
555
581
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compile-runner-C2eh_xLp.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"}
|