Skip to content

fix: add testFiles option to replace deprecated testcase #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ import { resolve } from "node:path";
import { Command } from "commander";
import { pathToFileURL } from "node:url";

import { validatArgument, start_unit_test } from "../dist/index.js";
import { validateArgument, start_unit_test } from "../dist/index.js";

const program = new Command();
program
.option("--config <config file>", "path of config file", "as-test.config.js")

.option("--temp <path>", "test template file folder")
.option("--output <path>", "coverage report output folder")
.option("--mode <output mode>", "coverage report output format")

.option("--coverageLimit [error warning...]", "set warn(yellow) and error(red) upper limit in coverage report")
.option("--testcase <testcases...>", "run only specified test cases")
.option("--testNamePattern <test name pattern>", "run only tests with a name that matches the regex pattern")
.option("--collectCoverage <boolean>", "whether to collect coverage information and report")

.option("--testcase <testcases...>", "run only specified test cases deprecated, use --testFiles instead")
.option("--testFiles <testFiles...>", "run only specified test files")
.option("--testNamePattern <test name pattern>", "run only tests with a name that matches the regex pattern")
.option("--onlyFailures", "Run tests that failed in the previous");

program.parse(process.argv);
Expand All @@ -38,20 +42,29 @@ if (includes === undefined) {
exit(-1);
}
const excludes = config.exclude || [];
validatArgument(includes, excludes);
validateArgument(includes, excludes);

if (options.testcase !== undefined) {
console.log(
chalk.yellowBright(
"Warning: --testcase is deprecated, please use --testFiles instead, --testcase will be removed in next versions"
)
);
}
const testFiles = options.testFiles || options.testcase;

const onlyFailures = options.onlyFailures || false;

// if enabled testcase or testNamePattern or onlyFailures, disable collectCoverage by default
const collectCoverage =
Boolean(options.collectCoverage) ||
config.collectCoverage ||
(!options.testcase && !options.testNamePattern && !onlyFailures);
(testFiles !== undefined && options.testNamePattern !== undefined && !onlyFailures);

const testOption = {
includes,
excludes,
testcases: options.testcase,
testFiles,
testNamePattern: options.testNamePattern,
collectCoverage,
onlyFailures,
Expand All @@ -74,6 +87,9 @@ start_unit_test(testOption)
}
})
.catch((e) => {
console.error(chalk.redBright(" Test crash, error message: ") + chalk.yellowBright(`${e.stack}`) + "\n");
console.error(chalk.redBright("framework crash, error message: ") + chalk.yellowBright(`${e.stack}`) + "\n");
console.error(
"please submit an issue at https://github.com/wasm-ecosystem/assemblyscript-unittest-framework/issues"
);
exit(255);
});
12 changes: 6 additions & 6 deletions docs/api-documents/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ There are command line options which can override the configuration in `as-test.
### Run partial test cases

```
--testcase <testcases...> only run specified test cases
--testFiles <test files...> only run specified test cases
--testNamePattern <test name pattern> run only tests with a name that matches the regex pattern
--onlyFailures Run tests that failed in the previous
```
Expand All @@ -34,10 +34,10 @@ There are several ways to run partial test cases:

#### Run specified test files

Providing file path to `--testcase`, it can specify a certain group of files for testing.
Providing file path to `--testFiles`, it can specify a certain group of files for testing.

::: tip
`--testcase` can accept multiple file paths.
`--testFiles` can accept multiple file paths.
:::

::: details
Expand All @@ -52,7 +52,7 @@ Providing file path to `--testcase`, it can specify a certain group of files for
|- case_4
```

run `as-test --testcase a.test.ts b.test.ts` will match all tests in `a.test.ts` and `b.test.ts`
run `as-test --testFiles a.test.ts b.test.ts` will match all tests in `a.test.ts` and `b.test.ts`

:::

Expand Down Expand Up @@ -91,7 +91,7 @@ describe("groupB", () => {
run `as-test --testNamePattern "groupA case_\d"` will run `case_1`, `case_2`, `case_3`.

::: tip
The framework join `DescriptionName` and `TestName` with `" "` by default, e.g. `groupA case_1` is the fullTestCaseName of `case_1`.
The framework join `DescriptionName` and `TestName` with `" "` by default, e.g. `groupA case_1` is the full test case name of `case_1`.

:::

Expand All @@ -105,6 +105,6 @@ Provides `--onlyFailures` command line option to run the test cases that failed
--collectCoverage <boolean> whether to collect coverage information and report
```

The framework collects coverage and generates reports by default, but it will be disablea while running partial test cases by `--testcase` or `--testNamePattern`.
The framework collects coverage and generates reports by default, but it will be disablea while running partial test cases by `--testFiles` or `--testNamePattern`.

You can control the coverage collection manually with `--collectCoverage` option.
4 changes: 2 additions & 2 deletions docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ Finally, run `npm run test` and as-test will print this message:
(node:144985) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
code analysis: OK
compile testcases: OK
compile test files: OK
instrument: OK
execute testcases: OK
execute test files: OK

test case: 1/2 (success/total)

Expand Down
8 changes: 4 additions & 4 deletions src/core/precompile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import assert from "node:assert";
export async function precompile(
includes: string[],
excludes: string[],
testcases: string[] | undefined, // this field specifed test file names
testFiles: string[] | undefined, // this field specifed test file names
testNamePattern: string | undefined,
failedTestNames: string[],
collectCoverage: boolean,
flags: string
): Promise<UnittestPackage> {
// if specify testcases, use testcases for unittest
// otherwise, get testcases(*.test.ts) in includes directory
const testCodePaths = testcases ?? getRelatedFiles(includes, excludes, (path: string) => path.endsWith(".test.ts"));
// if specify testFiles, use testFiles for unittest
// otherwise, get testFiles(*.test.ts) in includes directory
const testCodePaths = testFiles ?? getRelatedFiles(includes, excludes, (path: string) => path.endsWith(".test.ts"));
const matchedTestFiles = new Set<string>();
let matchedTestNames: string[] = [];

Expand Down
3 changes: 2 additions & 1 deletion src/executionResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ export class ExecutionResultSummary {
(this.fail === 0 ? chalk.greenBright(this.total) : chalk.redBright(this.total - this.fail)) +
"/" +
this.total.toString();
log(`\ntest case: ${rate} (success/total)\n`);
log(`\ntest case: ${rate} (success/total)`);
if (this.fail !== 0) {
log("");
this.#printErrorMessage(log);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { join } from "node:path";

const { readFileSync, emptydirSync } = pkg;

export function validatArgument(includes: unknown, excludes: unknown) {
export function validateArgument(includes: unknown, excludes: unknown) {
if (!Array.isArray(includes)) {
throw new TypeError("include section illegal");
}
Expand Down Expand Up @@ -53,7 +53,7 @@ export async function start_unit_test(options: TestOption): Promise<boolean> {
const unittestPackage = await precompile(
options.includes,
options.excludes,
options.testcases,
options.testFiles,
options.testNamePattern,
failedTestCases,
options.collectCoverage,
Expand All @@ -62,7 +62,7 @@ export async function start_unit_test(options: TestOption): Promise<boolean> {
console.log(chalk.blueBright("code analysis: ") + chalk.bold.greenBright("OK"));

const wasmPaths = await compile(unittestPackage.testCodePaths, options.tempFolder, options.flags);
console.log(chalk.blueBright("compile testcases: ") + chalk.bold.greenBright("OK"));
console.log(chalk.blueBright("compile test files: ") + chalk.bold.greenBright("OK"));

const sourcePaths = unittestPackage.sourceFunctions ? Array.from(unittestPackage.sourceFunctions.keys()) : [];
const instrumentResult = await instrument(wasmPaths, sourcePaths, options.collectCoverage);
Expand All @@ -74,7 +74,7 @@ export async function start_unit_test(options: TestOption): Promise<boolean> {
unittestPackage.matchedTestNames,
options.imports
);
console.log(chalk.blueBright("execute testcases: ") + chalk.bold.greenBright("OK"));
console.log(chalk.blueBright("execute test files: ") + chalk.bold.greenBright("OK"));

await executedResult.writeFailures(failurePath);
executedResult.print(console.log);
Expand Down
2 changes: 1 addition & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export type Imports = ((arg: ImportsArgument) => Record<string, unknown>) | null
export interface TestOption {
includes: string[];
excludes: string[];
testcases?: string[];
testFiles?: string[];
testNamePattern?: string;
collectCoverage: boolean;
onlyFailures: boolean;
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/assertFailed/stdout.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
code analysis: OK
compile testcases: OK
compile test files: OK
instrument: OK
execute testcases: OK
execute test files: OK

test case: 0/2 (success/total)

Expand All @@ -11,11 +11,11 @@ Error Message:
This test will fail due to an assertion error
Reason: unreachable
at start:tests/e2e/assertFailed/assertOnTest.test~anonymous|0 (tests/e2e/assertFailed/assertOnTest.test.ts:6:2)
at executeTestFunction (tests/e2e/assertFailed/tmp/assertOnTest.test.instrumented.wasm:1:675)
at executeTestFunction (tests/e2e/assertFailed/tmp/assertOnTest.test.instrumented.wasm:1:637)

tests/e2e/assertFailed/tmp/assertOnInit.test - init:
Test Crashed!
Reason: unreachable
at start:tests/e2e/assertFailed/assertOnInit.test (tests/e2e/assertFailed/assertOnInit.test.ts:1:0)
at ~start (tests/e2e/assertFailed/tmp/assertOnInit.test.instrumented.wasm:1:244)
at ~start (tests/e2e/assertFailed/tmp/assertOnInit.test.instrumented.wasm:1:206)

4 changes: 2 additions & 2 deletions tests/e2e/printLogInFailedInfo/stdout.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
code analysis: OK
compile testcases: OK
compile test files: OK
instrument: OK
execute testcases: OK
execute test files: OK

test case: 1/2 (success/total)

Expand Down
22 changes: 13 additions & 9 deletions tests/e2e/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import { argv } from "node:process";
import { readFileSync } from "node:fs";

function getDiff(s1, s2) {
const handleEscape = (c) =>
c
.split("\n")
.map((l) => (l.length === 0 ? "\xB6" : l))
.join("\n");
const handleEscape = (c) => (/^\n*$/.test(c) ? c.replaceAll("\n", "\xB6\n") : c);
return diffLines(s1, s2)
.map((part) => {
if (part.added) {
Expand All @@ -32,10 +28,10 @@ function isEnabled(name) {
return enabledTests.includes(name);
}

function runEndToEndTest(name, handle) {
function runEndToEndTest(name, flags, handle) {
if (isEnabled(name)) {
console.log(`Running e2e test: ${name}`);
exec(`node ./bin/as-test.js --config tests/e2e/${name}/as-test.config.js`, (error, stdout, stderr) => {
exec(`node ./bin/as-test.js --config tests/e2e/${name}/as-test.config.js ${flags}`, (error, stdout, stderr) => {
// standard check
const expectStdOut = readFileSync(`tests/e2e/${name}/stdout.txt`, "utf-8");
if (expectStdOut !== stdout) {
Expand All @@ -51,10 +47,18 @@ function runEndToEndTest(name, handle) {
}
}

runEndToEndTest("printLogInFailedInfo", (error, stdout, stderr) => {
runEndToEndTest("printLogInFailedInfo", "", (error, stdout, stderr) => {
assert(error.code === 255);
});

runEndToEndTest("assertFailed", (error, stdout, stderr) => {
runEndToEndTest("assertFailed", "", (error, stdout, stderr) => {
assert(error.code === 255);
});

runEndToEndTest(
"testFiles",
"--testFiles tests/e2e/testFiles/succeed_0.test.ts tests/e2e/testFiles/succeed_1.test.ts",
(error, stdout, stderr) => {
assert(error === null);
}
);
19 changes: 19 additions & 0 deletions tests/e2e/testFiles/as-test.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import path from "node:path";

const __dirname = path.dirname(new URL(import.meta.url).pathname);

export default {
include: [__dirname],
imports(runtime) {
return {
env: {
log: (msg) => {
runtime.framework.log(runtime.exports.__getString(msg));
},
},
};
},
temp: path.join(__dirname, "tmp"),
output: path.join(__dirname, "tmp"),
mode: [],
};
1 change: 1 addition & 0 deletions tests/e2e/testFiles/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export declare function log(msg: string): void;
7 changes: 7 additions & 0 deletions tests/e2e/testFiles/failed.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { test, expect } from "../../../assembly";
import { log } from "./env";

test("failed test", () => {
log("This is a log message for the failed test.");
expect(1 + 1).equal(3);
});
6 changes: 6 additions & 0 deletions tests/e2e/testFiles/stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
code analysis: OK
compile test files: OK
instrument: OK
execute test files: OK

test case: 2/2 (success/total)
7 changes: 7 additions & 0 deletions tests/e2e/testFiles/succeed_0.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { test, expect } from "../../../assembly";
import { log } from "./env";

test("succeed test", () => {
log("This is a log message for the succeed test.");
expect(1 + 1).equal(2);
});
7 changes: 7 additions & 0 deletions tests/e2e/testFiles/succeed_1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { test, expect } from "../../../assembly";
import { log } from "./env";

test("succeed test", () => {
log("This is a log message for the succeed test.");
expect(1 + 1).equal(2);
});
4 changes: 4 additions & 0 deletions tests/e2e/testFiles/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "assemblyscript/std/assembly.json",
"include": ["./**/*.ts"]
}
Loading