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/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 <feature> Enable build feature (coverage|try-as)\n",
295
+ " --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
291
296
  );
292
297
  process.stdout.write(
293
- " --disable <feature> Disable build feature (coverage|try-as)\n",
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 <feature> Enable feature (coverage|try-as)\n",
362
+ " --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
358
363
  );
359
364
  process.stdout.write(
360
- " --disable <feature> Disable feature (coverage|try-as)\n",
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 <feature> Enable feature (coverage|try-as)\n",
434
+ " --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
430
435
  );
431
436
  process.stdout.write(
432
- " --disable <feature> Disable feature (coverage|try-as)\n",
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") return {};
711
- const out = {};
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
- applyFeatureToggle(out, next, enabled);
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).trim();
732
- if (value.length) {
733
- applyFeatureToggle(out, value, enabled);
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.trim().toLowerCase();
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
- if (key == "try-as" || key == "try_as" || key == "tryas") {
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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 duplicateSpecBasenames =
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 = resolvePerFileArtifactKey(
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: `coverage.${artifactKey}.log.json`,
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
- function resolveDuplicateSpecBasenames(files) {
3605
- const counts = new Map();
3606
- for (const file of files) {
3607
- const base = path.basename(file);
3608
- counts.set(base, (counts.get(base) ?? 0) + 1);
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
- // Disambiguation must consider the full configured input set, not the
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
- const config = loadConfig(resolvedConfigPath, false);
3623
- return resolveDuplicateBasenamesForPatterns(config.input);
3631
+ return loadConfig(resolvedConfigPath, false).input;
3624
3632
  }
3625
- async function resolveAllConfiguredDuplicateFuzzBasenames(configPath) {
3633
+ async function loadFuzzInputPatterns(configPath) {
3626
3634
  const resolvedConfigPath =
3627
3635
  configPath ?? path.join(process.cwd(), "./as-test.config.json");
3628
- const config = loadConfig(resolvedConfigPath, false);
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 duplicateSpecBasenames =
4205
- await resolveAllConfiguredDuplicateSpecBasenames(configPath);
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 = resolveArtifactFileNameForPreview(
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 = resolveArtifactFileNameForPreview(
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 = resolveArtifactFileNameForPreview(
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;