2022-12-22 13:00:03 +00:00
|
|
|
import {type Result, Test, TestContext} from "./test.js";
|
|
|
|
|
|
|
|
/** Create a new test group and run it. */
|
|
|
|
export async function setup(
|
|
|
|
name: string,
|
|
|
|
fn: (group: Group) => Promise<void>,
|
2022-12-27 14:25:04 +00:00
|
|
|
options?: GroupOptions,
|
2022-12-22 13:00:03 +00:00
|
|
|
): Promise<Group> {
|
2022-12-27 14:25:04 +00:00
|
|
|
const group = new Group(name, options);
|
2022-12-22 13:00:03 +00:00
|
|
|
await fn(group);
|
|
|
|
await group.run();
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
2022-12-27 14:25:04 +00:00
|
|
|
/** Options for test groups. */
|
|
|
|
export type GroupOptions = {
|
|
|
|
parallel?: boolean;
|
|
|
|
};
|
|
|
|
|
2022-12-22 13:00:03 +00:00
|
|
|
/** A collection of tests. */
|
2022-12-27 14:25:04 +00:00
|
|
|
export class Group implements GroupOptions {
|
2022-12-22 13:00:03 +00:00
|
|
|
public context: TestContext = new TestContext();
|
2022-12-27 14:25:04 +00:00
|
|
|
public parallel: boolean;
|
2022-12-22 13:00:03 +00:00
|
|
|
public results: Result[] = [];
|
|
|
|
public tests: Test[] = [];
|
|
|
|
|
2022-12-23 20:45:29 +00:00
|
|
|
private _afterAll: (() => Promise<void>) | undefined;
|
|
|
|
private _beforeAll: (() => Promise<void>) | undefined;
|
|
|
|
|
2022-12-27 14:25:04 +00:00
|
|
|
constructor(public name: string, options?: GroupOptions) {
|
|
|
|
this.parallel = options?.parallel ?? false;
|
|
|
|
}
|
2022-12-22 13:00:03 +00:00
|
|
|
|
2022-12-24 22:32:10 +00:00
|
|
|
/** Set a function to run after all tests have finished. */
|
2022-12-23 20:45:29 +00:00
|
|
|
afterAll(fn: Group["_afterAll"]): void {
|
|
|
|
this._afterAll = fn;
|
|
|
|
}
|
|
|
|
|
2022-12-24 22:32:10 +00:00
|
|
|
/** Set a function to run before all tests begin. */
|
2022-12-23 20:45:29 +00:00
|
|
|
beforeAll(fn: Group["_beforeAll"]): void {
|
|
|
|
this._beforeAll = fn;
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:00:03 +00:00
|
|
|
/** Create a new test case that doesn't get run. */
|
|
|
|
skip(name: Test["name"], fn: Test["fn"]): void {
|
|
|
|
this.tests.push(new Test(name, fn, {skip: true}));
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Create a new test case. */
|
|
|
|
test(name: Test["name"], fn: Test["fn"]): void {
|
|
|
|
this.tests.push(new Test(name, fn));
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Run all the tests from this group and display their results. */
|
|
|
|
async run(): Promise<void> {
|
2022-12-23 20:45:29 +00:00
|
|
|
if (this._beforeAll !== undefined) {
|
|
|
|
await this._beforeAll();
|
|
|
|
}
|
|
|
|
|
2022-12-27 14:25:04 +00:00
|
|
|
let results: Result[];
|
|
|
|
if (this.parallel) {
|
|
|
|
results = await Promise.all(
|
|
|
|
this.tests.map(async (test) => test.run(this.context)),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
results = [];
|
|
|
|
for (const test of this.tests) {
|
|
|
|
// eslint-disable-next-line no-await-in-loop
|
|
|
|
results.push(await test.run(this.context));
|
|
|
|
}
|
|
|
|
}
|
2022-12-22 13:00:03 +00:00
|
|
|
|
2022-12-23 20:45:29 +00:00
|
|
|
if (this._afterAll !== undefined) {
|
|
|
|
await this._afterAll();
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:00:03 +00:00
|
|
|
console.log(
|
|
|
|
`# %c${this.name}`,
|
|
|
|
"font-weight: bold; text-decoration: underline;",
|
|
|
|
);
|
|
|
|
this.results = results;
|
|
|
|
for (const result of results) {
|
|
|
|
result.display();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|