Skip to content

Commit a6d5784

Browse files
committed
support listTestName transform
1 parent 80498be commit a6d5784

File tree

8 files changed

+1024
-24
lines changed

8 files changed

+1024
-24
lines changed

bin/cli.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ program
1616
.option("--temp <path>", "test template file folder")
1717
.option("--output <path>", "coverage report output folder")
1818
.option("--mode <output mode>", "test result output format")
19-
.option("--coverageLimit [error warning...]", "set warn(yellow) and error(red) upper limit in coverage report");
19+
.option("--coverageLimit [error warning...]", "set warn(yellow) and error(red) upper limit in coverage report")
20+
.option("--testNamePattern <test name pattern>", "run only tests with a name that matches the regex pattern");
2021

2122
program.parse(process.argv);
2223
const options = program.opts();
@@ -53,9 +54,11 @@ let outputFolder = options.output || config.output || "coverage";
5354
let errorLimit = options.coverageLimit?.at(0);
5455
let warnLimit = options.coverageLimit?.at(1);
5556

57+
let testNamePattern = options.testNamePattern;
58+
5659
validatArgument(includes, excludes);
5760
start_unit_test(
58-
{ includes, excludes, testcases },
61+
{ includes, excludes, testcases, testNamePattern },
5962
{ flags, imports },
6063
{ tempFolder, outputFolder, mode, warnLimit, errorLimit }
6164
)

src/core/precompile.ts

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,73 @@ import { getIncludeFiles } from "../utils/pathResolver.js";
99
import { SourceFunctionInfo, UnittestPackage } from "../interface.js";
1010
import { projectRoot } from "../utils/projectRoot.js";
1111

12-
const sourceFunctions = new Map<string, SourceFunctionInfo[]>();
1312
export async function precompile(
1413
includes: string[],
1514
excludes: string[],
1615
testcases: string[] | undefined,
17-
flags: string,
18-
transformFunction = join(projectRoot, "transform", "listFunctions.mjs")
16+
testNamePattern: string | undefined,
17+
flags: string
1918
): Promise<UnittestPackage> {
2019
// if specify testcases, use testcases for unittest
2120
// otherwise, get testcases(*.test.ts) in includes directory
2221
const testCodePaths = testcases ?? getRelatedFiles(includes, excludes, (path: string) => path.endsWith(".test.ts"));
2322

24-
const sourceCodePaths = getRelatedFiles(includes, excludes, (path: string) => !path.endsWith(".test.ts"));
23+
const matchedTestNames: string[] = [];
24+
if (testNamePattern) {
25+
const testNameInfos = new Map<string, string[]>();
26+
const testNameTransformFunction = join(projectRoot, "transform", "listTestNames.mjs");
27+
for (const testCodePath of testCodePaths) {
28+
await transform(testNameTransformFunction, testCodePath, flags, () => {
29+
testNameInfos.set(testCodePath, testNames);
30+
});
31+
}
32+
const regexPattern = new RegExp(testNamePattern);
33+
for (const [fileName, testNames] of testNameInfos) {
34+
for (const testName of testNames) {
35+
if (regexPattern.test(testName)) {
36+
matchedTestNames.push(testName);
37+
}
38+
}
39+
}
40+
}
2541

42+
const sourceCodePaths = getRelatedFiles(includes, excludes, (path: string) => !path.endsWith(".test.ts"));
43+
const sourceFunctions = new Map<string, SourceFunctionInfo[]>();
44+
const sourceTransformFunction = join(projectRoot, "transform", "listFunctions.mjs");
2645
// The batchSize = 2 is empirical data after benchmarking
2746
const batchSize = 2;
2847
for (let i = 0; i < sourceCodePaths.length; i += batchSize) {
2948
await Promise.all(
30-
sourceCodePaths.slice(i, i + batchSize).map((sourcePath) => transform(sourcePath, transformFunction, flags))
49+
sourceCodePaths.slice(i, i + batchSize).map((sourcePath) =>
50+
transform(sourceTransformFunction, sourcePath, flags, () => {
51+
sourceFunctions.set(sourcePath, functionInfos);
52+
})
53+
)
3154
);
3255
}
3356

3457
return {
3558
testCodePaths,
59+
matchedTestNames,
3660
sourceFunctions,
3761
};
3862
}
3963

64+
async function transform(transformFunction: string, codePath: string, flags: string, collectCallback: () => void) {
65+
let ascArgv = [codePath, "--noEmit", "--disableWarning", "--transform", transformFunction, "-O0"];
66+
if (flags) {
67+
const argv = flags.split(" ");
68+
ascArgv = ascArgv.concat(argv);
69+
}
70+
const { error, stderr } = await main(ascArgv);
71+
if (error) {
72+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
73+
console.error(stderr.toString());
74+
throw error;
75+
}
76+
collectCallback();
77+
}
78+
4079
// a. include in config
4180
// b. exclude in config
4281
export function getRelatedFiles(includes: string[], excludes: string[], filter: (path: string) => boolean) {
@@ -58,18 +97,3 @@ export function getRelatedFiles(includes: string[], excludes: string[], filter:
5897
}
5998
return result;
6099
}
61-
62-
async function transform(sourceCodePath: string, transformFunction: string, flags: string) {
63-
let ascArgv = [sourceCodePath, "--noEmit", "--disableWarning", "--transform", transformFunction, "-O0"];
64-
if (flags) {
65-
const argv = flags.split(" ");
66-
ascArgv = ascArgv.concat(argv);
67-
}
68-
const { error, stderr } = await main(ascArgv);
69-
if (error) {
70-
// eslint-disable-next-line @typescript-eslint/no-base-to-string
71-
console.error(stderr.toString());
72-
throw error;
73-
}
74-
sourceFunctions.set(sourceCodePath, functionInfos);
75-
}

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface FileOption {
5555
includes: string[];
5656
excludes: string[];
5757
testcases: string[] | undefined;
58+
testNamePattern: string | undefined;
5859
}
5960
export interface TestOption {
6061
flags: string;
@@ -75,7 +76,7 @@ export type OutputMode = "html" | "json" | "table";
7576
export async function start_unit_test(fo: FileOption, to: TestOption, oo: OutputOption): Promise<boolean> {
7677
emptydirSync(oo.outputFolder);
7778
emptydirSync(oo.tempFolder);
78-
const unittestPackage = await precompile(fo.includes, fo.excludes, fo.testcases, to.flags);
79+
const unittestPackage = await precompile(fo.includes, fo.excludes, fo.testcases, fo.testNamePattern, to.flags);
7980
console.log(chalk.blueBright("code analysis: ") + chalk.bold.greenBright("OK"));
8081
const wasmPaths = await compile(unittestPackage.testCodePaths, oo.tempFolder, to.flags);
8182
console.log(chalk.blueBright("compile testcases: ") + chalk.bold.greenBright("OK"));

src/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ export class CodeCoverage {
150150

151151
export interface UnittestPackage {
152152
readonly testCodePaths: string[];
153+
readonly matchedTestNames: string[];
153154
readonly sourceFunctions: Map<string, SourceFunctionInfo[]>;
154155
}
155156

@@ -158,5 +159,10 @@ export interface SourceFunctionInfo {
158159
range: [number, number];
159160
}
160161

162+
export interface TestNameInfo {
163+
testName: string;
164+
testFilePath: string;
165+
}
166+
161167
export const OrganizationName = "wasm-ecosystem";
162168
export const Repository = "https://github.com/wasm-ecosystem/assemblyscript-unittest-framework";

src/type/global.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { SourceFunctionInfo } from "../interface.ts";
33
declare global {
44
// store listFunctions transform results in global
55
let functionInfos: SourceFunctionInfo[];
6+
// store listTestNames transform results in global
7+
let testNames: string[];
68
}
79

810
export {};

0 commit comments

Comments
 (0)