This repository was archived by the owner on Oct 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.ts
88 lines (84 loc) · 2.53 KB
/
index.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Backend from "../backend";
import { runnerConfiguration } from "../generator";
export interface IRunnerOptions {
maxLoop: number;
}
const defaultRunnerOptions: IRunnerOptions = {
maxLoop: 20,
};
const errorHandler = (
nTimes: number,
errors: Error[],
intermediaryErrors: Array<string | { message: string }>,
cb?: jest.DoneCallback,
) => {
// tslint:disable-next-line:max-line-length
const msg = (rest: string) =>
`This many tests failed: ${errors.length +
intermediaryErrors.length} out of ${nTimes}. Here's the first error.\n${rest}`;
if (errors.length) {
errors[0].message = msg(errors[0].message);
} else {
intermediaryErrors[0] =
typeof intermediaryErrors[0] === "string"
? msg(intermediaryErrors[0] as string)
: {
message: msg(
(intermediaryErrors[0] as { message: string }).message,
),
};
}
if (cb) {
cb.fail(
intermediaryErrors.length ? intermediaryErrors[0] : errors[0].message,
);
} else {
throw errors[0];
}
};
export default (backend: Backend) => (
fn?: jest.ProvidesCallback,
options?: Partial<IRunnerOptions>,
) => async (cb?: jest.DoneCallback) => {
const realOptions = {
...defaultRunnerOptions,
...options,
};
const intermediaryErrors: Array<string | { message: string }> = [];
const intermediaryDoneCallback: jest.DoneCallback = () => {
/**/
};
intermediaryDoneCallback.fail = (error: string | { message: string }) => {
intermediaryErrors.push(error);
};
const errors: Error[] = [];
const res = [];
for (let i = 0; i < realOptions.maxLoop; i++) {
backend.randomNumberGenerator.setSeed(i);
runnerConfiguration.optionalsProbability = Math.random();
runnerConfiguration.minItems = Math.floor(Math.random() * 2 ** (i % 5)); // 2^5 seems enough for min items/length
try {
const r = await (fn ? fn(intermediaryDoneCallback) : undefined);
res.push(r);
} catch (e) {
if (e.constructor.name === "JestAssertionError") {
errors.push(e);
} else {
throw e;
}
} finally {
// reset histories
Object.entries(backend.serviceStore.services).forEach(([_, service]) => {
service.spy.resetHistory();
});
}
}
runnerConfiguration.reset();
// >= in case fail is called multiple times... fix
if (errors.length + intermediaryErrors.length > 0) {
errorHandler(realOptions.maxLoop, errors, intermediaryErrors, cb);
} else {
// tslint:disable-next-line:no-unused-expression
cb && cb();
}
};