as-test 1.2.0 → 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 +19 -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 +111 -38
- package/assembly/src/mode.ts +55 -0
- package/bin/commands/build-core.js +152 -7
- package/bin/commands/build.js +3 -1
- package/bin/commands/init-core.js +253 -5
- package/bin/commands/test.js +1 -1
- package/bin/index.js +60 -20
- package/bin/types.js +7 -0
- package/bin/util.js +43 -0
- package/package.json +3 -3
- 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";
|
|
@@ -26,6 +28,7 @@ import {
|
|
|
26
28
|
resolveModeNames,
|
|
27
29
|
resolveSpecRelativePath,
|
|
28
30
|
} from "./util.js";
|
|
31
|
+
import { normalizeFeatureName } from "./types.js";
|
|
29
32
|
import * as path from "path";
|
|
30
33
|
import { spawnSync } from "child_process";
|
|
31
34
|
import { glob } from "glob";
|
|
@@ -289,10 +292,10 @@ function printCommandHelp(command) {
|
|
|
289
292
|
" --mode <name[,name...]> Run one or multiple named config modes\n",
|
|
290
293
|
);
|
|
291
294
|
process.stdout.write(
|
|
292
|
-
" --enable <
|
|
295
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
293
296
|
);
|
|
294
297
|
process.stdout.write(
|
|
295
|
-
" --disable <
|
|
298
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
296
299
|
);
|
|
297
300
|
process.stdout.write(
|
|
298
301
|
" --parallel Run files through an ordered worker pool using an automatic worker count\n",
|
|
@@ -356,10 +359,10 @@ function printCommandHelp(command) {
|
|
|
356
359
|
);
|
|
357
360
|
process.stdout.write(" --suites <name[,name...]> Alias for --suite\n");
|
|
358
361
|
process.stdout.write(
|
|
359
|
-
" --enable <
|
|
362
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
360
363
|
);
|
|
361
364
|
process.stdout.write(
|
|
362
|
-
" --disable <
|
|
365
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
363
366
|
);
|
|
364
367
|
process.stdout.write(
|
|
365
368
|
" --reporter <name|path> Use built-in reporter (default|tap) or custom module path\n",
|
|
@@ -428,10 +431,10 @@ function printCommandHelp(command) {
|
|
|
428
431
|
);
|
|
429
432
|
process.stdout.write(" --suites <name[,name...]> Alias for --suite\n");
|
|
430
433
|
process.stdout.write(
|
|
431
|
-
" --enable <
|
|
434
|
+
" --enable <list> Enable features, comma-separated (e.g. coverage,try-as,simd)\n",
|
|
432
435
|
);
|
|
433
436
|
process.stdout.write(
|
|
434
|
-
" --disable <
|
|
437
|
+
" --disable <list> Disable features, comma-separated\n",
|
|
435
438
|
);
|
|
436
439
|
process.stdout.write(
|
|
437
440
|
" --fuzz Run fuzz targets after the normal test pass\n",
|
|
@@ -534,6 +537,12 @@ function printCommandHelp(command) {
|
|
|
534
537
|
process.stdout.write(
|
|
535
538
|
" --example <minimal|full|none> Set example template\n",
|
|
536
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
|
+
);
|
|
537
546
|
process.stdout.write(
|
|
538
547
|
" --install Install dependencies after scaffolding\n",
|
|
539
548
|
);
|
|
@@ -709,8 +718,9 @@ function resolveCommandArgs(rawArgs, command) {
|
|
|
709
718
|
return values;
|
|
710
719
|
}
|
|
711
720
|
function resolveFeatureToggles(rawArgs, command) {
|
|
712
|
-
if (command !== "build" && command !== "run" && command !== "test")
|
|
713
|
-
|
|
721
|
+
if (command !== "build" && command !== "run" && command !== "test")
|
|
722
|
+
return { featureOverrides: {} };
|
|
723
|
+
const out = { featureOverrides: {} };
|
|
714
724
|
let seenCommand = false;
|
|
715
725
|
for (let i = 0; i < rawArgs.length; i++) {
|
|
716
726
|
const arg = rawArgs[i];
|
|
@@ -722,7 +732,9 @@ function resolveFeatureToggles(rawArgs, command) {
|
|
|
722
732
|
const enabled = arg == "--enable";
|
|
723
733
|
const next = rawArgs[i + 1];
|
|
724
734
|
if (next && !next.startsWith("-")) {
|
|
725
|
-
|
|
735
|
+
for (const name of splitFeatureList(next)) {
|
|
736
|
+
applyFeatureToggle(out, name, enabled);
|
|
737
|
+
}
|
|
726
738
|
i++;
|
|
727
739
|
}
|
|
728
740
|
continue;
|
|
@@ -730,9 +742,9 @@ function resolveFeatureToggles(rawArgs, command) {
|
|
|
730
742
|
if (arg.startsWith("--enable=") || arg.startsWith("--disable=")) {
|
|
731
743
|
const enabled = arg.startsWith("--enable=");
|
|
732
744
|
const eq = arg.indexOf("=");
|
|
733
|
-
const value = arg.slice(eq + 1)
|
|
734
|
-
|
|
735
|
-
applyFeatureToggle(out,
|
|
745
|
+
const value = arg.slice(eq + 1);
|
|
746
|
+
for (const name of splitFeatureList(value)) {
|
|
747
|
+
applyFeatureToggle(out, name, enabled);
|
|
736
748
|
}
|
|
737
749
|
}
|
|
738
750
|
}
|
|
@@ -1280,19 +1292,24 @@ function parseIntegerFlag(flag, value) {
|
|
|
1280
1292
|
}
|
|
1281
1293
|
return Math.floor(parsed);
|
|
1282
1294
|
}
|
|
1295
|
+
function splitFeatureList(value) {
|
|
1296
|
+
return value
|
|
1297
|
+
.split(",")
|
|
1298
|
+
.map((part) => part.trim())
|
|
1299
|
+
.filter((part) => part.length > 0);
|
|
1300
|
+
}
|
|
1283
1301
|
function applyFeatureToggle(out, rawFeature, enabled) {
|
|
1284
|
-
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
|
+
}
|
|
1285
1308
|
if (key == "coverage") {
|
|
1286
1309
|
out.coverage = enabled;
|
|
1287
1310
|
return;
|
|
1288
1311
|
}
|
|
1289
|
-
|
|
1290
|
-
out.tryAs = enabled;
|
|
1291
|
-
return;
|
|
1292
|
-
}
|
|
1293
|
-
throw new Error(
|
|
1294
|
-
`unknown feature "${rawFeature}". Supported features: coverage, try-as`,
|
|
1295
|
-
);
|
|
1312
|
+
out.featureOverrides[key] = enabled;
|
|
1296
1313
|
}
|
|
1297
1314
|
function resolveCommandTokens(rawArgs, command) {
|
|
1298
1315
|
const values = [];
|
|
@@ -1425,6 +1442,7 @@ async function runTestSequential(
|
|
|
1425
1442
|
),
|
|
1426
1443
|
});
|
|
1427
1444
|
reporter.flush?.();
|
|
1445
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
1428
1446
|
}
|
|
1429
1447
|
return {
|
|
1430
1448
|
failed,
|
|
@@ -1874,6 +1892,7 @@ async function runTestModesCore(
|
|
|
1874
1892
|
),
|
|
1875
1893
|
});
|
|
1876
1894
|
reporterSession.reporter.flush?.();
|
|
1895
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
1877
1896
|
}
|
|
1878
1897
|
}
|
|
1879
1898
|
} finally {
|
|
@@ -2063,6 +2082,14 @@ async function runTestMatrix(
|
|
|
2063
2082
|
fuzzOverrides,
|
|
2064
2083
|
) {
|
|
2065
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
|
+
}
|
|
2066
2093
|
if (!files.length) {
|
|
2067
2094
|
if (!fuzzEnabled) {
|
|
2068
2095
|
throw await buildNoTestFilesMatchedError(configPath, selectors);
|
|
@@ -2215,6 +2242,7 @@ async function runTestMatrix(
|
|
|
2215
2242
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2216
2243
|
});
|
|
2217
2244
|
reporter.flush?.();
|
|
2245
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2218
2246
|
return failed;
|
|
2219
2247
|
}
|
|
2220
2248
|
async function runFuzzModes(
|
|
@@ -2372,6 +2400,7 @@ async function runRuntimeSingleParallel(
|
|
|
2372
2400
|
),
|
|
2373
2401
|
});
|
|
2374
2402
|
reporter.flush?.();
|
|
2403
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2375
2404
|
return results.some((result) => result.failed);
|
|
2376
2405
|
}
|
|
2377
2406
|
async function runRuntimeMatrixParallel(
|
|
@@ -2516,6 +2545,7 @@ async function runRuntimeMatrixParallel(
|
|
|
2516
2545
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2517
2546
|
});
|
|
2518
2547
|
reporter.flush?.();
|
|
2548
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2519
2549
|
return allResults.some((result) => result.failed);
|
|
2520
2550
|
}
|
|
2521
2551
|
async function runTestSingleParallel(
|
|
@@ -2671,6 +2701,7 @@ async function runTestSingleParallel(
|
|
|
2671
2701
|
),
|
|
2672
2702
|
});
|
|
2673
2703
|
reporter.flush?.();
|
|
2704
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2674
2705
|
return failed;
|
|
2675
2706
|
}
|
|
2676
2707
|
async function runTestMatrixParallel(
|
|
@@ -2687,6 +2718,14 @@ async function runTestMatrixParallel(
|
|
|
2687
2718
|
fuzzOverrides,
|
|
2688
2719
|
) {
|
|
2689
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
|
+
}
|
|
2690
2729
|
if (!files.length) {
|
|
2691
2730
|
if (!fuzzEnabled) {
|
|
2692
2731
|
throw await buildNoTestFilesMatchedError(configPath, selectors);
|
|
@@ -2851,6 +2890,7 @@ async function runTestMatrixParallel(
|
|
|
2851
2890
|
modeSummary: buildModeSummary(modeState, modeSummaryTotal),
|
|
2852
2891
|
});
|
|
2853
2892
|
reporter.flush?.();
|
|
2893
|
+
flushModeWarnings(process.argv.includes("--show-warnings"));
|
|
2854
2894
|
return failed;
|
|
2855
2895
|
}
|
|
2856
2896
|
async function runFuzzMatrixResultsParallel(
|
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;
|
package/bin/util.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CoverageIgnoreOptions,
|
|
7
7
|
FuzzConfig,
|
|
8
8
|
ModeConfig,
|
|
9
|
+
normalizeFeatureName,
|
|
9
10
|
ReporterConfig,
|
|
10
11
|
RunOptions,
|
|
11
12
|
Runtime,
|
|
@@ -186,6 +187,7 @@ function parseConfigRaw(raw, configPath) {
|
|
|
186
187
|
typeof config.fuzz.crashDir == "string" && config.fuzz.crashDir.length
|
|
187
188
|
? config.fuzz.crashDir
|
|
188
189
|
: "./.as-test/crashes";
|
|
190
|
+
config.features = parseFeaturesField(raw.features);
|
|
189
191
|
config.modes = parseModes(raw.modes, configDir);
|
|
190
192
|
CONFIG_META.set(config, {
|
|
191
193
|
sourcePath: configPath,
|
|
@@ -193,6 +195,19 @@ function parseConfigRaw(raw, configPath) {
|
|
|
193
195
|
});
|
|
194
196
|
return config;
|
|
195
197
|
}
|
|
198
|
+
function parseFeaturesField(raw) {
|
|
199
|
+
if (!Array.isArray(raw)) return [];
|
|
200
|
+
const seen = new Set();
|
|
201
|
+
const out = [];
|
|
202
|
+
for (const value of raw) {
|
|
203
|
+
if (typeof value != "string") continue;
|
|
204
|
+
const name = normalizeFeatureName(value);
|
|
205
|
+
if (!name.length || seen.has(name)) continue;
|
|
206
|
+
seen.add(name);
|
|
207
|
+
out.push(name);
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
196
211
|
const TOP_LEVEL_KEYS = new Set([
|
|
197
212
|
"$schema",
|
|
198
213
|
"input",
|
|
@@ -203,6 +218,7 @@ const TOP_LEVEL_KEYS = new Set([
|
|
|
203
218
|
"snapshotDir",
|
|
204
219
|
"config",
|
|
205
220
|
"coverage",
|
|
221
|
+
"features",
|
|
206
222
|
"env",
|
|
207
223
|
"buildOptions",
|
|
208
224
|
"fuzz",
|
|
@@ -238,6 +254,7 @@ function validateConfig(raw, configPath) {
|
|
|
238
254
|
validateStringField(raw, "snapshotDir", "$", issues);
|
|
239
255
|
validateStringField(raw, "config", "$", issues);
|
|
240
256
|
validateCoverageField(raw, "coverage", "$", issues);
|
|
257
|
+
validateFeaturesField(raw, "features", "$", issues);
|
|
241
258
|
validateEnvField(raw, "env", "$", issues);
|
|
242
259
|
validateBuildOptionsField(raw, "buildOptions", "$", issues);
|
|
243
260
|
validateFuzzField(raw, "fuzz", "$", issues);
|
|
@@ -742,12 +759,34 @@ function validateModesField(raw, key, pathPrefix, issues) {
|
|
|
742
759
|
validateStringField(modeObj, "snapshotDir", modePath, issues);
|
|
743
760
|
validateStringField(modeObj, "config", modePath, issues);
|
|
744
761
|
validateCoverageField(modeObj, "coverage", modePath, issues);
|
|
762
|
+
validateFeaturesField(modeObj, "features", modePath, issues);
|
|
745
763
|
validateFuzzField(modeObj, "fuzz", modePath, issues);
|
|
746
764
|
validateEnvField(modeObj, "env", modePath, issues);
|
|
747
765
|
validateBuildOptionsField(modeObj, "buildOptions", modePath, issues);
|
|
748
766
|
validateRunOptionsField(modeObj, "runOptions", modePath, issues);
|
|
749
767
|
}
|
|
750
768
|
}
|
|
769
|
+
function validateFeaturesField(raw, key, pathPrefix, issues) {
|
|
770
|
+
if (!(key in raw) || raw[key] == undefined) return;
|
|
771
|
+
const value = raw[key];
|
|
772
|
+
if (!Array.isArray(value)) {
|
|
773
|
+
issues.push({
|
|
774
|
+
path: `${pathPrefix}.${key}`,
|
|
775
|
+
message: "must be an array of feature name strings",
|
|
776
|
+
fix: 'example: "features": ["try-as", "simd"]',
|
|
777
|
+
});
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
for (let i = 0; i < value.length; i++) {
|
|
781
|
+
if (typeof value[i] != "string" || !value[i].trim().length) {
|
|
782
|
+
issues.push({
|
|
783
|
+
path: `${pathPrefix}.${key}[${i}]`,
|
|
784
|
+
message: "must be a non-empty string",
|
|
785
|
+
fix: 'feature names look like "try-as" or "simd"',
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
751
790
|
function isStringArray(value) {
|
|
752
791
|
return Array.isArray(value) && value.every((item) => typeof item == "string");
|
|
753
792
|
}
|
|
@@ -1051,6 +1090,7 @@ function cloneConfig(config) {
|
|
|
1051
1090
|
cloned.runOptions = cloneRunOptions(config.runOptions);
|
|
1052
1091
|
cloned.fuzz = cloneFuzzConfig(config.fuzz);
|
|
1053
1092
|
cloned.coverage = cloneCoverageOptions(config.coverage);
|
|
1093
|
+
cloned.features = [...config.features];
|
|
1054
1094
|
cloned.modes = Object.fromEntries(
|
|
1055
1095
|
Object.entries(config.modes).map(([name, mode]) => [
|
|
1056
1096
|
name,
|
|
@@ -1211,6 +1251,9 @@ function mergeRootConfig(base, override) {
|
|
|
1211
1251
|
raw.coverage,
|
|
1212
1252
|
);
|
|
1213
1253
|
}
|
|
1254
|
+
if (Array.isArray(raw.features)) {
|
|
1255
|
+
merged.features = [...override.features];
|
|
1256
|
+
}
|
|
1214
1257
|
if ("env" in raw) {
|
|
1215
1258
|
merged.env = { ...override.env };
|
|
1216
1259
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "as-test",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"assemblyscript-prettier": "^3.0.4",
|
|
26
26
|
"husky": "^9.1.7",
|
|
27
27
|
"json-as": "^1.3.7",
|
|
28
|
+
"playwright": "^1.60.0",
|
|
28
29
|
"prettier": "3.8.3",
|
|
29
30
|
"try-as": "^1.1.0",
|
|
30
31
|
"typescript": "^6.0.3",
|
|
@@ -91,7 +92,7 @@
|
|
|
91
92
|
"typecheck": "tsc -p cli --noEmit && tsc -p tsconfig.lib.json --noEmit && tsc -p transform --noEmit",
|
|
92
93
|
"lint": "eslint transform/src/**/*.ts tools/**/*.js eslint.config.js",
|
|
93
94
|
"build:lib": "tsc -p ./tsconfig.lib.json",
|
|
94
|
-
"build:transform": "tsc -p ./transform",
|
|
95
|
+
"build:transform": "tsc -p ./transform && prettier -w ./transform/",
|
|
95
96
|
"build:cli": "tsc -p cli",
|
|
96
97
|
"build:run": "npm run build:cli",
|
|
97
98
|
"docs:dev": "vitepress dev docs",
|
|
@@ -102,7 +103,6 @@
|
|
|
102
103
|
"prepublishOnly": "npm run build:cli && npm run build:lib && npm run build:transform && npm run test && npm run format",
|
|
103
104
|
"commitmsg:verify": "bash ./scripts/commit-msg.sh",
|
|
104
105
|
"precommit:verify": "bash ./scripts/pre-commit.sh",
|
|
105
|
-
"prepush:verify": "bash ./scripts/pre-push.sh",
|
|
106
106
|
"prepare": "husky"
|
|
107
107
|
},
|
|
108
108
|
"type": "module"
|
package/transform/lib/index.js
CHANGED
|
@@ -5,8 +5,10 @@ import { MockTransform } from "./mock.js";
|
|
|
5
5
|
import { LocationTransform } from "./location.js";
|
|
6
6
|
import { LogTransform } from "./log.js";
|
|
7
7
|
import { isStdlib } from "./util.js";
|
|
8
|
+
import { NodeKind } from "./types.js";
|
|
8
9
|
export default class Transformer extends Transform {
|
|
9
10
|
afterParse(parser) {
|
|
11
|
+
patchModeName(parser, process.env.AS_TEST_MODE_NAME ?? "default");
|
|
10
12
|
const mock = new MockTransform();
|
|
11
13
|
const location = new LocationTransform();
|
|
12
14
|
const log = new LogTransform(parser);
|
|
@@ -81,6 +83,30 @@ export default class Transformer extends Transform {
|
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
}
|
|
86
|
+
function patchModeName(parser, modeName) {
|
|
87
|
+
for (const source of parser.sources) {
|
|
88
|
+
if (!source.normalizedPath.endsWith("assembly/src/mode.ts"))
|
|
89
|
+
continue;
|
|
90
|
+
for (const stmt of source.statements) {
|
|
91
|
+
if (stmt.kind !== NodeKind.Variable)
|
|
92
|
+
continue;
|
|
93
|
+
const decls = stmt.declarations;
|
|
94
|
+
for (const decl of decls) {
|
|
95
|
+
if (decl.name.text !== "AS_TEST_MODE_NAME")
|
|
96
|
+
continue;
|
|
97
|
+
if (!decl.initializer)
|
|
98
|
+
continue;
|
|
99
|
+
if (decl.initializer.kind !== NodeKind.Literal)
|
|
100
|
+
continue;
|
|
101
|
+
const literal = decl.initializer;
|
|
102
|
+
if (literal.literalKind !== 2)
|
|
103
|
+
continue;
|
|
104
|
+
literal.value = modeName;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
84
110
|
function collectMockImportTargets(sources) {
|
|
85
111
|
const out = new Set();
|
|
86
112
|
const pattern = /\bmockImport\s*\(\s*["']([^"']+)["']/g;
|