-
Notifications
You must be signed in to change notification settings - Fork 220
/
Copy pathstacktrace.spec.ts
92 lines (84 loc) · 2.42 KB
/
stacktrace.spec.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
89
90
91
92
import suite from "../test-suite";
import {spawn} from "child_process";
suite(__filename, s => {
s.case("setTimeout", async () => {
const cherrypie = async () => {
await new Promise((resolve, reject) => setTimeout(resolve, 10));
throw new Error(`after timeout`);
};
const binomial = async () => await cherrypie();
const abacus = async () => await binomial();
await checkStack(s, abacus());
});
s.case("spawn", async () => {
const cherrypie = async () => {
let e: Error;
const code = await new Promise<number>((resolve, reject) => {
const child = spawn("i do not exist");
child.on("close", () => resolve(2));
child.on("error", (e2) => {
e = e2;
resolve(4);
});
});
s.is(code, 4);
if (e) {
throw e;
}
};
const binomial = async () => await cherrypie();
const abacus = async () => await binomial();
await checkStack(s, abacus());
});
s.case("after-await", async () => {
const literallyAnything = async () => null;
const cherrypie = async () => {
await literallyAnything();
throw new Error("in nested");
};
const binomial = async () => await cherrypie();
const abacus = async () => await binomial();
await checkStack(s, abacus());
});
s.case("after-await-thrower", async () => {
const literallyAnything = async () => null;
const thrower = async () => { throw new Error("oh no"); };
const cherrypie = async () => {
await literallyAnything();
await thrower();
};
const binomial = async () => await cherrypie();
const abacus = async () => await binomial();
await checkStack(s, abacus());
});
});
async function checkStack(t, promise: Promise<any>) {
let threw = false;
try {
await promise;
} catch (e) {
threw = true;
let seen = { a: false, b: false, c: false };
for (const line of e.stack.split("\n")) {
if (/at abacus /.test(line)) {
seen.a = true;
}
if (/at binomial /.test(line)) {
seen.b = true;
}
if (/at cherrypie /.test(line)) {
seen.c = true;
}
}
if (!seen.a || !seen.b || !seen.c) {
// tslint:disable-next-line
console.log(`Offensive stack trace:\n${e.stack}`);
}
t.true(seen.a, "seen a");
t.true(seen.b, "seen b");
t.true(seen.c, "seen c");
}
if (!threw) {
throw new Error(`should reject`);
}
}