Skip to content

Commit 1fb5f57

Browse files
committed
feat: implement setup and teardown
1 parent 7309333 commit 1fb5f57

File tree

12 files changed

+190
-11
lines changed

12 files changed

+190
-11
lines changed

assembly/env.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ export namespace assertResult {
1212
export declare function registerTestFunction(index: u32): void;
1313

1414

15+
@external("__unittest_framework_env","registerBeforeEachFunction")
16+
export declare function registerBeforeEachFunction(index: u32): boolean;
17+
18+
19+
@external("__unittest_framework_env","registerAfterEachFunction")
20+
export declare function registerAfterEachFunction(index: u32): boolean;
21+
22+
1523
@external("__unittest_framework_env","collectCheckResult")
1624
export declare function collectCheckResult(
1725
result: bool,

assembly/implement.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ export function testImpl(name: string, testFunction: () => void): void {
1515
assertResult.removeDescription();
1616
}
1717

18-
export function beforeEachImpl(func: () => void): void {}
18+
export function beforeEachImpl(func: () => void): void {
19+
const result = assertResult.registerBeforeEachFunction(func.index);
20+
assert(result, "register setup function failed");
21+
}
1922

20-
export function afterEachImpl(func: () => void): void {}
23+
export function afterEachImpl(func: () => void): void {
24+
const result = assertResult.registerAfterEachFunction(func.index);
25+
assert(result, "register teardown function failed");
26+
}
2127

2228
export function mockImpl<T extends Function>(
2329
originalFunction: T,

src/core/execute.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,24 @@ async function nodeExecutor(
7777
}
7878
executionRecorder.finishTestFunction();
7979

80-
const execTestFunction = ins.exports["executeTestFunction"];
80+
const execTestFunction = ins.exports["executeTestFunction"] as (a: number) => void;
8181
assert(typeof execTestFunction === "function");
8282

8383
for (const testCase of executionRecorder.testCases) {
8484
if (isCrashed) {
8585
break;
8686
}
87-
const { fullName, functionIndex } = testCase;
87+
const { fullName, functionIndex, setupFunctions, teardownFunctions } = testCase;
8888
if (matchedTestNames.length === 0 || matchedTestNames.includes(fullName)) {
8989
executionRecorder.startTestFunction(fullName);
9090
try {
91-
(execTestFunction as (a: number) => void)(functionIndex);
91+
for (const setupFuncIndex of setupFunctions) {
92+
execTestFunction(setupFuncIndex);
93+
}
94+
execTestFunction(functionIndex);
95+
for (const teardownFuncIndex of teardownFunctions) {
96+
execTestFunction(teardownFuncIndex);
97+
}
9298
} catch (error) {
9399
await exceptionHandler(error);
94100
}

src/core/executionRecorder.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,21 @@ export class ExecutionResult implements IExecutionResult {
4646

4747
class TestBlock {
4848
constructor(public description: string) {}
49+
setupFunctions: number[] = [];
50+
teardownFunctions: number[] = [];
4951
}
5052

51-
class TestCase {
53+
export class TestCase {
5254
fullName: string;
55+
setupFunctions: number[];
56+
teardownFunctions: number[];
5357
constructor(
5458
testBlockStack: TestBlock[],
5559
public functionIndex: number
5660
) {
5761
this.fullName = testBlockStack.map((block) => block.description).join(" ");
62+
this.setupFunctions = testBlockStack.flatMap((block) => block.setupFunctions);
63+
this.teardownFunctions = testBlockStack.flatMap((block) => block.teardownFunctions);
5864
}
5965
}
6066

@@ -73,6 +79,30 @@ export class ExecutionRecorder implements UnitTestFramework {
7379
_removeDescription(): void {
7480
this.testBlockStack.pop();
7581
}
82+
83+
get lastTestBlock(): TestBlock | undefined {
84+
return this.testBlockStack[this.testBlockStack.length - 1];
85+
}
86+
// return false if error
87+
_registerSetup(functionIndex: number): boolean {
88+
const lastTestBlock = this.lastTestBlock;
89+
if (lastTestBlock === undefined) {
90+
return false;
91+
} else {
92+
lastTestBlock.setupFunctions.push(functionIndex);
93+
return true;
94+
}
95+
}
96+
// return false if error
97+
_registerTeardown(functionIndex: number): boolean {
98+
const lastTestBlock = this.lastTestBlock;
99+
if (lastTestBlock === undefined) {
100+
return false;
101+
} else {
102+
lastTestBlock.teardownFunctions.push(functionIndex);
103+
return true;
104+
}
105+
}
76106
_addTestCase(functionIndex: number): void {
77107
this.testCases.push(new TestCase(this.testBlockStack, functionIndex));
78108
}
@@ -128,6 +158,12 @@ export class ExecutionRecorder implements UnitTestFramework {
128158
registerTestFunction: (index: number): void => {
129159
this._addTestCase(index);
130160
},
161+
registerBeforeEachFunction: (index: number): boolean => {
162+
return this._registerSetup(index);
163+
},
164+
registerAfterEachFunction: (index: number): boolean => {
165+
return this._registerTeardown(index);
166+
},
131167
collectCheckResult: (result: number, codeInfoIndex: number, actualValue: number, expectValue: number): void => {
132168
this.collectCheckResult(
133169
result !== 0,

tests/e2e/run.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@ runEndToEndTest("compilationFailed", "", (error, stdout, stderr) => {
5555
assert(error.code === 2);
5656
});
5757

58+
runEndToEndTest("isolated-cli", "--isolated false", (error, stdout, stderr) => {});
59+
runEndToEndTest("isolated-false", "", (error, stdout, stderr) => {});
60+
runEndToEndTest("isolated-true", "", (error, stdout, stderr) => {});
61+
5862
runEndToEndTest("printLogInFailedInfo", "", (error, stdout, stderr) => {
5963
assert(error.code === 1);
6064
});
6165

62-
runEndToEndTest("isolated-true", "", (error, stdout, stderr) => {});
63-
runEndToEndTest("isolated-false", "", (error, stdout, stderr) => {});
64-
runEndToEndTest("isolated-cli", "--isolated false", (error, stdout, stderr) => {});
66+
runEndToEndTest("setup-teardown", "", (error, stdout, stderr) => {});
6567

6668
runEndToEndTest(
6769
"testFiles",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import path from "node:path";
2+
3+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
4+
5+
/**
6+
* @type {import("../../../config.d.ts").Config}
7+
*/
8+
export default {
9+
include: [__dirname],
10+
temp: path.join(__dirname, "tmp"),
11+
output: path.join(__dirname, "tmp"),
12+
mode: [],
13+
isolated: true,
14+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { test, expect, describe, beforeEach } from "../../../assembly";
2+
3+
let setup0 = 0;
4+
let setup1 = 0;
5+
describe("setup", () => {
6+
beforeEach(() => {
7+
setup0 = 10;
8+
setup1 = 20;
9+
});
10+
test("1st", () => {
11+
expect(setup0).equal(10);
12+
expect(setup1).equal(20);
13+
setup0 = 100;
14+
setup1 = 200;
15+
});
16+
test("2nd", () => {
17+
expect(setup0).equal(10);
18+
expect(setup1).equal(20);
19+
setup0 = 100;
20+
setup1 = 200;
21+
});
22+
test("3nd", () => {
23+
expect(setup0).equal(10);
24+
expect(setup1).equal(20);
25+
});
26+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { beforeEach } from "../../../assembly";
2+
3+
beforeEach(() => {});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
code analysis: OK
2+
compile test files: OK
3+
instrument: OK
4+
execute test files: OK
5+
6+
test case: 12/13 (success/total)
7+
8+
Error Message:
9+
tests/e2e/setup-teardown/tmp/setup_out_of_block.test - init:
10+
Test Crashed!
11+
Reason: unreachable
12+
at assembly/implement/beforeEachImpl (assembly/implement.ts:20:2)
13+
at assembly/index/beforeEach (assembly/index.ts:47:2)
14+
at start:tests/e2e/setup-teardown/setup_out_of_block.test (tests/e2e/setup-teardown/tmp/setup_out_of_block.test.instrumented.wasm:1:547)
15+
at ~start (tests/e2e/setup-teardown/tmp/setup_out_of_block.test.instrumented.wasm:1:325)
16+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { test, expect, describe, afterEach } from "../../../assembly";
2+
3+
let teardown0 = 0;
4+
let teardown1 = 0;
5+
describe("teardown", () => {
6+
afterEach(() => {
7+
teardown0 = 10;
8+
teardown1 = 20;
9+
});
10+
test("1st", () => {
11+
expect(teardown0).equal(0);
12+
expect(teardown1).equal(0);
13+
teardown0 = 100;
14+
teardown1 = 200;
15+
});
16+
test("2nd", () => {
17+
expect(teardown0).equal(10);
18+
expect(teardown1).equal(20);
19+
teardown0 = 100;
20+
teardown1 = 200;
21+
});
22+
test("3nd", () => {
23+
expect(teardown0).equal(10);
24+
expect(teardown1).equal(20);
25+
});
26+
});

0 commit comments

Comments
 (0)