-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathharness.ts
69 lines (55 loc) · 1.85 KB
/
harness.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Check, ContextFactory, MethodMap, Result, Test, Tester, TestFactory } from "./api";
export function setup<T extends MethodMap, C>(methods: T, createContext?: ContextFactory<C>): TestFactory<T, C> {
return (description, spec) => ({
methods,
createContext: createContext || (() => null as any),
description,
spec,
});
}
export async function run(tests: Array<Test<any,any>>): Promise<Result[]> {
return Promise.all(tests.map(runTest));
}
/**
* This `Error`-type represents capture `throw` statements with a non-`Error` type.
*
* TODO maybe keep the value formatting internal to this class? remove formatting from `createReport` in here, and remove the `UnknownError` type from `Fact.error`?
*/
export class UnknownError extends Error {
constructor(public readonly value: unknown) {
super("Unknown error type");
}
}
export async function runTest<T extends MethodMap, C>({ methods, createContext, description, spec }: Test<T, C>): Promise<Result> {
const checks: Check[] = [];
let checked = (check: Check) => {
checks.push(check);
};
const tester = Object.fromEntries(
Object.entries(methods)
.map(([name, assertion]) => [name, (...args: any) => {
const location = new Error().stack!
.split("\n")[2]
.replace(/^\s+at /, "");
const fact = assertion(...args);
checked({ location, fact });
}])
) as Tester<T>;
const started = Date.now();
let error: Error | undefined;
try {
await spec(tester, createContext());
} catch (e: unknown) {
error = e instanceof Error ? e : new UnknownError(e);
}
const time = Date.now() - started;
checked = () => {
throw new Error(`attempted assertion after end of test "${description}" - please check your code for missing await statements.`);
};
return {
description,
checks,
time,
error,
};
}