vitest-pool-assemblyscript 0.2.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.
Files changed (83) hide show
  1. package/BINARYEN_VERSION +1 -0
  2. package/LICENSE +53 -0
  3. package/README.md +607 -0
  4. package/assembly/compare.ts +219 -0
  5. package/assembly/describe.ts +104 -0
  6. package/assembly/expect.ts +335 -0
  7. package/assembly/index.ts +14 -0
  8. package/assembly/options.ts +198 -0
  9. package/assembly/test.ts +147 -0
  10. package/assembly/tsconfig.json +6 -0
  11. package/binding.gyp +62 -0
  12. package/dist/ast-visitor-DC3SuTzs.mjs +310 -0
  13. package/dist/ast-visitor-DC3SuTzs.mjs.map +1 -0
  14. package/dist/compile-runner-8h0dBwG2.mjs +80 -0
  15. package/dist/compile-runner-8h0dBwG2.mjs.map +1 -0
  16. package/dist/compiler/transforms/strip-inline.d.mts +18 -0
  17. package/dist/compiler/transforms/strip-inline.d.mts.map +1 -0
  18. package/dist/compiler/transforms/strip-inline.mjs +38 -0
  19. package/dist/compiler/transforms/strip-inline.mjs.map +1 -0
  20. package/dist/compiler-CN6BRK_N.mjs +295 -0
  21. package/dist/compiler-CN6BRK_N.mjs.map +1 -0
  22. package/dist/config/index-v3.d.mts +111 -0
  23. package/dist/config/index-v3.d.mts.map +1 -0
  24. package/dist/config/index-v3.mjs +11 -0
  25. package/dist/config/index-v3.mjs.map +1 -0
  26. package/dist/config/index.d.mts +4 -0
  27. package/dist/config/index.mjs +8 -0
  28. package/dist/constants-CA50WBdr.mjs +130 -0
  29. package/dist/constants-CA50WBdr.mjs.map +1 -0
  30. package/dist/coverage-merge-0WqdC-dq.mjs +22 -0
  31. package/dist/coverage-merge-0WqdC-dq.mjs.map +1 -0
  32. package/dist/coverage-provider/index.d.mts +15 -0
  33. package/dist/coverage-provider/index.d.mts.map +1 -0
  34. package/dist/coverage-provider/index.mjs +535 -0
  35. package/dist/coverage-provider/index.mjs.map +1 -0
  36. package/dist/custom-provider-options-CF5C1kXb.d.mts +26 -0
  37. package/dist/custom-provider-options-CF5C1kXb.d.mts.map +1 -0
  38. package/dist/debug-IeEHsxy0.mjs +195 -0
  39. package/dist/debug-IeEHsxy0.mjs.map +1 -0
  40. package/dist/index-internal.d.mts +23 -0
  41. package/dist/index-internal.d.mts.map +1 -0
  42. package/dist/index-internal.mjs +4 -0
  43. package/dist/index-v3.d.mts +7 -0
  44. package/dist/index-v3.d.mts.map +1 -0
  45. package/dist/index-v3.mjs +206 -0
  46. package/dist/index-v3.mjs.map +1 -0
  47. package/dist/index.d.mts +3 -0
  48. package/dist/index.mjs +8 -0
  49. package/dist/load-user-imports-J9eaAW0_.mjs +801 -0
  50. package/dist/load-user-imports-J9eaAW0_.mjs.map +1 -0
  51. package/dist/pool-runner-init-CEwLyNI3.d.mts +8 -0
  52. package/dist/pool-runner-init-CEwLyNI3.d.mts.map +1 -0
  53. package/dist/pool-runner-init-d5qScS41.mjs +400 -0
  54. package/dist/pool-runner-init-d5qScS41.mjs.map +1 -0
  55. package/dist/pool-thread/compile-worker-thread.d.mts +7 -0
  56. package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -0
  57. package/dist/pool-thread/compile-worker-thread.mjs +42 -0
  58. package/dist/pool-thread/compile-worker-thread.mjs.map +1 -0
  59. package/dist/pool-thread/test-worker-thread.d.mts +7 -0
  60. package/dist/pool-thread/test-worker-thread.d.mts.map +1 -0
  61. package/dist/pool-thread/test-worker-thread.mjs +39 -0
  62. package/dist/pool-thread/test-worker-thread.mjs.map +1 -0
  63. package/dist/pool-thread/v3-tinypool-thread.d.mts +7 -0
  64. package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -0
  65. package/dist/pool-thread/v3-tinypool-thread.mjs +57 -0
  66. package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -0
  67. package/dist/resolve-config-as1w-Qyz.mjs +65 -0
  68. package/dist/resolve-config-as1w-Qyz.mjs.map +1 -0
  69. package/dist/test-runner-B2BpyPNK.mjs +142 -0
  70. package/dist/test-runner-B2BpyPNK.mjs.map +1 -0
  71. package/dist/types-8KKo9Hbf.d.mts +228 -0
  72. package/dist/types-8KKo9Hbf.d.mts.map +1 -0
  73. package/dist/vitest-file-tasks-BUwzh375.mjs +61 -0
  74. package/dist/vitest-file-tasks-BUwzh375.mjs.map +1 -0
  75. package/dist/vitest-tasks-BKS7689f.mjs +319 -0
  76. package/dist/vitest-tasks-BKS7689f.mjs.map +1 -0
  77. package/dist/worker-rpc-channel-lbhK7Qz8.mjs +25 -0
  78. package/dist/worker-rpc-channel-lbhK7Qz8.mjs.map +1 -0
  79. package/package.json +112 -0
  80. package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  81. package/scripts/install.js +91 -0
  82. package/scripts/setup-binaryen.js +179 -0
  83. package/src/native-instrumentation/addon.cpp +788 -0
@@ -0,0 +1,228 @@
1
+ import "tinyrainbow";
2
+ import { MessagePort } from "node:worker_threads";
3
+ import "birpc";
4
+ import "vitest/node";
5
+ import "@vitest/utils";
6
+ import { SerializedConfig } from "vitest";
7
+ import { File, Test } from "@vitest/runner/types";
8
+
9
+ //#region src/types/types.d.ts
10
+ /**
11
+ * AssemblyScript pool configuration options
12
+ */
13
+ interface AssemblyScriptPoolOptions {
14
+ /** Enable verbose debug logging */
15
+ debug?: boolean;
16
+ /**
17
+ * Strip `@inline` decorators during compilation to improve error message and coverage accuracy
18
+ *
19
+ * - When true (default): `@inline` decorators removed, functions become visible in coverage
20
+ * and source mapped errors point to the correct lines
21
+ * - When false: `@inline` functions are inlined by compiler, missing from coverage, and
22
+ * error line numbers don't match the non-inlined source
23
+ * @default true
24
+ */
25
+ stripInline?: boolean;
26
+ /**
27
+ * Maximum number of worker threads to spawn with vitest 3.x.
28
+ * Defaults to os.availableParallelism() - 1
29
+ *
30
+ * Use project config `test.maxWorkers` with vitest 4.x to control
31
+ * the number of cuncurrently executing tests.
32
+ */
33
+ maxThreadsV3?: number;
34
+ coverageMemoryPagesInitial?: number;
35
+ coverageMemoryPagesMax?: number;
36
+ testMemoryPagesInitial?: number;
37
+ testMemoryPagesMax?: number;
38
+ extraCompilerFlags?: string[];
39
+ wasmImportsFactory?: string;
40
+ }
41
+ /**
42
+ * HybridCoverageProvider configuration options.
43
+ */
44
+ interface HybridProviderOptions {
45
+ provider: "custom";
46
+ customProviderModule: string;
47
+ /**
48
+ * Glob patterns for AssemblyScript source files to include in coverage.
49
+ * Used to build the complete AS coverage map.
50
+ *
51
+ * The standard `include` patterns are used by the v8 provider for JS/TS files.
52
+ *
53
+ * @example ['assembly/**\/*.as.ts']
54
+ */
55
+ assemblyScriptInclude?: string[];
56
+ /**
57
+ * Glob patterns for AssemblyScript files to exclude from coverage.
58
+ *
59
+ * @example ['**\/*.as.test.ts']
60
+ */
61
+ assemblyScriptExclude?: string[];
62
+ }
63
+ interface WasmImportsFactoryInfo {
64
+ module: WebAssembly.Module;
65
+ memory: WebAssembly.Memory;
66
+ utils: {
67
+ liftString: (stringPtr: number) => string | undefined;
68
+ };
69
+ }
70
+ type WasmImportsFactory = (moduleInfo: WasmImportsFactoryInfo) => WebAssembly.Imports;
71
+ interface AssemblyScriptCompilerOptions {
72
+ shouldInstrument: boolean;
73
+ projectRoot: string;
74
+ instrumentationOptions?: InstrumentationOptions;
75
+ stripInline?: boolean;
76
+ extraFlags?: string[];
77
+ }
78
+ interface AssemblyScriptCompilerResult {
79
+ binary: Uint8Array;
80
+ sourceMap: string;
81
+ debugInfo?: BinaryDebugInfo;
82
+ isInstrumented: boolean;
83
+ compileTiming: number;
84
+ }
85
+ interface InstrumentationOptions {
86
+ /** List of relative file paths to exclude from instrumentation */
87
+ relativeExcludedFiles: string[];
88
+ excludedLibraryFilePrefix: string;
89
+ coverageMemoryPagesMin: number;
90
+ coverageMemoryPagesMax: number;
91
+ }
92
+ /**
93
+ * Source location in original AssemblyScript code (a point, not a range)
94
+ *
95
+ * All values are 1-based for internal consistency.
96
+ * Conversion to 0-based columns happens at Istanbul output boundary.
97
+ */
98
+ interface SourceLocation {
99
+ /** Relative file path */
100
+ filePath: string;
101
+ line: number;
102
+ column: number;
103
+ }
104
+ /**
105
+ * Branch edge in control flow graph
106
+ */
107
+ interface BranchEdgeDebugInfo {
108
+ /** Target basic block index */
109
+ targetBlockIndex: number;
110
+ /** Index of the expression that creates this branch (e.g., if condition) */
111
+ sourceExpressionIndex?: number;
112
+ }
113
+ /**
114
+ * Expression debug info extracted from WASM binary
115
+ *
116
+ * Expressions are the smallest unit of execution in WASM.
117
+ * In v2, each expression can be mapped to a source statement for line-level coverage.
118
+ */
119
+ interface ExpressionDebugInfo {
120
+ /** WASM expression type (e.g., "call", "if", "block") */
121
+ type: string;
122
+ /** Source location (POINT, not range) from source map */
123
+ location?: SourceLocation;
124
+ /** Whether this expression is a branch point (if, switch, select) */
125
+ isBranch: boolean;
126
+ /** Number of branch paths (for branch coverage) */
127
+ branchPaths?: number;
128
+ /**
129
+ * Index into coverage memory counters
130
+ * v2 only: Propagated from containing BasicBlockDebugInfo by TS wrapper
131
+ */
132
+ coverageMemoryIndex?: number;
133
+ }
134
+ /**
135
+ * Basic block debug info from CFG analysis
136
+ *
137
+ * Basic blocks are sequences of expressions with single entry/exit points.
138
+ * In v2, counters are placed at basic block boundaries for efficient coverage.
139
+ */
140
+ interface BasicBlockDebugInfo {
141
+ /** Block index within the function */
142
+ index: number;
143
+ /** Indices of expressions contained in this block */
144
+ expressionIndices: number[];
145
+ /** Outgoing branch edges */
146
+ branches: BranchEdgeDebugInfo[];
147
+ /**
148
+ * Index into coverage memory counters
149
+ * v2 only: Source of truth for block-level coverage
150
+ */
151
+ coverageMemoryIndex?: number;
152
+ }
153
+ /**
154
+ * Function debug info extracted from WASM binary via native addon
155
+ */
156
+ interface FunctionDebugInfo {
157
+ /** WASM function index */
158
+ wasmIndex: number;
159
+ /** Function name from WASM (informational) */
160
+ name: string;
161
+ /**
162
+ * Representative source location (a point within the function).
163
+ * Used for containment matching to find the parsedsource function.
164
+ */
165
+ representativeLocation: SourceLocation;
166
+ /** Index into coverage memory counters */
167
+ coverageMemoryIndex: number;
168
+ /** All expressions in this function */
169
+ expressions: ExpressionDebugInfo[];
170
+ /** Basic blocks from CFG analysis */
171
+ basicBlocks: BasicBlockDebugInfo[];
172
+ }
173
+ /**
174
+ * Binary debug info extracted from WASM + source map via native addon
175
+ *
176
+ * This is the processed output after TS wrapper transforms NativeDebugInfoOutput.
177
+ * Functions are grouped by file and keyed by position for stable identity.
178
+ */
179
+ interface BinaryDebugInfo {
180
+ /** All source files represented in extracted debug info (directly or inlined) */
181
+ debugSourceFiles: string[];
182
+ /**
183
+ * Functions grouped by file path, then keyed by position ("line:column")
184
+ * Position key enables stable identity across compilations
185
+ */
186
+ functionsByFileAndPosition: Record<string, Record<string, FunctionDebugInfo>>;
187
+ instrumentedFunctionCount: number;
188
+ }
189
+ interface WASMCompilation {
190
+ filePath: string;
191
+ binary: Uint8Array;
192
+ sourceMap: string;
193
+ debugInfo?: BinaryDebugInfo;
194
+ }
195
+ interface ThreadSpec {
196
+ file: File;
197
+ compilation?: WASMCompilation;
198
+ }
199
+ interface RunCompileAndDiscoverTask {
200
+ dispatchStart: number;
201
+ workerId: number;
202
+ port: MessagePort;
203
+ file: File;
204
+ config: SerializedConfig;
205
+ isCollectTestsMode: boolean;
206
+ }
207
+ interface RunTestsTask {
208
+ dispatchStart: number;
209
+ workerId: number;
210
+ port: MessagePort;
211
+ file: File;
212
+ compilation: WASMCompilation;
213
+ config: SerializedConfig;
214
+ isCollectTestsMode: boolean;
215
+ timedOutTest?: Test;
216
+ }
217
+ interface ProcessPoolRunFileTask {
218
+ dispatchStart: number;
219
+ port: MessagePort;
220
+ file: File;
221
+ config: SerializedConfig;
222
+ isCollectTestsMode: boolean;
223
+ timedOutTest?: Test;
224
+ timedOutCompilation?: WASMCompilation;
225
+ }
226
+ //#endregion
227
+ export { AssemblyScriptCompilerOptions, AssemblyScriptCompilerResult, AssemblyScriptPoolOptions, HybridProviderOptions, ProcessPoolRunFileTask, RunCompileAndDiscoverTask, RunTestsTask, ThreadSpec, WasmImportsFactory, WasmImportsFactoryInfo };
228
+ //# sourceMappingURL=types-8KKo9Hbf.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-8KKo9Hbf.d.mts","names":[],"sources":["../src/types/types.ts"],"mappings":";;;;;;;;;;AAqHA;;UA3DiB,yBAAA;EA6DK;EA3DpB,KAAA;;;;;;;;;;EAUA,WAAA;EAuDF;;;;;;;EA9CE,YAAA;EAEA,0BAAA;EACA,sBAAA;EAEA,sBAAA;EACA,kBAAA;EAEA,kBAAA;EAEA,kBAAA;AAAA;;;;UAMe,qBAAA;EACf,QAAA;EACA,oBAAA;EAsGA;AAGF;;;;;;;EA/FE,qBAAA;;;;;;EAOA,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,UAqEpE,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,qBAAA;EACA,yBAAA;EACA,sBAAA;EACA,sBAAA;AAAA;;;;;;AAiZF;UAxXiB,cAAA;;EAEf,QAAA;EACA,IAAA;EACA,MAAA;AAAA;;;;UAoEe,mBAAA;;EAEf,gBAAA;;EAEA,qBAAA;AAAA;;;;;;;UASe,mBAAA;EAyUjB;EAvUE,IAAA;;EAEA,QAAA,GAAW,cAAA;;EAEX,QAAA;;EAEA,WAAA;;;;;EAKA,mBAAA;AAAA;;;;;;;UASe,mBAAA;;EAEf,KAAA;EAwTsB;EAtTtB,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;;;;;EAKA,0BAAA,EAA4B,MAAA,SAAe,MAAA,SAAe,iBAAA;EAE1D,yBAAA;AAAA;AAAA,UA2Ne,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"}
@@ -0,0 +1,61 @@
1
+ import { calculateSuiteHash, createFileTask, interpretTaskModes, someTasksAreOnly } from "@vitest/runner/utils";
2
+
3
+ //#region src/types/typed-constants.ts
4
+ const DEFAULT_ASSEMBLYSCRIPT_TEST_OPTIONS = {
5
+ fails: false,
6
+ skip: false,
7
+ only: false
8
+ };
9
+
10
+ //#endregion
11
+ //#region src/util/vitest-file-tasks.ts
12
+ function createInitialFileTask(testFile, projectName, projectRoot, configTestTimeout, configRetry) {
13
+ const file = createFileTask(testFile, projectRoot, projectName, "assemblyscript");
14
+ file.mode = "queued";
15
+ file.environmentLoad = 0;
16
+ file.setupDuration = 0;
17
+ file.meta = {
18
+ idxInParentTasks: -1,
19
+ defaultTestOptions: {
20
+ ...DEFAULT_ASSEMBLYSCRIPT_TEST_OPTIONS,
21
+ timeout: configTestTimeout,
22
+ retry: configRetry
23
+ },
24
+ suitePreparedSent: false,
25
+ resultFinal: false
26
+ };
27
+ return file;
28
+ }
29
+ function prepareFileTaskForCollection(file, testNamePattern, allowOnly) {
30
+ calculateSuiteHash(file);
31
+ interpretTaskModes(file, testNamePattern, void 0, someTasksAreOnly(file), false, allowOnly);
32
+ if (file.mode === "queued") file.mode = "run";
33
+ }
34
+ function failFile(file, error, runStartPerf) {
35
+ file.mode = "run";
36
+ if (file.result) {
37
+ file.result.state = "fail";
38
+ file.result.errors = file.result.errors ? file.result.errors.concat(error) : [error];
39
+ } else file.result = {
40
+ state: "fail",
41
+ errors: [error]
42
+ };
43
+ file.environmentLoad = file.environmentLoad ?? 0;
44
+ file.setupDuration = performance.now() - runStartPerf;
45
+ file.collectDuration = file.collectDuration ?? 0;
46
+ return file;
47
+ }
48
+ function getFullTaskHierarchy(file) {
49
+ function spacesForLevel(level) {
50
+ return new Array(level + 1).fill(" ").join("");
51
+ }
52
+ function taskStr(task, level) {
53
+ if (task.type === "test") return `${spacesForLevel(level)}ID: ${task.id} Mode: "${task.mode}" Test: "${task.name}"`;
54
+ else return `${spacesForLevel(level)}ID: ${task.id} Mode: "${task.mode}" Suite: "${task.name}"\n` + task.tasks.map((t) => taskStr(t, level + 1)).join("\n");
55
+ }
56
+ return taskStr(file, 0);
57
+ }
58
+
59
+ //#endregion
60
+ export { createInitialFileTask, failFile, getFullTaskHierarchy, prepareFileTaskForCollection };
61
+ //# sourceMappingURL=vitest-file-tasks-BUwzh375.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-file-tasks-BUwzh375.mjs","names":[],"sources":["../src/types/typed-constants.ts","../src/util/vitest-file-tasks.ts"],"sourcesContent":["/**\n * Typed Constants\n * \n * Constants which require importing ./types\n */\n\nimport { AssemblyScriptTestOptions } from './types.js';\n\n// hard-coded defaults only - timeout and retry defaults always come from vitest config\nexport const DEFAULT_ASSEMBLYSCRIPT_TEST_OPTIONS: Pick<AssemblyScriptTestOptions, 'fails' | 'skip' | 'only'> = {\n fails: false,\n skip: false,\n only: false\n};\n","import type { SerializedConfig } from 'vitest';\nimport type { File, Task } from '@vitest/runner/types';\nimport {\n calculateSuiteHash,\n createFileTask,\n interpretTaskModes,\n someTasksAreOnly\n} from '@vitest/runner/utils';\n\nimport { ASSEMBLYSCRIPT_POOL_NAME } from '../types/constants.js';\nimport { DEFAULT_ASSEMBLYSCRIPT_TEST_OPTIONS } from '../types/typed-constants.js';\nimport type {\n AssemblyScriptSuiteTaskMeta,\n AssemblyScriptTestError,\n AssemblyScriptTestOptions,\n} from '../types/types.js';\n\nexport function createInitialFileTask(\n testFile: string,\n projectName: string,\n projectRoot: string,\n configTestTimeout: number,\n configRetry: number,\n): File {\n const file: File = createFileTask(\n testFile,\n projectRoot,\n projectName,\n ASSEMBLYSCRIPT_POOL_NAME\n );\n\n file.mode = 'queued';\n file.environmentLoad = 0; // AS pool has no environment setup\n file.setupDuration = 0; // AS pool has no setup files\n\n const defaultTestOptions: AssemblyScriptTestOptions = {\n ...DEFAULT_ASSEMBLYSCRIPT_TEST_OPTIONS,\n timeout: configTestTimeout,\n retry: configRetry,\n };\n\n const meta: AssemblyScriptSuiteTaskMeta = {\n idxInParentTasks: -1, // file task has no parent, should never be used anyway\n defaultTestOptions,\n suitePreparedSent: false,\n resultFinal: false,\n }\n file.meta = meta;\n\n return file;\n}\n\nexport function createFailedFileTask(\n testFile: string,\n projectName: string,\n config: SerializedConfig,\n error: AssemblyScriptTestError,\n): File {\n const file: File = createFileTask(\n testFile,\n config.root,\n projectName,\n ASSEMBLYSCRIPT_POOL_NAME\n );\n file.mode = 'run';\n file.result = {\n state: 'fail',\n errors: [error]\n };\n file.environmentLoad = 0;\n file.setupDuration = 0;\n file.collectDuration = 0;\n\n return file;\n}\n\nexport function prepareFileTaskForCollection(\n file: File,\n testNamePattern?: RegExp,\n allowOnly?: boolean,\n): void {\n calculateSuiteHash(file);\n\n // Interpret task modes does the following:\n // 1. If only mode enabled on any test, flip all non-only test.mode to skip\n // 2. Apply test name pattern filtering (from -t flag) to skip if needed\n // 3. If all test modes are skip, set file task mode to skip\n const hasOnly = someTasksAreOnly(file);\n interpretTaskModes(\n file,\n testNamePattern, // user regexp\n undefined, // testLocations\n hasOnly, // onlyMode - true if only is used anywhere\n false, // parentIsOnly - always false for the file task\n allowOnly\n );\n\n // update from queued (onQueued report) to run (onCollected report)\n if (file.mode === 'queued') {\n file.mode = 'run';\n }\n}\n\nexport function failFile(\n file: File,\n error: AssemblyScriptTestError,\n runStartPerf: number,\n): File {\n file.mode = 'run';\n\n if (file.result) {\n file.result.state = 'fail';\n file.result.errors = file.result.errors ? file.result.errors.concat(error) : [error];\n } else {\n file.result = {\n state: 'fail',\n errors: [error]\n };\n }\n file.environmentLoad = file.environmentLoad ?? 0;\n file.setupDuration = performance.now() - runStartPerf;\n file.collectDuration = file.collectDuration ?? 0;\n\n return file;\n}\n\n\n\nexport function getFullTaskHierarchy(file: File): string {\n function spacesForLevel(level: number): string {\n return new Array(level + 1).fill(' ').join('');\n }\n\n function taskStr(task: Task, level: number): string {\n if (task.type === 'test') {\n return `${spacesForLevel(level)}ID: ${task.id} Mode: \"${task.mode}\" Test: \"${task.name}\"`;\n } else {\n const suiteStr = `${spacesForLevel(level)}ID: ${task.id} Mode: \"${task.mode}\" Suite: \"${task.name}\"\\n`;\n return suiteStr + task.tasks.map(t => taskStr(t, level + 1)).join('\\n');\n }\n };\n\n return taskStr(file, 0);\n}\n"],"mappings":";;;AASA,MAAa,sCAAkG;CAC7G,OAAO;CACP,MAAM;CACN,MAAM;CACP;;;;ACID,SAAgB,sBACd,UACA,aACA,aACA,mBACA,aACM;CACN,MAAM,OAAa,eACjB,UACA,aACA,8BAED;AAED,MAAK,OAAO;AACZ,MAAK,kBAAkB;AACvB,MAAK,gBAAgB;AAcrB,MAAK,OANqC;EACxC,kBAAkB;EAClB,oBARoD;GACpD,GAAG;GACH,SAAS;GACT,OAAO;GACR;EAKC,mBAAmB;EACnB,aAAa;EACd;AAGD,QAAO;;AA2BT,SAAgB,6BACd,MACA,iBACA,WACM;AACN,oBAAmB,KAAK;AAOxB,oBACE,MACA,iBACA,QAJc,iBAAiB,KAAK,EAMpC,OACA,UACD;AAGD,KAAI,KAAK,SAAS,SAChB,MAAK,OAAO;;AAIhB,SAAgB,SACd,MACA,OACA,cACM;AACN,MAAK,OAAO;AAEZ,KAAI,KAAK,QAAQ;AACf,OAAK,OAAO,QAAQ;AACpB,OAAK,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,OAAO,OAAO,OAAO,MAAM,GAAG,CAAC,MAAM;OAEpF,MAAK,SAAS;EACZ,OAAO;EACP,QAAQ,CAAC,MAAM;EAChB;AAEH,MAAK,kBAAkB,KAAK,mBAAmB;AAC/C,MAAK,gBAAgB,YAAY,KAAK,GAAG;AACzC,MAAK,kBAAkB,KAAK,mBAAmB;AAE/C,QAAO;;AAKT,SAAgB,qBAAqB,MAAoB;CACvD,SAAS,eAAe,OAAuB;AAC7C,SAAO,IAAI,MAAM,QAAQ,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG;;CAGjD,SAAS,QAAQ,MAAY,OAAuB;AAClD,MAAI,KAAK,SAAS,OAChB,QAAO,GAAG,eAAe,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,KAAK,KAAK,WAAW,KAAK,KAAK;MAGvF,QADiB,GAAG,eAAe,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,KAAK,KAAK,YAAY,KAAK,KAAK,OAChF,KAAK,MAAM,KAAI,MAAK,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC,KAAK,KAAK;;AAI3E,QAAO,QAAQ,MAAM,EAAE"}
@@ -0,0 +1,319 @@
1
+ import { POOL_ERROR_NAMES, TEST_ERROR_NAMES } from "./constants-CA50WBdr.mjs";
2
+ import { createPoolErrorFromAnyError, createTestExpectedToFailError, createTestTimeoutError, debug } from "./debug-IeEHsxy0.mjs";
3
+
4
+ //#region src/wasm-executor/source-maps.ts
5
+ function parseSourceMap(sourceMap) {
6
+ try {
7
+ const sourceMapObj = JSON.parse(sourceMap);
8
+ delete sourceMapObj.sourceRoot;
9
+ return sourceMapObj;
10
+ } catch (err) {
11
+ throw createPoolErrorFromAnyError(`parseSourceMap error`, POOL_ERROR_NAMES.PoolError, err);
12
+ }
13
+ }
14
+ /**
15
+ * Extract structured call stack from V8 using Error.prepareStackTrace
16
+ *
17
+ * V8 provides a special API to access structured stack traces with line:column info.
18
+ * This gives us WAT text positions which can be mapped to AS source via source maps.
19
+ *
20
+ * @param capturedError - Error object to extract stack from
21
+ * @returns Array of V8 CallSite objects
22
+ */
23
+ function extractCallStack(capturedError) {
24
+ let stackTrace = [];
25
+ const originalPrepareStackTrace = Error.prepareStackTrace;
26
+ Error.prepareStackTrace = (_err, structuredStackTrace) => {
27
+ stackTrace = structuredStackTrace;
28
+ return "";
29
+ };
30
+ capturedError.stack;
31
+ Error.prepareStackTrace = originalPrepareStackTrace;
32
+ return stackTrace;
33
+ }
34
+ /**
35
+ * Create WebAssembly call site with source mapping
36
+ *
37
+ * Takes a V8 CallSite and maps it to AS source location if possible.
38
+ *
39
+ * @param callSite - V8 CallSite object from Error.prepareStackTrace
40
+ * @param sourceMapJson - Source map consumer initialized with WASM source map
41
+ * @returns Mapped call site or null if not a WASM call site
42
+ */
43
+ function createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix) {
44
+ const fileName = callSite.getFileName();
45
+ if (!fileName || !fileName.startsWith("wasm://")) return null;
46
+ const watLine = callSite.getLineNumber();
47
+ const watColumn = callSite.getColumnNumber();
48
+ const functionName = callSite.getFunctionName() || "wasm-function[unknown]";
49
+ const debugString = `function: "${functionName}" | wasm: ${fileName}:${watLine}:${watColumn}`;
50
+ if (watLine && watColumn) {
51
+ const original = sourceMapConsumer.originalPositionFor({
52
+ line: watLine,
53
+ column: watColumn
54
+ });
55
+ if (!original.source || original.line === null || original.column === null) {
56
+ debug(`${loggingPrefix} - Failed to source-map stack location: ${debugString}`);
57
+ return null;
58
+ }
59
+ debug(`${loggingPrefix} - Source-mapped stack location: ${debugString} → ${original.source}:${original.line}:${original.column}`);
60
+ return {
61
+ functionName,
62
+ location: {
63
+ filePath: original.source,
64
+ line: original.line,
65
+ column: original.column
66
+ }
67
+ };
68
+ }
69
+ debug(`${loggingPrefix} - Failed to source-map stack-location: ${debugString}`);
70
+ return {
71
+ functionName,
72
+ location: {
73
+ filePath: fileName,
74
+ line: watLine || -1,
75
+ column: watColumn || -1
76
+ }
77
+ };
78
+ }
79
+
80
+ //#endregion
81
+ //#region src/util/vitest-tasks.ts
82
+ function positiveSum(items, getSummableValue) {
83
+ return items.reduce((total, next) => {
84
+ return total + Math.max(getSummableValue(next) || 0, 0);
85
+ }, 0);
86
+ }
87
+ function hasNonFileParentSuite(suite) {
88
+ return !!suite.suite?.id && suite.suite.id !== suite.file.id;
89
+ }
90
+ function getSuiteHierarchyName(suite) {
91
+ let name = suite.name;
92
+ let currentSuite = suite;
93
+ while (hasNonFileParentSuite(currentSuite)) {
94
+ name = `${currentSuite.suite.name} > ${name}`;
95
+ currentSuite = currentSuite.suite;
96
+ }
97
+ return name;
98
+ }
99
+ function isSuiteOwnFile(suite) {
100
+ return suite.file.id === suite.id;
101
+ }
102
+ function getTaskLogLabel(base, task) {
103
+ if (task.type === "suite") return isSuiteOwnFile(task) ? `${base}` : `${base} - "${getSuiteHierarchyName(task)}"`;
104
+ else return `${base} - "${getSuiteHierarchyName(task.suite)} > ${task.name}"`;
105
+ }
106
+ function getTaskLogPrefix(logModule, base, task) {
107
+ return `[${logModule}] ${getTaskLogLabel(base, task)}`;
108
+ }
109
+ function createAfterSuiteRunMeta(coverage, testFiles, projectName = "", vitestVersion = "v4") {
110
+ const base = {
111
+ coverage,
112
+ testFiles,
113
+ projectName
114
+ };
115
+ if (vitestVersion) return {
116
+ ...base,
117
+ transformMode: "ssr"
118
+ };
119
+ else return {
120
+ ...base,
121
+ environment: "node"
122
+ };
123
+ }
124
+ function getInitialTaskMode(options) {
125
+ if (options.skip) return "skip";
126
+ else if (options.only) return "only";
127
+ else return "run";
128
+ }
129
+ function getInitialTestTaskMeta(fnIndex, parentAfterAddingTask) {
130
+ return {
131
+ fnIndex,
132
+ idxInParentTasks: parentAfterAddingTask.tasks.length - 1,
133
+ assertionsPassedCount: 0,
134
+ assertionsFailed: [],
135
+ resultFinal: false
136
+ };
137
+ }
138
+ function getInitialSuiteTaskMeta(parentAfterAddingTask, mergedOptions) {
139
+ return {
140
+ idxInParentTasks: parentAfterAddingTask.tasks.length - 1,
141
+ defaultTestOptions: mergedOptions,
142
+ suitePreparedSent: false,
143
+ resultFinal: false
144
+ };
145
+ }
146
+ function createTaskName(names, separator = " > ") {
147
+ return names.filter((name) => name !== void 0).join(separator);
148
+ }
149
+ function createTestTask(name, fnIndex, file, parent, mergedOptions, vitestVersion = "v4") {
150
+ const test = {
151
+ type: "test",
152
+ name,
153
+ fullName: createTaskName([parent?.fullName ?? file?.fullName, name]),
154
+ fullTestName: createTaskName([parent?.fullTestName, name]),
155
+ id: "",
156
+ file,
157
+ suite: parent,
158
+ context: {},
159
+ annotations: [],
160
+ artifacts: [],
161
+ meta: {},
162
+ mode: getInitialTaskMode(mergedOptions),
163
+ timeout: mergedOptions.timeout,
164
+ retry: mergedOptions.retry,
165
+ fails: mergedOptions.fails
166
+ };
167
+ if (vitestVersion === "v3") {
168
+ delete test.fullName;
169
+ delete test.fullTestName;
170
+ delete test.artifacts;
171
+ }
172
+ parent.tasks.push(test);
173
+ test.meta = getInitialTestTaskMeta(fnIndex, parent);
174
+ return test;
175
+ }
176
+ function createSuiteTask(name, file, parent, mergedOptions, vitestVersion = "v4") {
177
+ const suite = {
178
+ type: "suite",
179
+ name,
180
+ fullName: createTaskName([parent?.fullName ?? file?.fullName, name]),
181
+ fullTestName: createTaskName([parent?.fullTestName, name]),
182
+ id: "",
183
+ file,
184
+ suite: parent,
185
+ meta: {},
186
+ tasks: [],
187
+ mode: getInitialTaskMode(mergedOptions)
188
+ };
189
+ if (vitestVersion === "v3") {
190
+ delete suite.fullName;
191
+ delete suite.fullTestName;
192
+ }
193
+ parent.tasks.push(suite);
194
+ suite.meta = getInitialSuiteTaskMeta(parent, mergedOptions);
195
+ return suite;
196
+ }
197
+ function getRunnableTasks(suite) {
198
+ return suite.tasks.filter((t) => t.mode === "queued" || t.mode === "run");
199
+ }
200
+ function shouldRetryTask(task) {
201
+ return task.result?.state === "fail" && task.retry !== void 0 && task.retry > 0 && (task.result.retryCount === void 0 || task.result.retryCount === 0 || task.result.retryCount < task.retry);
202
+ }
203
+ /**
204
+ * Invert result if test configured as 'fails'.
205
+ */
206
+ function checkFailsAndInvertResult(test, logPrefix) {
207
+ if (test.fails) {
208
+ if (test.result?.state === "pass") {
209
+ test.result.state = "fail";
210
+ debug(`${logPrefix} - Has 'fails' option set - inverted "pass" to "fail"`);
211
+ const err = createTestExpectedToFailError(test);
212
+ if (test.result.errors) test.result.errors.push(err);
213
+ else test.result.errors = [err];
214
+ } else if (test.result?.state === "fail") {
215
+ test.result.state = "pass";
216
+ test.result.errors = [];
217
+ debug(`${logPrefix} - Has 'fails' option set - inverted "fail" to "pass"`);
218
+ }
219
+ }
220
+ }
221
+ function setTestResultForTestPrepare(test, startTime) {
222
+ test.result = {
223
+ state: "run",
224
+ startTime,
225
+ retryCount: 0
226
+ };
227
+ }
228
+ function updateTestResultAfterRun(test, testTimings) {
229
+ if (test.result?.state === "run") test.result.state = "pass";
230
+ if (test.result && testTimings) test.result.duration = (test.result.duration ?? 0) + (testTimings.execEnd - testTimings.execStart);
231
+ }
232
+ function flagTestTerminated(test) {
233
+ test.meta.lastTimeoutTerminationTime = Date.now();
234
+ }
235
+ function flagTestFinalized(test) {
236
+ test.meta.resultFinal = true;
237
+ }
238
+ function failTest(test, errorMessage, capturedError, logPrefix) {
239
+ if (test.result) test.result.state = "fail";
240
+ else test.result = { state: "fail" };
241
+ const testError = {
242
+ name: TEST_ERROR_NAMES.WASMRuntimeError,
243
+ message: errorMessage
244
+ };
245
+ const meta = test.meta;
246
+ if (meta.assertionsFailed?.length > 0) {
247
+ testError.name = TEST_ERROR_NAMES.AssertionError;
248
+ const assertion = meta.assertionsFailed[meta.assertionsFailed.length - 1];
249
+ if (assertion.valuesProvided) {
250
+ meta.lastErrorValuesProvided = true;
251
+ testError.expected = assertion.expected !== void 0 ? String(assertion.expected) : void 0;
252
+ testError.actual = assertion.actual !== void 0 ? String(assertion.actual) : void 0;
253
+ }
254
+ }
255
+ meta.lastError = testError;
256
+ meta.lastErrorRawCallStack = extractCallStack(capturedError);
257
+ debug(`${logPrefix} - Captured raw V8 call stack with ${meta.lastErrorRawCallStack.length} frames`);
258
+ }
259
+ function failTestWithTimeoutError(test, startTime, duration) {
260
+ const timeoutErr = createTestTimeoutError(test);
261
+ if (test.result) {
262
+ test.result.state = "fail";
263
+ test.result.startTime = startTime;
264
+ test.result.duration = (test.result.duration ?? 0) + duration;
265
+ if (test.result.errors) test.result.errors.push(timeoutErr);
266
+ else test.result.errors = [timeoutErr];
267
+ } else test.result = {
268
+ state: "fail",
269
+ startTime,
270
+ duration,
271
+ errors: [timeoutErr],
272
+ retryCount: 0
273
+ };
274
+ }
275
+ function setSuitePrepareResult(suite) {
276
+ if (suite.mode === "skip") suite.result = {
277
+ state: "skip",
278
+ duration: 0
279
+ };
280
+ else suite.result = {
281
+ state: "run",
282
+ startTime: Date.now()
283
+ };
284
+ }
285
+ function updateSuiteFinishedResult(suite, logPrefix) {
286
+ if (suite.mode === "skip") suite.result = {
287
+ state: "skip",
288
+ duration: 0
289
+ };
290
+ else {
291
+ const hasFailures = suite.tasks.some(({ result }) => result?.state === "fail");
292
+ if (suite.result) {
293
+ suite.result.duration = positiveSum(suite.tasks, (t) => t.result?.duration);
294
+ suite.result.state = hasFailures ? "fail" : "pass";
295
+ debug(`${logPrefix} - Set suite result: "${suite.result.state}" (hasFailures: ${hasFailures})`);
296
+ }
297
+ }
298
+ }
299
+ function finalizeSuiteResult(suite) {
300
+ suite.meta.resultFinal = true;
301
+ }
302
+ function resetTestForRetry(test, startTime) {
303
+ if (test.result) {
304
+ test.result.state = "run";
305
+ test.result.startTime = startTime;
306
+ }
307
+ const meta = test.meta;
308
+ meta.assertionsPassedCount = 0;
309
+ meta.assertionsFailed = [];
310
+ delete meta.lastError;
311
+ delete meta.lastErrorValuesProvided;
312
+ delete meta.lastErrorRawCallStack;
313
+ delete meta.lastTimeoutTerminationTime;
314
+ delete meta.coverageData;
315
+ }
316
+
317
+ //#endregion
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-BKS7689f.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-tasks-BKS7689f.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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"}