1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
6 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
7 | };
|
8 | Object.defineProperty(exports, "__esModule", { value: true });
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | const ms_1 = __importDefault(require("ms"));
|
18 | const chalk_1 = __importDefault(require("chalk"));
|
19 | const jest_diff_1 = __importDefault(require("jest-diff"));
|
20 | const utils_1 = require("../utils");
|
21 | const Contracts_1 = require("../Contracts");
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | const icons = {
|
27 | passed: chalk_1.default.green('✓'),
|
28 | failed: chalk_1.default.red('✖'),
|
29 | skipped: chalk_1.default.yellow('.'),
|
30 | todo: chalk_1.default.cyan('!'),
|
31 | regression: '',
|
32 | };
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | const colors = {
|
38 | passed: 'grey',
|
39 | failed: 'red',
|
40 | skipped: 'yellow',
|
41 | todo: 'cyan',
|
42 | regression: 'magenta',
|
43 | };
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | class ListReporter {
|
49 | constructor(emitter) {
|
50 | this._store = new utils_1.TestsStore();
|
51 | emitter.on(Contracts_1.IEvents.STARTED, this._onStart.bind(this));
|
52 | emitter.on(Contracts_1.IEvents.COMPLETED, this._onEnd.bind(this));
|
53 | emitter.on(Contracts_1.IEvents.GROUPSTARTED, this._onGroupStart.bind(this));
|
54 | emitter.on(Contracts_1.IEvents.GROUPCOMPLETED, this._onGroupEnd.bind(this));
|
55 | emitter.on(Contracts_1.IEvents.TESTCOMPLETED, this._onTestEnd.bind(this));
|
56 | }
|
57 | get _indent() {
|
58 | return this._store.activeGroup.title === 'root' ? '' : ' ';
|
59 | }
|
60 | |
61 |
|
62 |
|
63 |
|
64 | _onStart() {
|
65 | console.log('');
|
66 | this._store.open();
|
67 | }
|
68 | |
69 |
|
70 |
|
71 | _onGroupStart(group) {
|
72 | this._store.recordGroup(group);
|
73 | |
74 |
|
75 |
|
76 | if (group.title !== 'root') {
|
77 | console.log(`\n${group.title}`);
|
78 | }
|
79 | }
|
80 | |
81 |
|
82 |
|
83 | _onGroupEnd(group) {
|
84 | this._store.endGroup(group);
|
85 | }
|
86 | |
87 |
|
88 |
|
89 | _printCount(label, count) {
|
90 | if (count) {
|
91 | console.log(chalk_1.default.dim(`${label.padEnd(13)} : ${count}`));
|
92 | }
|
93 | }
|
94 | |
95 |
|
96 |
|
97 |
|
98 | _printTestError(error) {
|
99 | if ((0, utils_1.isCoreException)(error)) {
|
100 | console.log(chalk_1.default.red(` ${error.message}`));
|
101 | return;
|
102 | }
|
103 | const { actual, expected } = error;
|
104 | if (actual && expected) {
|
105 | const diff = (0, jest_diff_1.default)(expected, actual);
|
106 | const mainLine = this._cleanupErrorStack(error.stack)[1];
|
107 | if (mainLine) {
|
108 | console.log(chalk_1.default.dim(` source => ${mainLine.trim().replace(/at\s+/, '')}`));
|
109 | }
|
110 | if (diff) {
|
111 | console.log(diff);
|
112 | }
|
113 | else {
|
114 | console.log(chalk_1.default.red(` Assertion Error: ${error.message}`));
|
115 | }
|
116 | return;
|
117 | }
|
118 | console.log(` ${this._formatErrorStack(error.stack)}`);
|
119 | }
|
120 | |
121 |
|
122 |
|
123 | _onTestEnd(test) {
|
124 | this._store.recordTest(test);
|
125 | const icon = icons[test.status];
|
126 | const message = chalk_1.default[colors[test.status]](test.title);
|
127 | const duration = chalk_1.default.dim(`(${(0, ms_1.default)(test.duration)})`);
|
128 | const regressionMessage = test.regressionMessage
|
129 | ? `\n${this._indent} ${chalk_1.default.magenta(test.regressionMessage)}`
|
130 | : '';
|
131 | console.log(`${this._indent}${icon} ${message} ${duration}${regressionMessage}`);
|
132 | }
|
133 | |
134 |
|
135 |
|
136 |
|
137 | _isNativeStackLine(line) {
|
138 | return ['Callable'].some((keyword) => line.includes(keyword));
|
139 | }
|
140 | |
141 |
|
142 |
|
143 |
|
144 | _isNativeSorroundedLine(line) {
|
145 | return ['Generator.next', 'new Promise'].some((keyword) => line.includes(keyword));
|
146 | }
|
147 | |
148 |
|
149 |
|
150 | _getFailingTitle(title) {
|
151 | return chalk_1.default.red(`${icons.failed} ${title}`);
|
152 | }
|
153 | |
154 |
|
155 |
|
156 | _cleanupErrorStack(errorStack) {
|
157 | let prevIsNative = false;
|
158 | if (!errorStack) {
|
159 | return [];
|
160 | }
|
161 | return errorStack
|
162 | .split('\n')
|
163 | .filter((line) => {
|
164 | if (prevIsNative && this._isNativeSorroundedLine(line)) {
|
165 | return false;
|
166 | }
|
167 | prevIsNative = this._isNativeStackLine(line);
|
168 | return !prevIsNative;
|
169 | });
|
170 | }
|
171 | |
172 |
|
173 |
|
174 |
|
175 | _formatErrorStack(errorStack) {
|
176 | if (!errorStack) {
|
177 | return;
|
178 | }
|
179 | return this._cleanupErrorStack(errorStack).map((line, index) => {
|
180 | if (index === 0) {
|
181 | return chalk_1.default.red(line);
|
182 | }
|
183 | return chalk_1.default.dim(line);
|
184 | }).join('\n');
|
185 | }
|
186 | |
187 |
|
188 |
|
189 | _onEnd() {
|
190 | this._store.close();
|
191 | const report = this._store.getReport();
|
192 | |
193 |
|
194 |
|
195 | if (report.total === 0 && report.groups.length === 0) {
|
196 | console.log(chalk_1.default.bgMagenta.white(' ZERO TESTS EXECUTED '));
|
197 | return;
|
198 | }
|
199 | const failedGroups = report.groups.filter((group) => {
|
200 | return group.failedTests.length || group.failedHooks.length;
|
201 | });
|
202 | console.log('');
|
203 | if (failedGroups.length) {
|
204 | console.log(chalk_1.default.bgRed.white(' FAILED '));
|
205 | }
|
206 | else {
|
207 | console.log(chalk_1.default.bgGreen.white(' PASSED '));
|
208 | }
|
209 | console.log('');
|
210 | this._printCount('total', report.total);
|
211 | this._printCount('failed', report.failedCount);
|
212 | this._printCount('passed', report.passedCount);
|
213 | this._printCount('todo', report.todoCount);
|
214 | this._printCount('skipped', report.skippedCount);
|
215 | this._printCount('regression', report.regressionCount);
|
216 | this._printCount('duration', (0, ms_1.default)(report.duration));
|
217 | failedGroups.forEach(({ title, failedHooks, failedTests }) => {
|
218 | console.log('');
|
219 | console.log(failedHooks.length ? this._getFailingTitle(title) : title);
|
220 | if (failedHooks.length) {
|
221 | const failedHook = failedHooks[0];
|
222 | console.log(`${chalk_1.default.red(` (${failedHook.title})`)} ${this._formatErrorStack(failedHook.error.stack)}`);
|
223 | }
|
224 | if (failedTests.length) {
|
225 | failedTests.forEach((test) => {
|
226 | console.log('');
|
227 | console.log(` ${this._getFailingTitle(test.title)}`);
|
228 | this._printTestError(test.error);
|
229 | });
|
230 | }
|
231 | });
|
232 | }
|
233 | }
|
234 | function listReporter(emitter) {
|
235 | return new ListReporter(emitter);
|
236 | }
|
237 | exports.default = listReporter;
|