vitest-pool-assemblyscript 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assembly/compare.ts +44 -0
- package/assembly/expect.ts +59 -17
- package/dist/pool-thread/test-worker-thread.mjs +1 -1
- package/dist/pool-thread/v3-tinypool-thread.mjs +1 -1
- package/dist/{test-runner-WF857_Bk.mjs → test-runner-C4I9VknR.mjs} +2 -6
- package/dist/test-runner-C4I9VknR.mjs.map +1 -0
- package/package.json +8 -4
- package/dist/test-runner-WF857_Bk.mjs.map +0 -1
package/assembly/compare.ts
CHANGED
|
@@ -32,6 +32,38 @@ function setEquals<T, U>(actual: T, expected: U): bool {
|
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function arrayBufferEquals<T, U>(actual: T, expected: U): bool {
|
|
36
|
+
if (!(actual instanceof ArrayBuffer) || !(expected instanceof ArrayBuffer)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (actual.byteLength != expected.byteLength) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const actualPtr = changetype<usize>(actual);
|
|
45
|
+
const expectedPtr = changetype<usize>(expected);
|
|
46
|
+
const wordCount: usize = actual.byteLength / 8;
|
|
47
|
+
const remainder: usize = actual.byteLength % 8;
|
|
48
|
+
|
|
49
|
+
// compare 8 bytes at a time (u64 word-sized comparison)
|
|
50
|
+
for (let i: usize = 0; i < wordCount; i++) {
|
|
51
|
+
if (load<u64>(actualPtr + i * 8) != load<u64>(expectedPtr + i * 8)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// compare remaining 0-7 bytes individually
|
|
57
|
+
const remainderOffset = wordCount * 8;
|
|
58
|
+
for (let i: usize = 0; i < remainder; i++) {
|
|
59
|
+
if (load<u8>(actualPtr + remainderOffset + i) != load<u8>(expectedPtr + remainderOffset + i)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
35
67
|
function mapEquals<T, U>(actual: T, expected: U): bool {
|
|
36
68
|
if (actual instanceof Map && expected instanceof Map) {
|
|
37
69
|
if (actual.size != expected.size) {
|
|
@@ -169,6 +201,13 @@ export function closeTo<T, U>(actual: T, expected: U, precision: i32 = 2): bool
|
|
|
169
201
|
return receivedDiff < expectedDiff;
|
|
170
202
|
}
|
|
171
203
|
|
|
204
|
+
if (isVector<T>() || isVector<U>()) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
"Approximate comparison is not supported for " + nameof<T>() + " and " + nameof<U>()
|
|
207
|
+
+ ". Extract lane values and compare them individually with toBeCloseTo()."
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
172
211
|
return false;
|
|
173
212
|
}
|
|
174
213
|
|
|
@@ -215,6 +254,9 @@ export function equals<T, U>(actual: T, expected: U): bool {
|
|
|
215
254
|
if (actual instanceof Map && expected instanceof Map) {
|
|
216
255
|
return mapEquals(actual, expected);
|
|
217
256
|
}
|
|
257
|
+
if (actual instanceof ArrayBuffer && expected instanceof ArrayBuffer) {
|
|
258
|
+
return arrayBufferEquals(actual, expected);
|
|
259
|
+
}
|
|
218
260
|
|
|
219
261
|
if (idof<T>() != idof<U>()) {
|
|
220
262
|
throw new Error("Cannot compare equality between " + nameof<T>(actual)
|
|
@@ -370,6 +412,8 @@ export function isNull<T>(value: T): bool {
|
|
|
370
412
|
} else {
|
|
371
413
|
if (isBoolean<T>()) {
|
|
372
414
|
return false;
|
|
415
|
+
} else if (isVector<T>()) {
|
|
416
|
+
return false;
|
|
373
417
|
} else {
|
|
374
418
|
return nameof<T>(value) == 'usize' && value == 0;
|
|
375
419
|
}
|
package/assembly/expect.ts
CHANGED
|
@@ -96,7 +96,8 @@ abstract class BaseExpectMatcher<T> {
|
|
|
96
96
|
/**
|
|
97
97
|
* Checks that a value is what you expect using identity comparison. Primitives and strings
|
|
98
98
|
* are compared by value, and references are checked for reference equality only (including
|
|
99
|
-
* objects, arrays, etc).
|
|
99
|
+
* objects, arrays, etc). SIMD vectors use WASM's native `==` comparison, which compares at
|
|
100
|
+
* the bit level, ignoring lane type.
|
|
100
101
|
*
|
|
101
102
|
* Cross-type numeric comparisons are allowed where AssemblyScript's own `==` operator
|
|
102
103
|
* permits them (e.g. `f64` vs `i32`). `toBeCloseTo()` is safer for any comparison
|
|
@@ -116,6 +117,9 @@ abstract class BaseExpectMatcher<T> {
|
|
|
116
117
|
* // supported float/integer comparisons (small integer types)
|
|
117
118
|
* expect(f64(42.0)).toBe(i32(42));
|
|
118
119
|
*
|
|
120
|
+
* // SIMD vectors: different lane types with the same underlying bits are identical
|
|
121
|
+
* expect(i64x2(3, 7)).toBe(i32x4(3, 0, 7, 0));
|
|
122
|
+
*
|
|
119
123
|
* // unsupported float/integer comparisons throw an error
|
|
120
124
|
* // expect(f32(42.0)).toBe(i32(42)); // Error: float precision insufficient
|
|
121
125
|
* // expect(f64(42.0)).toBe(i64(42)); // Error: float precision insufficient
|
|
@@ -133,10 +137,15 @@ abstract class BaseExpectMatcher<T> {
|
|
|
133
137
|
*
|
|
134
138
|
* Strings are compared by value equality as with `toBe`. Non-numeric, non-string types return false.
|
|
135
139
|
*
|
|
136
|
-
*
|
|
140
|
+
* SIMD `v128` vectors are not supported, as approximate comparison requires a lane type
|
|
141
|
+
* interpretation to extract numeric values. Extract lane values as needed and compare them individually.
|
|
142
|
+
*
|
|
143
|
+
* @param precision - Specify the number of decimal places that must match for values to be
|
|
137
144
|
* considered close. Defaults to 2 digits, meaning effectively that values must be within 0.005 of
|
|
138
145
|
* each other.
|
|
139
146
|
*
|
|
147
|
+
* @throws When either value is a `v128` vector.
|
|
148
|
+
*
|
|
140
149
|
* @example
|
|
141
150
|
* expect(0.1 + 0.2).toBeCloseTo(0.3);
|
|
142
151
|
* expect(1.005).toBeCloseTo(1.0, 1);
|
|
@@ -153,11 +162,14 @@ abstract class BaseExpectMatcher<T> {
|
|
|
153
162
|
* (more permissive than AS's own `>` operator). Booleans are treated as numeric
|
|
154
163
|
* (true=1, false=0).
|
|
155
164
|
*
|
|
165
|
+
* SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
|
|
166
|
+
* specific lane type interpretation. Extract lane values and compare them individually instead.
|
|
167
|
+
*
|
|
156
168
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
157
169
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
158
170
|
* @throws When comparing nullable strings where either value is null. Use `toBeNull()`
|
|
159
171
|
* to check for null values.
|
|
160
|
-
* @throws When comparing non-string reference types (objects, arrays, etc).
|
|
172
|
+
* @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
|
|
161
173
|
*
|
|
162
174
|
* @example
|
|
163
175
|
* expect(10).toBeGreaterThan(5);
|
|
@@ -179,11 +191,14 @@ abstract class BaseExpectMatcher<T> {
|
|
|
179
191
|
* (more permissive than AS's own `>=` operator). Booleans are treated as numeric
|
|
180
192
|
* (true=1, false=0).
|
|
181
193
|
*
|
|
194
|
+
* SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
|
|
195
|
+
* specific lane type interpretation. Extract lane values and compare them individually instead.
|
|
196
|
+
*
|
|
182
197
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
183
198
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
184
199
|
* @throws When comparing nullable strings where either value is null. Use `toBeNull()`
|
|
185
200
|
* to check for null values.
|
|
186
|
-
* @throws When comparing non-string reference types (objects, arrays, etc).
|
|
201
|
+
* @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
|
|
187
202
|
*
|
|
188
203
|
* @example
|
|
189
204
|
* expect(10).toBeGreaterThanOrEqual(10);
|
|
@@ -204,11 +219,14 @@ abstract class BaseExpectMatcher<T> {
|
|
|
204
219
|
* (more permissive than AS's own `<` operator). Booleans are treated as numeric
|
|
205
220
|
* (true=1, false=0).
|
|
206
221
|
*
|
|
222
|
+
* SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
|
|
223
|
+
* specific lane type interpretation. Extract lane values and compare them individually instead.
|
|
224
|
+
*
|
|
207
225
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
208
226
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
209
227
|
* @throws When comparing nullable strings where either value is null. Use `toBeNull()`
|
|
210
228
|
* to check for null values.
|
|
211
|
-
* @throws When comparing non-string reference types (objects, arrays, etc).
|
|
229
|
+
* @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
|
|
212
230
|
*
|
|
213
231
|
* @example
|
|
214
232
|
* expect(5).toBeLessThan(10);
|
|
@@ -230,11 +248,14 @@ abstract class BaseExpectMatcher<T> {
|
|
|
230
248
|
* (more permissive than AS's own `<=` operator). Booleans are treated as numeric
|
|
231
249
|
* (true=1, false=0).
|
|
232
250
|
*
|
|
251
|
+
* SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
|
|
252
|
+
* specific lane type interpretation. Extract lane values and compare them individually instead.
|
|
253
|
+
*
|
|
233
254
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
234
255
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
235
256
|
* @throws When comparing nullable strings where either value is null. Use `toBeNull()`
|
|
236
257
|
* to check for null values.
|
|
237
|
-
* @throws When comparing non-string reference types (objects, arrays, etc).
|
|
258
|
+
* @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
|
|
238
259
|
*
|
|
239
260
|
* @example
|
|
240
261
|
* expect(5).toBeLessThanOrEqual(5);
|
|
@@ -248,17 +269,22 @@ abstract class BaseExpectMatcher<T> {
|
|
|
248
269
|
}
|
|
249
270
|
|
|
250
271
|
/**
|
|
251
|
-
* Checks that two values have the same value (deep equality).
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* `
|
|
272
|
+
* Checks that two values have the same value (deep equality). Primitives and strings
|
|
273
|
+
* are compared by value. The following reference types are compared with deep equality:
|
|
274
|
+
* - `Array`: element-by-element using `toEqual()` recursively
|
|
275
|
+
* - `ArrayBuffer`: byte-level content comparison
|
|
276
|
+
* - `Set`: membership equality (same elements, order-independent)
|
|
277
|
+
* - `Map`: key-by-key with values compared using `toEqual()`
|
|
278
|
+
*
|
|
279
|
+
* Other object references use `toBe()` rules (reference identity).
|
|
280
|
+
* ⚠️ IMPORTANT: Does not yet support user-defined object deep equality checking.
|
|
256
281
|
*
|
|
257
282
|
* Like `toBe`, cross-type numeric comparisons follow AssemblyScript's own `==` operator
|
|
258
283
|
* restrictions. `toBeCloseTo()` is safer for any comparison involving a float and
|
|
259
284
|
* accurately handles precision-loss edge cases.
|
|
260
|
-
*
|
|
261
|
-
*
|
|
285
|
+
*
|
|
286
|
+
* SIMD vectors use WASM's native `==` comparison, which compares at the bit level,
|
|
287
|
+
* ignoring lane type.
|
|
262
288
|
*
|
|
263
289
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
264
290
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
@@ -267,10 +293,20 @@ abstract class BaseExpectMatcher<T> {
|
|
|
267
293
|
* expect([1, 2, 3]).toEqual([1, 2, 3]);
|
|
268
294
|
* expect(["one", "two", "three"]).toEqual(["one", "two", "three"]);
|
|
269
295
|
*
|
|
270
|
-
* //
|
|
271
|
-
* const a
|
|
272
|
-
* const b
|
|
273
|
-
*
|
|
296
|
+
* // ArrayBuffer byte-level comparison
|
|
297
|
+
* const a = new ArrayBuffer(4);
|
|
298
|
+
* const b = new ArrayBuffer(4);
|
|
299
|
+
* store<u8>(changetype<usize>(a), 0x42);
|
|
300
|
+
* store<u8>(changetype<usize>(b), 66); // 66 decimal == 0x42 hex
|
|
301
|
+
* expect(a).toEqual(b);
|
|
302
|
+
*
|
|
303
|
+
* // SIMD vectors: different lane types with the same underlying bits are equal
|
|
304
|
+
* expect(i64x2(3, 7)).toEqual(i32x4(3, 0, 7, 0));
|
|
305
|
+
*
|
|
306
|
+
* // user-defined objects use reference equality (deep equality not yet supported)
|
|
307
|
+
* const x = new MyObject(1);
|
|
308
|
+
* const y = new MyObject(1); // same data, different reference
|
|
309
|
+
* // expect(x).toEqual(y); // throws — not yet supported
|
|
274
310
|
*/
|
|
275
311
|
toEqual<U>(val: U): void {
|
|
276
312
|
this.assertComparison(equals(this.actual, val), this.actual, val, "to deeply equal", true);
|
|
@@ -293,10 +329,13 @@ abstract class BaseExpectMatcher<T> {
|
|
|
293
329
|
* an object reference, not a primitive. An empty string is still an allocated object
|
|
294
330
|
* with a non-zero address, so it evaluates as truthy.
|
|
295
331
|
*
|
|
332
|
+
* A SIMD `v128` vector with at least one non-zero bit is truthy; an all-zero vector is falsy.
|
|
333
|
+
*
|
|
296
334
|
* @example
|
|
297
335
|
* expect(1).toBeTruthy();
|
|
298
336
|
* expect("hello").toBeTruthy();
|
|
299
337
|
* expect("").toBeTruthy(); // truthy in AS (unlike JS)
|
|
338
|
+
* expect(i32x4.splat(1)).toBeTruthy();
|
|
300
339
|
*/
|
|
301
340
|
toBeTruthy(): void {
|
|
302
341
|
this.assertComparison(truthyOrFalsey(this.actual, true), this.actual, true, "to be truthy", false);
|
|
@@ -309,11 +348,14 @@ abstract class BaseExpectMatcher<T> {
|
|
|
309
348
|
* an object reference, not a primitive. An empty string is still an allocated object
|
|
310
349
|
* with a non-zero address, so it evaluates as truthy.
|
|
311
350
|
*
|
|
351
|
+
* An all-zero SIMD `v128` vector is falsy; a vector with at least one non-zero bit is truthy.
|
|
352
|
+
*
|
|
312
353
|
* @example
|
|
313
354
|
* expect(0).toBeFalsy();
|
|
314
355
|
* expect(NaN).toBeFalsy();
|
|
315
356
|
* expect(null).toBeFalsy();
|
|
316
357
|
* expect("").not.toBeFalsy(); // not falsy in AS (unlike JS)
|
|
358
|
+
* expect(i32x4.splat(0)).toBeFalsy();
|
|
317
359
|
*/
|
|
318
360
|
toBeFalsy(): void {
|
|
319
361
|
this.assertComparison(truthyOrFalsey(this.actual, false), this.actual, false, "to be falsey", false);
|
|
@@ -3,7 +3,7 @@ import { debug, setGlobalDebugMode } from "../debug-Cm1VFmaz.mjs";
|
|
|
3
3
|
import "../vitest-tasks--ow4pacR.mjs";
|
|
4
4
|
import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-imports-B3Iy_K8k.mjs";
|
|
5
5
|
import { isNodeVersionSupportedForCoverage } from "../feature-check-ELxw_Mji.mjs";
|
|
6
|
-
import { runSuite } from "../test-runner-
|
|
6
|
+
import { runSuite } from "../test-runner-C4I9VknR.mjs";
|
|
7
7
|
import { basename } from "node:path";
|
|
8
8
|
import { threadId, workerData } from "node:worker_threads";
|
|
9
9
|
import { highlight } from "@vitest/utils/highlight";
|
|
@@ -6,7 +6,7 @@ import { createRpcClient, loadUserWasmImportsFactory } from "../load-user-import
|
|
|
6
6
|
import { isNodeVersionSupportedForCoverage } from "../feature-check-ELxw_Mji.mjs";
|
|
7
7
|
import "../compiler-CIXpfKq0.mjs";
|
|
8
8
|
import { runCompileAndDiscover } from "../compile-runner-DOMhsLQE.mjs";
|
|
9
|
-
import { runSuite } from "../test-runner-
|
|
9
|
+
import { runSuite } from "../test-runner-C4I9VknR.mjs";
|
|
10
10
|
import { basename } from "node:path";
|
|
11
11
|
import { workerId } from "tinypool";
|
|
12
12
|
import { threadId, workerData } from "node:worker_threads";
|
|
@@ -94,12 +94,8 @@ async function runSuite(rpc, port, base, collectCoverage, compilation, suite, lo
|
|
|
94
94
|
await reportSuitePrepare(rpc, suite, logModule, base);
|
|
95
95
|
suiteMeta.suitePreparedSent = true;
|
|
96
96
|
}
|
|
97
|
-
if (isTimedOutTestInSuite) {
|
|
98
|
-
suiteMeta.coverageData = timedOutTest.suite.meta.coverageData;
|
|
99
|
-
const coverageKeys = Object.keys(suiteMeta.coverageData ?? {}).length;
|
|
100
|
-
debug(`${suiteLogPrefix} - Restored suite coverage data after timeout (${coverageKeys} unique positions)`);
|
|
101
|
-
}
|
|
102
97
|
suiteMeta.coverageData = { hitCountsByFileAndPosition: {} };
|
|
98
|
+
debug(`${suiteLogPrefix} - Initialized empty suite coverage data`);
|
|
103
99
|
let tasksToRun = getRunnableTasks(suite);
|
|
104
100
|
debug(`${suiteLogPrefix} - Runnable tasks:`, tasksToRun.length);
|
|
105
101
|
for (const task of tasksToRun) if (task.type === "suite") {
|
|
@@ -139,4 +135,4 @@ async function runSuite(rpc, port, base, collectCoverage, compilation, suite, lo
|
|
|
139
135
|
|
|
140
136
|
//#endregion
|
|
141
137
|
export { runSuite };
|
|
142
|
-
//# sourceMappingURL=test-runner-
|
|
138
|
+
//# sourceMappingURL=test-runner-C4I9VknR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-runner-C4I9VknR.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 // initialize aggregated coverage data for suite, which gets updated as each subtask completes\n suiteMeta.coverageData = { hitCountsByFileAndPosition: {} };\n debug(`${suiteLogPrefix} - Initialized empty suite coverage data`);\n\n let tasksToRun: Task[] = getRunnableTasks(suite);\n debug(`${suiteLogPrefix} - Runnable tasks:`, tasksToRun.length);\n\n for (const task of tasksToRun) {\n if (task.type === 'suite') {\n const suiteTaskMeta = task.meta as AssemblyScriptSuiteTaskMeta;\n\n await runSuite(\n rpc, port, base, collectCoverage, compilation, task, logModule,\n poolOptions, threadImports, vitestVersion, bail, diffOptions, timedOutTest\n );\n\n // merge suite task coverage into parent suite coverage\n if (suiteMeta.coverageData && suiteTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, suiteTaskMeta.coverageData);\n }\n \n } else {\n const testLogPrefix = getTaskLogPrefix(logModule, base, task);\n const testTaskMeta = task.meta as AssemblyScriptTestTaskMeta;\n\n const testCompleted = testTaskMeta.resultFinal;\n const testTimedOutPreviously = !!timedOutTest && task.id === timedOutTest.id;\n\n if (testCompleted) {\n debug(`${testLogPrefix} - Skipping completed test | state: \"${task.result?.state}\"`);\n } else if (testTimedOutPreviously) {\n if (shouldRetryTask(task)) {\n const previousRetryCount = task.result?.retryCount ?? 0;\n const newRetryCount = previousRetryCount + 1;\n\n debug(`${testLogPrefix} - Retrying after test timeout`\n + ` | retry attempt ${newRetryCount} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n \n // report retried for the previous timeout failure, which won't\n // have been reported because the thread was killed to timeout\n await reportTestRetried(rpc, task, logModule, base);\n\n // increment the retry count (after reporting retried)\n task.result!.retryCount = newRetryCount;\n \n // retry timed out test\n // - if it passes, process as normal\n // - if it fails again, it will end up in the else block below\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n } else {\n debug(`${testLogPrefix} - Timed-out test has no retries left`\n + ` | retries attempted ${task.result?.retryCount || 0} / ${task.retry} ` \n + ` | ${task.result?.errors?.length ?? 0} errors`\n + ` | state: \"${task.result?.state}\"`\n );\n\n await Promise.all([\n // as needed: invert if `fails`, bail\n postProcessTestResult(rpc, bail, task, testLogPrefix, logModule),\n \n reportTestFinished(rpc, task, logModule, base),\n ]);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n flagTestFinalized(task);\n\n debug(`${testLogPrefix} - Completed timed out test run`);\n }\n } else {\n debug(`${testLogPrefix} - Running test task | state: \"${task.result?.state}\"`);\n await runTest(\n rpc, port, base, collectCoverage, compilation,\n task, logModule, poolOptions, threadImports, bail, diffOptions\n );\n }\n\n // merge test coverage into suite coverage\n if (suiteMeta.coverageData && testTaskMeta.coverageData) {\n mergeCoverageData(suiteMeta.coverageData, testTaskMeta.coverageData);\n }\n }\n }\n\n // update suite result based on its tasks, report coverage data, report suite task result\n updateSuiteFinishedResult(suite, suiteLogPrefix);\n await reportSuiteFinished(rpc, suite, logModule, base, vitestVersion);\n\n // ensure completed test will not be run again if another test\n // times out later and the file worker thread gets re-launched\n finalizeSuiteResult(suite);\n\n const suiteTime = performance.now() - suiteStart;\n debug(`${suiteLogPrefix} - Suite Run Complete | TIMING ${suiteTime.toFixed(2)} ms`);\n\n return suite;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-pool-assemblyscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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",
|
|
@@ -82,23 +82,27 @@
|
|
|
82
82
|
"//---- install pool externally and run our tests from there ----": "",
|
|
83
83
|
"test:ext:setup": "node scripts/setup-test-external.js",
|
|
84
84
|
"test:ext:setup:v3": "cross-env VITEST_VERSION=3 node scripts/setup-test-external.js",
|
|
85
|
-
"test:ext:pass": "node scripts/run-vitest.js -c vitest.pass.config.ts",
|
|
86
|
-
"test:ext:pass:no-cov": "node scripts/run-vitest.js -c vitest.pass.config.ts --coverage.enabled=false",
|
|
87
|
-
"test:ext:meta": "node scripts/run-vitest.js -c vitest.meta.config.ts",
|
|
85
|
+
"test:ext:pass": "node scripts/run-vitest-external.js -c vitest.pass.config.ts",
|
|
86
|
+
"test:ext:pass:no-cov": "node scripts/run-vitest-external.js -c vitest.pass.config.ts --coverage.enabled=false",
|
|
87
|
+
"test:ext:meta": "node scripts/run-vitest-external.js -c vitest.meta.config.ts",
|
|
88
88
|
"test:ext:meta:verify": "cross-env RUN_CONTEXT=external vitest run -c vitest.meta-verify.config.ts",
|
|
89
89
|
"test:ext:meta:verify:no-cov": "cross-env RUN_CONTEXT=external_no_coverage vitest run -c vitest.meta-verify.config.ts",
|
|
90
90
|
"//---- test shortcuts ----": "",
|
|
91
91
|
"ptest": "npm run test:pass",
|
|
92
92
|
"mtest": "npm run test:meta",
|
|
93
93
|
"mvtest": "npm run test:meta:verify",
|
|
94
|
+
"atest": "npm run ptest && npm run mvtest",
|
|
94
95
|
"//---- external test shortcuts ----": "",
|
|
95
96
|
"eptest": "npm run test:ext:setup && npm run test:ext:pass",
|
|
96
97
|
"emtest": "npm run test:ext:setup && npm run test:ext:meta",
|
|
97
98
|
"emvtest": "npm run test:ext:setup && npm run test:ext:meta:verify",
|
|
99
|
+
"aetest": "npm run eptest && npm run test:ext:meta:verify",
|
|
98
100
|
"//---- external v3 test shortcuts ----": "",
|
|
99
101
|
"ep3test": "npm run test:ext:setup:v3 && npm run test:ext:pass",
|
|
100
102
|
"em3test": "npm run test:ext:setup:v3 && npm run test:ext:meta",
|
|
101
103
|
"emv3test": "npm run test:ext:setup:v3 && npm run test:ext:meta:verify",
|
|
104
|
+
"ae3test": "npm run ep3test && npm run test:ext:meta:verify",
|
|
105
|
+
"eetest": "npm run aetest && npm run ae3test",
|
|
102
106
|
"//---- compile & test shortcuts ----": "",
|
|
103
107
|
"tcptest": "npm run tc && npm run build && npm run ptest",
|
|
104
108
|
"cptest": "npm run build && npm run ptest",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-runner-WF857_Bk.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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"}
|