rust-analyzer/editors/code/tests/unit/index.ts
2021-12-02 13:05:50 +02:00

80 lines
2 KiB
TypeScript

import * as path from 'path';
class Test {
readonly name: string;
readonly promise: Promise<void>;
constructor(name: string, promise: Promise<void>) {
this.name = name;
this.promise = promise;
}
}
class Suite {
tests: Test[];
constructor() {
this.tests = [];
}
public addTest(name: string, f: () => Promise<void>): void {
const test = new Test(name, f());
this.tests.push(test);
}
public async run(): Promise<void> {
let failed = 0;
for (const test of this.tests) {
try {
await test.promise;
ok(`${test.name}`);
} catch (e) {
error(` ✖︎ ${test.name}\n ${e.stack}`);
failed += 1;
}
}
if (failed) {
const plural = failed > 1 ? "s" : "";
throw new Error(`${failed} failed test${plural}`);
}
}
}
export class Context {
public async suite(name: string, f: (ctx: Suite) => void): Promise<void> {
const ctx = new Suite();
f(ctx);
try {
ok(`⌛︎ ${name}`);
await ctx.run();
ok(`${name}`);
} catch (e) {
error(`✖︎ ${name}\n ${e.stack}`);
throw e;
}
}
}
export async function run(): Promise<void> {
const context = new Context();
const testFiles = ["launch_config.test.js", "runnable_env.test.js"];
for (const testFile of testFiles) {
try {
const testModule = require(path.resolve(__dirname, testFile));
await testModule.getTests(context);
} catch (e) {
error(`${e}`);
throw e;
}
}
}
function ok(message: string): void {
// eslint-disable-next-line no-console
console.log(`\x1b[32m${message}\x1b[0m`);
}
function error(message: string): void {
// eslint-disable-next-line no-console
console.error(`\x1b[31m${message}\x1b[0m`);
}