/
error.ts
150 lines (120 loc) · 3.29 KB
/
error.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import chalk from "chalk";
import cleanStack from "clean-stack";
import exit from "exit";
import { CLIError, formatError, handleError } from "../error";
jest.spyOn(console, "error").mockImplementation(() => {
// do nothing
});
jest.mock("exit");
describe("formatError", () => {
let stack: string;
let err: Error;
beforeEach(() => {
stack = formatError(err);
});
describe("when stack is undefined", () => {
beforeAll(() => {
err = new Error("foo");
delete err.stack;
});
test("should return message", () => {
expect(stack).toEqual(err.message);
});
});
describe("when stack is defined", () => {
beforeAll(() => {
err = new Error("foo");
});
test("should turn stack into gray", () => {
const [headline, ...rest] = cleanStack(err.stack!, {
pretty: true
}).split("\n");
expect(stack).toEqual(headline + chalk.gray("\n" + rest.join("\n")));
});
});
describe("when message is multi-line", () => {
beforeAll(() => {
err = new Error("foo\nbar");
});
test("should extract stack properly", () => {
const [first, second, ...rest] = cleanStack(err.stack!, {
pretty: true
}).split("\n");
expect(stack).toEqual(
first + "\n" + second + chalk.gray("\n" + rest.join("\n"))
);
});
});
});
describe("handleError", () => {
let err: any;
beforeEach(() => {
handleError(err);
});
describe("given a CLIError", () => {
describe("when output is set", () => {
beforeAll(() => {
err = new CLIError("err", { output: "foo" });
});
test("should print output", () => {
expect(console.error).toHaveBeenCalledWith("foo");
});
});
describe("when output is unset", () => {
beforeAll(() => {
err = new CLIError("err");
});
test("should print stack", () => {
expect(console.error).toHaveBeenCalledWith(formatError(err));
});
});
describe("when code is set", () => {
describe("and = 0", () => {
beforeAll(() => {
err = new CLIError("err", { code: 0 });
});
test("should exit with the code", () => {
expect(exit).toHaveBeenCalledWith(0);
});
});
describe("and != 0", () => {
beforeAll(() => {
err = new CLIError("err", { code: 46 });
});
test("should exit with the code", () => {
expect(exit).toHaveBeenCalledWith(46);
});
});
});
describe("when code is unset", () => {
beforeAll(() => {
err = new CLIError("err");
});
test("should exit with 1", () => {
expect(exit).toHaveBeenCalledWith(1);
});
});
});
describe("given a normal error", () => {
beforeAll(() => {
err = new Error("err");
});
test("should exit with 1", () => {
expect(exit).toHaveBeenCalledWith(1);
});
test("should print stack", () => {
expect(console.error).toHaveBeenCalledWith(formatError(err));
});
});
describe("given non-Error", () => {
beforeAll(() => {
err = "foo";
});
test("should exit with 1", () => {
expect(exit).toHaveBeenCalledWith(1);
});
test("should print stack", () => {
expect(console.error).toHaveBeenCalledWith(err);
});
});
});