as-test 1.1.10 → 1.3.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/CHANGELOG.md +48 -0
- package/as-test.config.schema.json +15 -0
- package/assembly/coverage.ts +22 -26
- package/assembly/index.ts +2 -0
- package/assembly/src/expectation.ts +152 -44
- package/assembly/src/mode.ts +55 -0
- package/bin/commands/build-core.js +190 -65
- package/bin/commands/build.js +3 -1
- package/bin/commands/fuzz-core.js +30 -56
- package/bin/commands/init-core.js +253 -5
- package/bin/commands/run-core.js +38 -119
- package/bin/commands/test.js +1 -1
- package/bin/commands/web-session.js +4 -0
- package/bin/crash-store.js +1 -1
- package/bin/index.js +94 -152
- package/bin/types.js +7 -0
- package/bin/util.js +117 -0
- package/package.json +14 -9
- package/transform/lib/index.js +26 -0
package/bin/index.js
CHANGED
|
@@ -3,8 +3,10 @@ import chalk from "chalk";
|
|
|
3
3
|
import {
|
|
4
4
|
build,
|
|
5
5
|
BuildFailureError,
|
|
6
|
+
flushModeWarnings,
|
|
6
7
|
formatInvocation as formatBuildInvocation,
|
|
7
8
|
getBuildInvocationPreview,
|
|
9
|
+
warnOnUnknownModeReferences,
|
|
8
10
|
} from "./commands/build.js";
|
|
9
11
|
import { createRunReporter, run } from "./commands/run.js";
|
|
10
12
|
import { executeBuildCommand } from "./commands/build.js";
|
|
@@ -22,8 +24,11 @@ import {
|
|
|
22
24
|
getDefaultModeNames,
|
|
23
25
|
getCliVersion,
|
|
24
26
|
loadConfig,
|
|
27
|
+
resolveArtifactPath,
|
|
25
28
|
resolveModeNames,
|
|
29
|
+
resolveSpecRelativePath,
|
|
26
30
|
} from "./util.js";
|
|
31
|
+
import { normalizeFeatureName } from "./types.js";
|
|
27
32
|
import * as path from "path";
|
|
28
33
|
import { spawnSync } from "child_process";
|
|
29
34
|
import { glob } from "glob";
|
|
@@ -287,10 +292,10 @@ function printCommandHelp(command) {
|
|
|
287
292
|
" --mode <name[,name...]> Run one or multiple named config modes\n",
|
|
288
293
|
);
|
|
289
294
|
process.stdout.write(
|
|
290
|
-
" --enable <
|
|
295
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
291
296
|
);
|
|
292
297
|
process.stdout.write(
|
|
293
|
-
" --disable <
|
|
298
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
294
299
|
);
|
|
295
300
|
process.stdout.write(
|
|
296
301
|
" --parallel Run files through an ordered worker pool using an automatic worker count\n",
|
|
@@ -354,10 +359,10 @@ function printCommandHelp(command) {
|
|
|
354
359
|
);
|
|
355
360
|
process.stdout.write(" --suites <name[,name...]> Alias for --suite\n");
|
|
356
361
|
process.stdout.write(
|
|
357
|
-
" --enable <
|
|
362
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
358
363
|
);
|
|
359
364
|
process.stdout.write(
|
|
360
|
-
" --disable <
|
|
365
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
361
366
|
);
|
|
362
367
|
process.stdout.write(
|
|
363
368
|
" --reporter <name|path> Use built-in reporter (default|tap) or custom module path\n",
|
|
@@ -426,10 +431,10 @@ function printCommandHelp(command) {
|
|
|
426
431
|
);
|
|
427
432
|
process.stdout.write(" --suites <name[,name...]> Alias for --suite\n");
|
|
428
433
|
process.stdout.write(
|
|
429
|
-
" --enable <
|
|
434
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
430
435
|
);
|
|
431
436
|
process.stdout.write(
|
|
432
|
-
" --disable <
|
|
437
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
433
438
|
);
|
|
434
439
|
process.stdout.write(
|
|
435
440
|
" --fuzz Run fuzz targets after the normal test pass\n",
|
|
@@ -532,6 +537,12 @@ function printCommandHelp(command) {
|
|
|
532
537
|
process.stdout.write(
|
|
533
538
|
" --example <minimal|full|none> Set example template\n",
|
|
534
539
|
);
|
|
540
|
+
process.stdout.write(
|
|
541
|
+
" --enable <list> Enable features, comma-separated (coverage,try-as)\n",
|
|
542
|
+
);
|
|
543
|
+
process.stdout.write(
|
|
544
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
545
|
+
);
|
|
535
546
|
process.stdout.write(
|
|
536
547
|
" --install Install dependencies after scaffolding\n",
|
|
537
548
|
);
|
|
@@ -707,8 +718,9 @@ function resolveCommandArgs(rawArgs, command) {
|
|
|
707
718
|
return values;
|
|
708
719
|
}
|
|
709
720
|
function resolveFeatureToggles(rawArgs, command) {
|
|
710
|
-
if (command !== "build" && command !== "run" && command !== "test")
|
|
711
|
-
|
|
721
|
+
if (command !== "build" && command !== "run" && command !== "test")
|
|
722
|
+
return { featureOverrides: {} };
|
|
723
|
+
const out = { featureOverrides: {} };
|
|
712
724
|
let seenCommand = false;
|
|
713
725
|
for (let i = 0; i < rawArgs.length; i++) {
|
|
714
726
|
const arg = rawArgs[i];
|
|
@@ -720,7 +732,9 @@ function resolveFeatureToggles(rawArgs, command) {
|
|
|
720
732
|
const enabled = arg == "--enable";
|
|
721
733
|
const next = rawArgs[i + 1];
|
|
722
734
|
if (next && !next.startsWith("-")) {
|
|
723
|
-
|
|
735
|
+
for (const name of splitFeatureList(next)) {
|
|
736
|
+
applyFeatureToggle(out, name, enabled);
|
|
737
|
+
}
|
|
724
738
|
i++;
|
|
725
739
|
}
|
|
726
740
|
continue;
|
|
@@ -728,9 +742,9 @@ function resolveFeatureToggles(rawArgs, command) {
|
|
|
728
742
|
if (arg.startsWith("--enable=") || arg.startsWith("--disable=")) {
|
|
729
743
|
const enabled = arg.startsWith("--enable=");
|
|
730
744
|
const eq = arg.indexOf("=");
|
|
731
|
-
const value = arg.slice(eq + 1)
|
|
732
|
-
|
|
733
|
-
applyFeatureToggle(out,
|
|
745
|
+
const value = arg.slice(eq + 1);
|
|
746
|
+
for (const name of splitFeatureList(value)) {
|
|
747
|
+
applyFeatureToggle(out, name, enabled);
|
|
734
748
|
}
|
|
735
749
|
}
|
|
736
750
|
}
|
|
@@ -1278,19 +1292,24 @@ function parseIntegerFlag(flag, value) {
|
|
|
1278
1292
|
}
|
|
1279
1293
|
return Math.floor(parsed);
|
|
1280
1294
|
}
|
|
1295
|
+
function splitFeatureList(value) {
|
|
1296
|
+
return value
|
|
1297
|
+
.split(",")
|
|
1298
|
+
.map((part) => part.trim())
|
|
1299
|
+
.filter((part) => part.length > 0);
|
|
1300
|
+
}
|
|
1281
1301
|
function applyFeatureToggle(out, rawFeature, enabled) {
|
|
1282
|
-
const key = rawFeature
|
|
1302
|
+
const key = normalizeFeatureName(rawFeature);
|
|
1303
|
+
if (!key.length) {
|
|
1304
|
+
throw new Error(
|
|
1305
|
+
`empty feature name passed to ${enabled ? "--enable" : "--disable"}`,
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1283
1308
|
if (key == "coverage") {
|
|
1284
1309
|
out.coverage = enabled;
|
|
1285
1310
|
return;
|
|
1286
1311
|
}
|
|
1287
|
-
|
|
1288
|
-
out.tryAs = enabled;
|
|
1289
|
-
return;
|
|
1290
|
-
}
|
|
1291
|
-
throw new Error(
|
|
1292
|
-
`unknown feature "${rawFeature}". Supported features: coverage, try-as`,
|
|
1293
|
-
);
|
|
1312
|
+
out.featureOverrides[key] = enabled;
|
|
1294
1313
|
}
|
|
1295
1314
|
function resolveCommandTokens(rawArgs, command) {
|
|
1296
1315
|
const values = [];
|
|
@@ -1366,8 +1385,7 @@ async function runTestSequential(
|
|
|
1366
1385
|
const results = [];
|
|
1367
1386
|
let failed = false;
|
|
1368
1387
|
const buildIntervals = [];
|
|
1369
|
-
const
|
|
1370
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
1388
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
1371
1389
|
for (const file of files) {
|
|
1372
1390
|
const buildStartedAt = Date.now();
|
|
1373
1391
|
let result;
|
|
@@ -1380,10 +1398,7 @@ async function runTestSequential(
|
|
|
1380
1398
|
modeName,
|
|
1381
1399
|
buildFeatureToggles,
|
|
1382
1400
|
);
|
|
1383
|
-
const artifactKey =
|
|
1384
|
-
file,
|
|
1385
|
-
duplicateSpecBasenames,
|
|
1386
|
-
);
|
|
1401
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
1387
1402
|
result = await run(runFlags, configPath, [file], false, {
|
|
1388
1403
|
reporter,
|
|
1389
1404
|
webSession,
|
|
@@ -1391,7 +1406,7 @@ async function runTestSequential(
|
|
|
1391
1406
|
emitRunStart: false,
|
|
1392
1407
|
emitRunComplete: false,
|
|
1393
1408
|
logFileName: `test.${artifactKey}.log.json`,
|
|
1394
|
-
coverageFileName:
|
|
1409
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
1395
1410
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1396
1411
|
modeName,
|
|
1397
1412
|
});
|
|
@@ -1427,6 +1442,7 @@ async function runTestSequential(
|
|
|
1427
1442
|
),
|
|
1428
1443
|
});
|
|
1429
1444
|
reporter.flush?.();
|
|
1445
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
1430
1446
|
}
|
|
1431
1447
|
return {
|
|
1432
1448
|
failed,
|
|
@@ -1645,8 +1661,7 @@ async function runRuntimeMatrix(
|
|
|
1645
1661
|
failed: false,
|
|
1646
1662
|
passed: false,
|
|
1647
1663
|
}));
|
|
1648
|
-
const
|
|
1649
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
1664
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
1650
1665
|
const buildIntervals = [];
|
|
1651
1666
|
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
1652
1667
|
const file = files[fileIndex];
|
|
@@ -1665,10 +1680,7 @@ async function runRuntimeMatrix(
|
|
|
1665
1680
|
modeName,
|
|
1666
1681
|
{},
|
|
1667
1682
|
);
|
|
1668
|
-
const artifactKey =
|
|
1669
|
-
file,
|
|
1670
|
-
duplicateSpecBasenames,
|
|
1671
|
-
);
|
|
1683
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
1672
1684
|
const result = await run(runFlags, configPath, [file], false, {
|
|
1673
1685
|
reporter: silentReporter,
|
|
1674
1686
|
reporterKind: "default",
|
|
@@ -1676,7 +1688,7 @@ async function runRuntimeMatrix(
|
|
|
1676
1688
|
emitRunStart: false,
|
|
1677
1689
|
emitRunComplete: false,
|
|
1678
1690
|
logFileName: `run.${artifactKey}.log.json`,
|
|
1679
|
-
coverageFileName:
|
|
1691
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
1680
1692
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
1681
1693
|
modeName,
|
|
1682
1694
|
});
|
|
@@ -1880,6 +1892,7 @@ async function runTestModesCore(
|
|
|
1880
1892
|
),
|
|
1881
1893
|
});
|
|
1882
1894
|
reporterSession.reporter.flush?.();
|
|
1895
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
1883
1896
|
}
|
|
1884
1897
|
}
|
|
1885
1898
|
} finally {
|
|
@@ -2069,6 +2082,14 @@ async function runTestMatrix(
|
|
|
2069
2082
|
fuzzOverrides,
|
|
2070
2083
|
) {
|
|
2071
2084
|
const files = await resolveSelectedFiles(configPath, selectors);
|
|
2085
|
+
if (files.length && configPath) {
|
|
2086
|
+
try {
|
|
2087
|
+
const loaded = loadConfig(configPath, false);
|
|
2088
|
+
warnOnUnknownModeReferences(files, loaded.modes ?? {});
|
|
2089
|
+
} catch {
|
|
2090
|
+
// Best-effort: never fail the run on a scan error.
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2072
2093
|
if (!files.length) {
|
|
2073
2094
|
if (!fuzzEnabled) {
|
|
2074
2095
|
throw await buildNoTestFilesMatchedError(configPath, selectors);
|
|
@@ -2106,8 +2127,7 @@ async function runTestMatrix(
|
|
|
2106
2127
|
failed: false,
|
|
2107
2128
|
passed: false,
|
|
2108
2129
|
}));
|
|
2109
|
-
const
|
|
2110
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
2130
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
2111
2131
|
const buildIntervals = [];
|
|
2112
2132
|
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
2113
2133
|
const file = files[fileIndex];
|
|
@@ -2135,17 +2155,14 @@ async function runTestMatrix(
|
|
|
2135
2155
|
modeName,
|
|
2136
2156
|
buildFeatureToggles,
|
|
2137
2157
|
);
|
|
2138
|
-
const artifactKey =
|
|
2139
|
-
file,
|
|
2140
|
-
duplicateSpecBasenames,
|
|
2141
|
-
);
|
|
2158
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
2142
2159
|
result = await run(runFlags, configPath, [file], false, {
|
|
2143
2160
|
reporter: silentReporter,
|
|
2144
2161
|
reporterKind: "default",
|
|
2145
2162
|
emitRunStart: false,
|
|
2146
2163
|
emitRunComplete: false,
|
|
2147
2164
|
logFileName: `test.${artifactKey}.log.json`,
|
|
2148
|
-
coverageFileName:
|
|
2165
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
2149
2166
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
2150
2167
|
modeName,
|
|
2151
2168
|
});
|
|
@@ -2225,6 +2242,7 @@ async function runTestMatrix(
|
|
|
2225
2242
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2226
2243
|
});
|
|
2227
2244
|
reporter.flush?.();
|
|
2245
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2228
2246
|
return failed;
|
|
2229
2247
|
}
|
|
2230
2248
|
async function runFuzzModes(
|
|
@@ -2382,6 +2400,7 @@ async function runRuntimeSingleParallel(
|
|
|
2382
2400
|
),
|
|
2383
2401
|
});
|
|
2384
2402
|
reporter.flush?.();
|
|
2403
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2385
2404
|
return results.some((result) => result.failed);
|
|
2386
2405
|
}
|
|
2387
2406
|
async function runRuntimeMatrixParallel(
|
|
@@ -2413,8 +2432,7 @@ async function runRuntimeMatrixParallel(
|
|
|
2413
2432
|
const silentReporter = {};
|
|
2414
2433
|
const modeLabels = modes.map((modeName) => modeName ?? "default");
|
|
2415
2434
|
const showPerModeTimes = Boolean(runFlags.verbose);
|
|
2416
|
-
const
|
|
2417
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
2435
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
2418
2436
|
const ordered = new Array(files.length);
|
|
2419
2437
|
const useQueueDisplay = reporterSession.reporterKind == "default";
|
|
2420
2438
|
const queueDisplay = new ParallelQueueDisplay(
|
|
@@ -2454,10 +2472,7 @@ async function runRuntimeMatrixParallel(
|
|
|
2454
2472
|
modeName,
|
|
2455
2473
|
{},
|
|
2456
2474
|
);
|
|
2457
|
-
const artifactKey =
|
|
2458
|
-
file,
|
|
2459
|
-
duplicateSpecBasenames,
|
|
2460
|
-
);
|
|
2475
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
2461
2476
|
result = await run(runFlags, configPath, [file], false, {
|
|
2462
2477
|
reporter: silentReporter,
|
|
2463
2478
|
reporterKind: "default",
|
|
@@ -2465,7 +2480,7 @@ async function runRuntimeMatrixParallel(
|
|
|
2465
2480
|
emitRunStart: false,
|
|
2466
2481
|
emitRunComplete: false,
|
|
2467
2482
|
logFileName: `run.${artifactKey}.log.json`,
|
|
2468
|
-
coverageFileName:
|
|
2483
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
2469
2484
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
2470
2485
|
modeName,
|
|
2471
2486
|
});
|
|
@@ -2530,6 +2545,7 @@ async function runRuntimeMatrixParallel(
|
|
|
2530
2545
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2531
2546
|
});
|
|
2532
2547
|
reporter.flush?.();
|
|
2548
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2533
2549
|
return allResults.some((result) => result.failed);
|
|
2534
2550
|
}
|
|
2535
2551
|
async function runTestSingleParallel(
|
|
@@ -2563,8 +2579,7 @@ async function runTestSingleParallel(
|
|
|
2563
2579
|
snapshotEnabled,
|
|
2564
2580
|
createSnapshots: runFlags.createSnapshots,
|
|
2565
2581
|
});
|
|
2566
|
-
const
|
|
2567
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
2582
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
2568
2583
|
const results = new Array(files.length);
|
|
2569
2584
|
const useQueueDisplay = reporterSession.reporterKind == "default";
|
|
2570
2585
|
const queueDisplay = new ParallelQueueDisplay(
|
|
@@ -2607,10 +2622,7 @@ async function runTestSingleParallel(
|
|
|
2607
2622
|
modeName,
|
|
2608
2623
|
buildFeatureToggles,
|
|
2609
2624
|
);
|
|
2610
|
-
const artifactKey =
|
|
2611
|
-
file,
|
|
2612
|
-
duplicateSpecBasenames,
|
|
2613
|
-
);
|
|
2625
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
2614
2626
|
result = await run(
|
|
2615
2627
|
{ ...runFlags, clean: true },
|
|
2616
2628
|
configPath,
|
|
@@ -2622,7 +2634,7 @@ async function runTestSingleParallel(
|
|
|
2622
2634
|
suiteSelectors,
|
|
2623
2635
|
emitRunComplete: false,
|
|
2624
2636
|
logFileName: `test.${artifactKey}.log.json`,
|
|
2625
|
-
coverageFileName:
|
|
2637
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
2626
2638
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
2627
2639
|
modeName,
|
|
2628
2640
|
},
|
|
@@ -2689,6 +2701,7 @@ async function runTestSingleParallel(
|
|
|
2689
2701
|
),
|
|
2690
2702
|
});
|
|
2691
2703
|
reporter.flush?.();
|
|
2704
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2692
2705
|
return failed;
|
|
2693
2706
|
}
|
|
2694
2707
|
async function runTestMatrixParallel(
|
|
@@ -2705,6 +2718,14 @@ async function runTestMatrixParallel(
|
|
|
2705
2718
|
fuzzOverrides,
|
|
2706
2719
|
) {
|
|
2707
2720
|
const files = await resolveSelectedFiles(configPath, selectors);
|
|
2721
|
+
if (files.length && configPath) {
|
|
2722
|
+
try {
|
|
2723
|
+
const loaded = loadConfig(configPath, false);
|
|
2724
|
+
warnOnUnknownModeReferences(files, loaded.modes ?? {});
|
|
2725
|
+
} catch {
|
|
2726
|
+
// Best-effort: never fail the run on a scan error.
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2708
2729
|
if (!files.length) {
|
|
2709
2730
|
if (!fuzzEnabled) {
|
|
2710
2731
|
throw await buildNoTestFilesMatchedError(configPath, selectors);
|
|
@@ -2734,8 +2755,7 @@ async function runTestMatrixParallel(
|
|
|
2734
2755
|
const silentReporter = {};
|
|
2735
2756
|
const modeLabels = modes.map((modeName) => modeName ?? "default");
|
|
2736
2757
|
const showPerModeTimes = Boolean(runFlags.verbose);
|
|
2737
|
-
const
|
|
2738
|
-
await resolveAllConfiguredDuplicateSpecBasenames(configPath);
|
|
2758
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
2739
2759
|
const ordered = new Array(files.length);
|
|
2740
2760
|
const useQueueDisplay = reporterSession.reporterKind == "default";
|
|
2741
2761
|
const queueDisplay = new ParallelQueueDisplay(
|
|
@@ -2775,10 +2795,7 @@ async function runTestMatrixParallel(
|
|
|
2775
2795
|
modeName,
|
|
2776
2796
|
buildFeatureToggles,
|
|
2777
2797
|
);
|
|
2778
|
-
const artifactKey =
|
|
2779
|
-
file,
|
|
2780
|
-
duplicateSpecBasenames,
|
|
2781
|
-
);
|
|
2798
|
+
const artifactKey = resolveArtifactStem(file, inputPatterns);
|
|
2782
2799
|
result = await run(runFlags, configPath, [file], false, {
|
|
2783
2800
|
reporter: silentReporter,
|
|
2784
2801
|
reporterKind: "default",
|
|
@@ -2786,7 +2803,7 @@ async function runTestMatrixParallel(
|
|
|
2786
2803
|
emitRunStart: false,
|
|
2787
2804
|
emitRunComplete: false,
|
|
2788
2805
|
logFileName: `test.${artifactKey}.log.json`,
|
|
2789
|
-
coverageFileName:
|
|
2806
|
+
coverageFileName: `${artifactKey}.log.json`,
|
|
2790
2807
|
buildCommand: formatBuildInvocation(buildInvocation),
|
|
2791
2808
|
modeName,
|
|
2792
2809
|
});
|
|
@@ -2873,6 +2890,7 @@ async function runTestMatrixParallel(
|
|
|
2873
2890
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2874
2891
|
});
|
|
2875
2892
|
reporter.flush?.();
|
|
2893
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2876
2894
|
return failed;
|
|
2877
2895
|
}
|
|
2878
2896
|
async function runFuzzMatrixResultsParallel(
|
|
@@ -3601,80 +3619,21 @@ function isBareSuiteSelector(selector) {
|
|
|
3601
3619
|
function stripSuiteSuffix(selector) {
|
|
3602
3620
|
return selector.replace(/\.spec\.ts$/, "").replace(/\.ts$/, "");
|
|
3603
3621
|
}
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
}
|
|
3610
|
-
const duplicates = new Set();
|
|
3611
|
-
for (const [base, count] of counts) {
|
|
3612
|
-
if (count > 1) duplicates.add(base);
|
|
3613
|
-
}
|
|
3614
|
-
return duplicates;
|
|
3622
|
+
// Returns the spec relative path (under the configured input base) with the
|
|
3623
|
+
// trailing ".ts" stripped, suitable for use as a stable per-file key for
|
|
3624
|
+
// coverage and log filenames.
|
|
3625
|
+
function resolveArtifactStem(file, inputPatterns) {
|
|
3626
|
+
return resolveSpecRelativePath(file, inputPatterns).replace(/\.ts$/i, "");
|
|
3615
3627
|
}
|
|
3616
|
-
|
|
3617
|
-
// selector-filtered subset, otherwise running a single spec writes/looks up an
|
|
3618
|
-
// artifact name that the rest of the toolchain doesn't agree on.
|
|
3619
|
-
async function resolveAllConfiguredDuplicateSpecBasenames(configPath) {
|
|
3628
|
+
async function loadInputPatterns(configPath) {
|
|
3620
3629
|
const resolvedConfigPath =
|
|
3621
3630
|
configPath ?? path.join(process.cwd(), "./as-test.config.json");
|
|
3622
|
-
|
|
3623
|
-
return resolveDuplicateBasenamesForPatterns(config.input);
|
|
3631
|
+
return loadConfig(resolvedConfigPath, false).input;
|
|
3624
3632
|
}
|
|
3625
|
-
async function
|
|
3633
|
+
async function loadFuzzInputPatterns(configPath) {
|
|
3626
3634
|
const resolvedConfigPath =
|
|
3627
3635
|
configPath ?? path.join(process.cwd(), "./as-test.config.json");
|
|
3628
|
-
|
|
3629
|
-
return resolveDuplicateBasenamesForPatterns(config.fuzz.input);
|
|
3630
|
-
}
|
|
3631
|
-
async function resolveDuplicateBasenamesForPatterns(configured) {
|
|
3632
|
-
const patterns = Array.isArray(configured) ? configured : [configured];
|
|
3633
|
-
const files = await glob(patterns);
|
|
3634
|
-
return resolveDuplicateSpecBasenames(files);
|
|
3635
|
-
}
|
|
3636
|
-
function resolvePerFileArtifactKey(file, duplicateSpecBasenames) {
|
|
3637
|
-
const base = path.basename(file);
|
|
3638
|
-
let raw = base;
|
|
3639
|
-
if (duplicateSpecBasenames.has(base)) {
|
|
3640
|
-
const disambiguator = resolvePerFileDisambiguator(file);
|
|
3641
|
-
if (disambiguator.length) {
|
|
3642
|
-
raw = `${base}.${disambiguator}`;
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
return raw.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
3646
|
-
}
|
|
3647
|
-
function resolvePerFileDisambiguator(file) {
|
|
3648
|
-
const relDir = path.dirname(path.relative(process.cwd(), file));
|
|
3649
|
-
if (!relDir.length || relDir == ".") return "";
|
|
3650
|
-
return relDir
|
|
3651
|
-
.replace(/[\\/]+/g, "__")
|
|
3652
|
-
.replace(/[^A-Za-z0-9._-]/g, "_")
|
|
3653
|
-
.replace(/^_+|_+$/g, "");
|
|
3654
|
-
}
|
|
3655
|
-
function resolveArtifactFileNameForPreview(
|
|
3656
|
-
file,
|
|
3657
|
-
target,
|
|
3658
|
-
modeName,
|
|
3659
|
-
duplicateSpecBasenames,
|
|
3660
|
-
) {
|
|
3661
|
-
const base = path
|
|
3662
|
-
.basename(file)
|
|
3663
|
-
.replace(/\.spec\.ts$/, "")
|
|
3664
|
-
.replace(/\.ts$/, "");
|
|
3665
|
-
const legacy = !modeName
|
|
3666
|
-
? `${path.basename(file).replace(".ts", ".wasm")}`
|
|
3667
|
-
: `${base}.${modeName}.${target}.wasm`;
|
|
3668
|
-
if (!duplicateSpecBasenames.has(path.basename(file))) {
|
|
3669
|
-
return legacy;
|
|
3670
|
-
}
|
|
3671
|
-
const disambiguator = resolvePerFileDisambiguator(file);
|
|
3672
|
-
if (!disambiguator.length) {
|
|
3673
|
-
return legacy;
|
|
3674
|
-
}
|
|
3675
|
-
const ext = path.extname(legacy);
|
|
3676
|
-
const stem = ext.length ? legacy.slice(0, -ext.length) : legacy;
|
|
3677
|
-
return `${stem}.${disambiguator}${ext}`;
|
|
3636
|
+
return loadConfig(resolvedConfigPath, false).fuzz.input;
|
|
3678
3637
|
}
|
|
3679
3638
|
async function ensureWebBrowsersReady(configPath, modes, browserOverride) {
|
|
3680
3639
|
const resolvedConfigPath =
|
|
@@ -4201,10 +4160,8 @@ async function listExecutionPlan(
|
|
|
4201
4160
|
: `No test files matched: ${scope}`,
|
|
4202
4161
|
);
|
|
4203
4162
|
}
|
|
4204
|
-
const
|
|
4205
|
-
|
|
4206
|
-
const duplicateFuzzBasenames =
|
|
4207
|
-
await resolveAllConfiguredDuplicateFuzzBasenames(configPath);
|
|
4163
|
+
const inputPatterns = await loadInputPatterns(configPath);
|
|
4164
|
+
const fuzzInputPatterns = await loadFuzzInputPatterns(configPath);
|
|
4208
4165
|
if (specFiles.length) {
|
|
4209
4166
|
process.stdout.write(chalk.bold("Resolved files:\n"));
|
|
4210
4167
|
for (const file of specFiles) {
|
|
@@ -4258,12 +4215,7 @@ async function listExecutionPlan(
|
|
|
4258
4215
|
if (specFiles.length) {
|
|
4259
4216
|
process.stdout.write(" artifacts:\n");
|
|
4260
4217
|
for (const file of specFiles) {
|
|
4261
|
-
const artifactName =
|
|
4262
|
-
file,
|
|
4263
|
-
active.buildOptions.target,
|
|
4264
|
-
modeName,
|
|
4265
|
-
duplicateSpecBasenames,
|
|
4266
|
-
);
|
|
4218
|
+
const artifactName = resolveArtifactPath(file, inputPatterns);
|
|
4267
4219
|
process.stdout.write(
|
|
4268
4220
|
` - ${path.join(active.outDir, artifactName)}\n`,
|
|
4269
4221
|
);
|
|
@@ -4272,12 +4224,7 @@ async function listExecutionPlan(
|
|
|
4272
4224
|
if (fuzzFiles.length && command == "test") {
|
|
4273
4225
|
process.stdout.write(" fuzz artifacts:\n");
|
|
4274
4226
|
for (const file of fuzzFiles) {
|
|
4275
|
-
const artifactName =
|
|
4276
|
-
file,
|
|
4277
|
-
"bindings",
|
|
4278
|
-
modeName,
|
|
4279
|
-
duplicateFuzzBasenames,
|
|
4280
|
-
);
|
|
4227
|
+
const artifactName = resolveArtifactPath(file, fuzzInputPatterns);
|
|
4281
4228
|
process.stdout.write(
|
|
4282
4229
|
` - ${path.join(active.outDir, artifactName)}\n`,
|
|
4283
4230
|
);
|
|
@@ -4285,12 +4232,7 @@ async function listExecutionPlan(
|
|
|
4285
4232
|
} else if (command == "fuzz") {
|
|
4286
4233
|
process.stdout.write(" artifacts:\n");
|
|
4287
4234
|
for (const file of fuzzFiles) {
|
|
4288
|
-
const artifactName =
|
|
4289
|
-
file,
|
|
4290
|
-
"bindings",
|
|
4291
|
-
modeName,
|
|
4292
|
-
duplicateFuzzBasenames,
|
|
4293
|
-
);
|
|
4235
|
+
const artifactName = resolveArtifactPath(file, fuzzInputPatterns);
|
|
4294
4236
|
process.stdout.write(
|
|
4295
4237
|
` - ${path.join(active.outDir, artifactName)}\n`,
|
|
4296
4238
|
);
|
package/bin/types.js
CHANGED
|
@@ -8,6 +8,7 @@ export class Config {
|
|
|
8
8
|
this.snapshotDir = "./.as-test/snapshots";
|
|
9
9
|
this.config = "none";
|
|
10
10
|
this.coverage = false;
|
|
11
|
+
this.features = [];
|
|
11
12
|
this.env = {};
|
|
12
13
|
this.buildOptions = new BuildOptions();
|
|
13
14
|
this.runOptions = new RunOptions();
|
|
@@ -15,6 +16,12 @@ export class Config {
|
|
|
15
16
|
this.modes = {};
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
export const INTERNAL_FEATURE_NAMES = new Set(["try-as"]);
|
|
20
|
+
export function normalizeFeatureName(value) {
|
|
21
|
+
const trimmed = value.trim().toLowerCase();
|
|
22
|
+
if (trimmed == "try_as" || trimmed == "tryas") return "try-as";
|
|
23
|
+
return trimmed;
|
|
24
|
+
}
|
|
18
25
|
export class CoverageOptions {
|
|
19
26
|
constructor() {
|
|
20
27
|
this.enabled = false;
|