ava 3.8.1 → 3.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +13 -2
- package/lib/assert.js +89 -14
- package/lib/cli.js +24 -11
- package/lib/code-excerpt.js +1 -1
- package/lib/concordance-options.js +0 -1
- package/lib/like-selector.js +37 -0
- package/lib/line-numbers.js +2 -2
- package/lib/load-config.js +1 -1
- package/lib/reporters/default.js +849 -0
- package/lib/reporters/tap.js +4 -1
- package/lib/runner.js +14 -5
- package/lib/test.js +27 -6
- package/lib/worker/subprocess.js +5 -3
- package/package.json +27 -26
- package/readme.md +1 -1
- package/lib/reporters/mini.js +0 -619
- package/lib/reporters/verbose.js +0 -463
package/lib/reporters/mini.js
DELETED
|
@@ -1,619 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const os = require('os');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const stream = require('stream');
|
|
5
|
-
|
|
6
|
-
const cliCursor = require('cli-cursor');
|
|
7
|
-
const figures = require('figures');
|
|
8
|
-
const indentString = require('indent-string');
|
|
9
|
-
const ora = require('ora');
|
|
10
|
-
const plur = require('plur');
|
|
11
|
-
const trimOffNewlines = require('trim-off-newlines');
|
|
12
|
-
const beautifyStack = require('./beautify-stack');
|
|
13
|
-
|
|
14
|
-
const chalk = require('../chalk').get();
|
|
15
|
-
const codeExcerpt = require('../code-excerpt');
|
|
16
|
-
const colors = require('./colors');
|
|
17
|
-
const formatSerializedError = require('./format-serialized-error');
|
|
18
|
-
const improperUsageMessages = require('./improper-usage-messages');
|
|
19
|
-
const prefixTitle = require('./prefix-title');
|
|
20
|
-
const whileCorked = require('./while-corked');
|
|
21
|
-
|
|
22
|
-
const nodeInternals = require('stack-utils').nodeInternals();
|
|
23
|
-
|
|
24
|
-
class LineWriter extends stream.Writable {
|
|
25
|
-
constructor(dest, spinner) {
|
|
26
|
-
super();
|
|
27
|
-
|
|
28
|
-
this.dest = dest;
|
|
29
|
-
this.columns = dest.columns || 80;
|
|
30
|
-
this.spinner = spinner;
|
|
31
|
-
this.lastSpinnerText = '';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
_write(chunk, encoding, callback) {
|
|
35
|
-
// Discard the current spinner output. Any lines that were meant to be
|
|
36
|
-
// preserved should be rewritten.
|
|
37
|
-
this.spinner.clear();
|
|
38
|
-
|
|
39
|
-
this._writeWithSpinner(chunk.toString('utf8'));
|
|
40
|
-
callback();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
_writev(pieces, callback) {
|
|
44
|
-
// Discard the current spinner output. Any lines that were meant to be
|
|
45
|
-
// preserved should be rewritten.
|
|
46
|
-
this.spinner.clear();
|
|
47
|
-
|
|
48
|
-
const last = pieces.pop();
|
|
49
|
-
for (const piece of pieces) {
|
|
50
|
-
this.dest.write(piece.chunk);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this._writeWithSpinner(last.chunk.toString('utf8'));
|
|
54
|
-
callback();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
_writeWithSpinner(string) {
|
|
58
|
-
if (!this.spinner.id) {
|
|
59
|
-
this.dest.write(string);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.lastSpinnerText = string;
|
|
64
|
-
// Ignore whitespace at the end of the chunk. We're continiously rewriting
|
|
65
|
-
// the last line through the spinner. Also be careful to remove the indent
|
|
66
|
-
// as the spinner adds its own.
|
|
67
|
-
this.spinner.text = string.trimEnd().slice(2);
|
|
68
|
-
this.spinner.render();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
writeLine(string) {
|
|
72
|
-
if (string) {
|
|
73
|
-
this.write(indentString(string, 2) + os.EOL);
|
|
74
|
-
} else {
|
|
75
|
-
this.write(os.EOL);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
class MiniReporter {
|
|
81
|
-
constructor(options) {
|
|
82
|
-
this.reportStream = options.reportStream;
|
|
83
|
-
this.stdStream = options.stdStream;
|
|
84
|
-
this.watching = options.watching;
|
|
85
|
-
|
|
86
|
-
this.spinner = ora({
|
|
87
|
-
isEnabled: true,
|
|
88
|
-
color: options.spinner ? options.spinner.color : 'gray',
|
|
89
|
-
discardStdin: !options.watching,
|
|
90
|
-
hideCursor: false,
|
|
91
|
-
spinner: options.spinner || (process.platform === 'win32' ? 'line' : 'dots'),
|
|
92
|
-
stream: options.reportStream
|
|
93
|
-
});
|
|
94
|
-
this.lineWriter = new LineWriter(this.reportStream, this.spinner);
|
|
95
|
-
|
|
96
|
-
this.consumeStateChange = whileCorked(this.reportStream, whileCorked(this.lineWriter, this.consumeStateChange));
|
|
97
|
-
this.endRun = whileCorked(this.reportStream, whileCorked(this.lineWriter, this.endRun));
|
|
98
|
-
this.relativeFile = file => path.relative(options.projectDir, file);
|
|
99
|
-
|
|
100
|
-
this.reset();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
reset() {
|
|
104
|
-
if (this.removePreviousListener) {
|
|
105
|
-
this.removePreviousListener();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.failFastEnabled = false;
|
|
109
|
-
this.failures = [];
|
|
110
|
-
this.filesWithMissingAvaImports = new Set();
|
|
111
|
-
this.filesWithoutDeclaredTests = new Set();
|
|
112
|
-
this.filesWithoutMatchedLineNumbers = new Set();
|
|
113
|
-
this.internalErrors = [];
|
|
114
|
-
this.knownFailures = [];
|
|
115
|
-
this.lineNumberErrors = [];
|
|
116
|
-
this.matching = false;
|
|
117
|
-
this.prefixTitle = (testFile, title) => title;
|
|
118
|
-
this.previousFailures = 0;
|
|
119
|
-
this.removePreviousListener = null;
|
|
120
|
-
this.stats = null;
|
|
121
|
-
this.uncaughtExceptions = [];
|
|
122
|
-
this.unhandledRejections = [];
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
startRun(plan) {
|
|
126
|
-
if (plan.bailWithoutReporting) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this.reset();
|
|
131
|
-
|
|
132
|
-
this.failFastEnabled = plan.failFastEnabled;
|
|
133
|
-
this.matching = plan.matching;
|
|
134
|
-
this.previousFailures = plan.previousFailures;
|
|
135
|
-
|
|
136
|
-
if (this.watching || plan.files.length > 1) {
|
|
137
|
-
this.prefixTitle = (testFile, title) => prefixTitle(plan.filePathPrefix, testFile, title);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
this.removePreviousListener = plan.status.on('stateChange', evt => this.consumeStateChange(evt));
|
|
141
|
-
|
|
142
|
-
if (this.watching && plan.runVector > 1) {
|
|
143
|
-
this.reportStream.write(chalk.gray.dim('\u2500'.repeat(this.lineWriter.columns)) + os.EOL);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
cliCursor.hide(this.reportStream);
|
|
147
|
-
this.lineWriter.writeLine();
|
|
148
|
-
|
|
149
|
-
this.spinner.start();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
consumeStateChange(evt) { // eslint-disable-line complexity
|
|
153
|
-
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
|
|
154
|
-
|
|
155
|
-
switch (evt.type) {
|
|
156
|
-
case 'declared-test':
|
|
157
|
-
// Ignore
|
|
158
|
-
break;
|
|
159
|
-
case 'hook-failed':
|
|
160
|
-
this.failures.push(evt);
|
|
161
|
-
this.writeTestSummary(evt);
|
|
162
|
-
break;
|
|
163
|
-
case 'internal-error':
|
|
164
|
-
this.internalErrors.push(evt);
|
|
165
|
-
if (evt.testFile) {
|
|
166
|
-
this.writeWithCounts(colors.error(`${figures.cross} Internal error when running ${this.relativeFile(evt.testFile)}`));
|
|
167
|
-
} else {
|
|
168
|
-
this.writeWithCounts(colors.error(`${figures.cross} Internal error`));
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
break;
|
|
172
|
-
case 'line-number-selection-error':
|
|
173
|
-
this.lineNumberErrors.push(evt);
|
|
174
|
-
this.writeWithCounts(colors.information(`${figures.warning} Could not parse ${this.relativeFile(evt.testFile)} for line number selection`));
|
|
175
|
-
break;
|
|
176
|
-
case 'missing-ava-import':
|
|
177
|
-
this.filesWithMissingAvaImports.add(evt.testFile);
|
|
178
|
-
this.writeWithCounts(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}, make sure to import "ava" at the top of your test file`));
|
|
179
|
-
break;
|
|
180
|
-
case 'selected-test':
|
|
181
|
-
// Ignore
|
|
182
|
-
break;
|
|
183
|
-
case 'stats':
|
|
184
|
-
this.stats = evt.stats;
|
|
185
|
-
break;
|
|
186
|
-
case 'test-failed':
|
|
187
|
-
this.failures.push(evt);
|
|
188
|
-
this.writeTestSummary(evt);
|
|
189
|
-
break;
|
|
190
|
-
case 'test-passed':
|
|
191
|
-
if (evt.knownFailing) {
|
|
192
|
-
this.knownFailures.push(evt);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
this.writeTestSummary(evt);
|
|
196
|
-
break;
|
|
197
|
-
case 'timeout':
|
|
198
|
-
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Timed out while running tests`));
|
|
199
|
-
this.lineWriter.writeLine('');
|
|
200
|
-
this.writePendingTests(evt);
|
|
201
|
-
break;
|
|
202
|
-
case 'interrupt':
|
|
203
|
-
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Exiting due to SIGINT`));
|
|
204
|
-
this.lineWriter.writeLine('');
|
|
205
|
-
this.writePendingTests(evt);
|
|
206
|
-
break;
|
|
207
|
-
case 'uncaught-exception':
|
|
208
|
-
this.uncaughtExceptions.push(evt);
|
|
209
|
-
break;
|
|
210
|
-
case 'unhandled-rejection':
|
|
211
|
-
this.unhandledRejections.push(evt);
|
|
212
|
-
break;
|
|
213
|
-
case 'worker-failed':
|
|
214
|
-
if (fileStats.declaredTests === 0) {
|
|
215
|
-
this.filesWithoutDeclaredTests.add(evt.testFile);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
break;
|
|
219
|
-
case 'worker-finished':
|
|
220
|
-
if (fileStats.declaredTests === 0) {
|
|
221
|
-
this.filesWithoutDeclaredTests.add(evt.testFile);
|
|
222
|
-
this.writeWithCounts(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}`));
|
|
223
|
-
} else if (fileStats.selectingLines && fileStats.selectedTests === 0) {
|
|
224
|
-
this.filesWithoutMatchedLineNumbers.add(evt.testFile);
|
|
225
|
-
this.writeWithCounts(colors.error(`${figures.cross} Line numbers for ${this.relativeFile(evt.testFile)} did not match any tests`));
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
break;
|
|
229
|
-
case 'worker-stderr':
|
|
230
|
-
case 'worker-stdout':
|
|
231
|
-
// Forcibly clear the spinner, writing the chunk corrupts the TTY.
|
|
232
|
-
this.spinner.clear();
|
|
233
|
-
|
|
234
|
-
this.stdStream.write(evt.chunk);
|
|
235
|
-
// If the chunk does not end with a linebreak, *forcibly* write one to
|
|
236
|
-
// ensure it remains visible in the TTY.
|
|
237
|
-
// Tests cannot assume their standard output is not interrupted. Indeed
|
|
238
|
-
// we multiplex stdout and stderr into a single stream. However as
|
|
239
|
-
// long as stdStream is different from reportStream users can read
|
|
240
|
-
// their original output by redirecting the streams.
|
|
241
|
-
if (evt.chunk[evt.chunk.length - 1] !== 0x0A) {
|
|
242
|
-
// Use write() rather than writeLine() so the (presumably corked)
|
|
243
|
-
// line writer will actually write the empty line before re-rendering
|
|
244
|
-
// the last spinner text below.
|
|
245
|
-
this.lineWriter.write(os.EOL);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
this.lineWriter.write(this.lineWriter.lastSpinnerText);
|
|
249
|
-
break;
|
|
250
|
-
default:
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
writeWithCounts(string) {
|
|
256
|
-
if (!this.stats) {
|
|
257
|
-
return this.lineWriter.writeLine(string);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
string = string || '';
|
|
261
|
-
if (string !== '') {
|
|
262
|
-
string += os.EOL;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
let firstLinePostfix = this.watching ?
|
|
266
|
-
' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']') :
|
|
267
|
-
'';
|
|
268
|
-
|
|
269
|
-
if (this.stats.passedTests > 0) {
|
|
270
|
-
string += os.EOL + colors.pass(`${this.stats.passedTests} passed`) + firstLinePostfix;
|
|
271
|
-
firstLinePostfix = '';
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (this.stats.passedKnownFailingTests > 0) {
|
|
275
|
-
string += os.EOL + colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (this.stats.failedHooks > 0) {
|
|
279
|
-
string += os.EOL + colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix;
|
|
280
|
-
firstLinePostfix = '';
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (this.stats.failedTests > 0) {
|
|
284
|
-
string += os.EOL + colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix;
|
|
285
|
-
firstLinePostfix = '';
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (this.stats.skippedTests > 0) {
|
|
289
|
-
string += os.EOL + colors.skip(`${this.stats.skippedTests} skipped`);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (this.stats.todoTests > 0) {
|
|
293
|
-
string += os.EOL + colors.todo(`${this.stats.todoTests} todo`);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
this.lineWriter.writeLine(string);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
writeErr(evt) {
|
|
300
|
-
if (evt.err.name === 'TSError' && evt.err.object && evt.err.object.diagnosticText) {
|
|
301
|
-
this.lineWriter.writeLine(colors.errorStack(trimOffNewlines(evt.err.object.diagnosticText)));
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (evt.err.source) {
|
|
306
|
-
this.lineWriter.writeLine(colors.errorSource(`${this.relativeFile(evt.err.source.file)}:${evt.err.source.line}`));
|
|
307
|
-
const excerpt = codeExcerpt(evt.err.source, {maxWidth: this.lineWriter.columns - 2});
|
|
308
|
-
if (excerpt) {
|
|
309
|
-
this.lineWriter.writeLine();
|
|
310
|
-
this.lineWriter.writeLine(excerpt);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (evt.err.avaAssertionError) {
|
|
315
|
-
const result = formatSerializedError(evt.err);
|
|
316
|
-
if (result.printMessage) {
|
|
317
|
-
this.lineWriter.writeLine();
|
|
318
|
-
this.lineWriter.writeLine(evt.err.message);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (result.formatted) {
|
|
322
|
-
this.lineWriter.writeLine();
|
|
323
|
-
this.lineWriter.writeLine(result.formatted);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const message = improperUsageMessages.forError(evt.err);
|
|
327
|
-
if (message) {
|
|
328
|
-
this.lineWriter.writeLine();
|
|
329
|
-
this.lineWriter.writeLine(message);
|
|
330
|
-
}
|
|
331
|
-
} else if (evt.err.nonErrorObject) {
|
|
332
|
-
this.lineWriter.writeLine(trimOffNewlines(evt.err.formatted));
|
|
333
|
-
} else {
|
|
334
|
-
this.lineWriter.writeLine();
|
|
335
|
-
this.lineWriter.writeLine(evt.err.summary);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
const formatted = this.formatErrorStack(evt.err);
|
|
339
|
-
if (formatted.length > 0) {
|
|
340
|
-
this.lineWriter.writeLine();
|
|
341
|
-
this.lineWriter.writeLine(formatted.join('\n'));
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
formatErrorStack(error) {
|
|
346
|
-
if (!error.stack) {
|
|
347
|
-
return [];
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (error.shouldBeautifyStack) {
|
|
351
|
-
return beautifyStack(error.stack).map(line => {
|
|
352
|
-
if (nodeInternals.some(internal => internal.test(line))) {
|
|
353
|
-
return colors.errorStackInternal(`${figures.pointerSmall} ${line}`);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
return colors.errorStack(`${figures.pointerSmall} ${line}`);
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return [error.stack];
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
writeLogs(evt) {
|
|
364
|
-
if (evt.logs) {
|
|
365
|
-
for (const log of evt.logs) {
|
|
366
|
-
const logLines = indentString(colors.log(log), 4);
|
|
367
|
-
const logLinesWithLeadingFigure = logLines.replace(
|
|
368
|
-
/^ {4}/,
|
|
369
|
-
` ${colors.information(figures.info)} `
|
|
370
|
-
);
|
|
371
|
-
this.lineWriter.writeLine(logLinesWithLeadingFigure);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
writeTestSummary(evt) {
|
|
377
|
-
if (evt.type === 'hook-failed' || evt.type === 'test-failed') {
|
|
378
|
-
this.writeWithCounts(`${this.prefixTitle(evt.testFile, evt.title)}`);
|
|
379
|
-
} else if (evt.knownFailing) {
|
|
380
|
-
this.writeWithCounts(`${colors.error(this.prefixTitle(evt.testFile, evt.title))}`);
|
|
381
|
-
} else {
|
|
382
|
-
this.writeWithCounts(`${this.prefixTitle(evt.testFile, evt.title)}`);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
writeFailure(evt) {
|
|
387
|
-
this.lineWriter.writeLine(`${colors.title(this.prefixTitle(evt.testFile, evt.title))}`);
|
|
388
|
-
this.writeLogs(evt);
|
|
389
|
-
this.lineWriter.writeLine();
|
|
390
|
-
this.writeErr(evt);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
writePendingTests(evt) {
|
|
394
|
-
for (const [file, testsInFile] of evt.pendingTests) {
|
|
395
|
-
if (testsInFile.size === 0) {
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
this.lineWriter.writeLine(`${testsInFile.size} tests were pending in ${this.relativeFile(file)}\n`);
|
|
400
|
-
for (const title of testsInFile) {
|
|
401
|
-
this.lineWriter.writeLine(`${figures.circleDotted} ${this.prefixTitle(file, title)}`);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
this.lineWriter.writeLine('');
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
endRun() { // eslint-disable-line complexity
|
|
409
|
-
this.spinner.stop();
|
|
410
|
-
cliCursor.show(this.reportStream);
|
|
411
|
-
|
|
412
|
-
if (!this.stats) {
|
|
413
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldn’t find any files to test`));
|
|
414
|
-
this.lineWriter.writeLine();
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (this.matching && this.stats.selectedTests === 0) {
|
|
419
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldn’t find any matching tests`));
|
|
420
|
-
this.lineWriter.writeLine();
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
this.lineWriter.writeLine();
|
|
425
|
-
|
|
426
|
-
let firstLinePostfix = this.watching ?
|
|
427
|
-
' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']') :
|
|
428
|
-
'';
|
|
429
|
-
|
|
430
|
-
if (this.filesWithMissingAvaImports.size > 0) {
|
|
431
|
-
for (const testFile of this.filesWithMissingAvaImports) {
|
|
432
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(testFile)}, make sure to import "ava" at the top of your test file`) + firstLinePostfix);
|
|
433
|
-
firstLinePostfix = '';
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (this.filesWithoutDeclaredTests.size > 0) {
|
|
438
|
-
for (const testFile of this.filesWithoutDeclaredTests) {
|
|
439
|
-
if (!this.filesWithMissingAvaImports.has(testFile)) {
|
|
440
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(testFile)}`) + firstLinePostfix);
|
|
441
|
-
firstLinePostfix = '';
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
if (this.lineNumberErrors.length > 0) {
|
|
447
|
-
for (const evt of this.lineNumberErrors) {
|
|
448
|
-
this.lineWriter.writeLine(colors.information(`${figures.warning} Could not parse ${this.relativeFile(evt.testFile)} for line number selection`));
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
if (this.filesWithoutMatchedLineNumbers.size > 0) {
|
|
453
|
-
for (const testFile of this.filesWithoutMatchedLineNumbers) {
|
|
454
|
-
if (!this.filesWithMissingAvaImports.has(testFile) && !this.filesWithoutDeclaredTests.has(testFile)) {
|
|
455
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} Line numbers for ${this.relativeFile(testFile)} did not match any tests`) + firstLinePostfix);
|
|
456
|
-
firstLinePostfix = '';
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
if (this.filesWithMissingAvaImports.size > 0 || this.filesWithoutDeclaredTests.size > 0 || this.filesWithoutMatchedLineNumbers.size > 0) {
|
|
462
|
-
this.lineWriter.writeLine();
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
if (this.stats.failedHooks > 0) {
|
|
466
|
-
this.lineWriter.writeLine(colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix);
|
|
467
|
-
firstLinePostfix = '';
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (this.stats.failedTests > 0) {
|
|
471
|
-
this.lineWriter.writeLine(colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix);
|
|
472
|
-
firstLinePostfix = '';
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (this.stats.failedHooks === 0 && this.stats.failedTests === 0 && this.stats.passedTests > 0) {
|
|
476
|
-
this.lineWriter.writeLine(colors.pass(`${this.stats.passedTests} ${plur('test', this.stats.passedTests)} passed`) + firstLinePostfix);
|
|
477
|
-
firstLinePostfix = '';
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
if (this.stats.passedKnownFailingTests > 0) {
|
|
481
|
-
this.lineWriter.writeLine(colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`));
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
if (this.stats.skippedTests > 0) {
|
|
485
|
-
this.lineWriter.writeLine(colors.skip(`${this.stats.skippedTests} ${plur('test', this.stats.skippedTests)} skipped`));
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (this.stats.todoTests > 0) {
|
|
489
|
-
this.lineWriter.writeLine(colors.todo(`${this.stats.todoTests} ${plur('test', this.stats.todoTests)} todo`));
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
if (this.stats.unhandledRejections > 0) {
|
|
493
|
-
this.lineWriter.writeLine(colors.error(`${this.stats.unhandledRejections} unhandled ${plur('rejection', this.stats.unhandledRejections)}`));
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
if (this.stats.uncaughtExceptions > 0) {
|
|
497
|
-
this.lineWriter.writeLine(colors.error(`${this.stats.uncaughtExceptions} uncaught ${plur('exception', this.stats.uncaughtExceptions)}`));
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
if (this.previousFailures > 0) {
|
|
501
|
-
this.lineWriter.writeLine(colors.error(`${this.previousFailures} previous ${plur('failure', this.previousFailures)} in test files that were not rerun`));
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
if (this.stats.passedKnownFailingTests > 0) {
|
|
505
|
-
this.lineWriter.writeLine();
|
|
506
|
-
for (const evt of this.knownFailures) {
|
|
507
|
-
this.lineWriter.writeLine(colors.error(this.prefixTitle(evt.testFile, evt.title)));
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const shouldWriteFailFastDisclaimer = this.failFastEnabled && (this.stats.remainingTests > 0 || this.stats.files > this.stats.finishedWorkers);
|
|
512
|
-
|
|
513
|
-
if (this.failures.length > 0) {
|
|
514
|
-
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.internalErrors.length > 0 || this.uncaughtExceptions.length > 0 || this.unhandledRejections.length > 0;
|
|
515
|
-
this.lineWriter.writeLine();
|
|
516
|
-
|
|
517
|
-
const last = this.failures[this.failures.length - 1];
|
|
518
|
-
for (const evt of this.failures) {
|
|
519
|
-
this.writeFailure(evt);
|
|
520
|
-
if (evt !== last || writeTrailingLines) {
|
|
521
|
-
this.lineWriter.writeLine();
|
|
522
|
-
this.lineWriter.writeLine();
|
|
523
|
-
this.lineWriter.writeLine();
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (this.internalErrors.length > 0) {
|
|
529
|
-
const writeLeadingLine = this.failures.length === 0;
|
|
530
|
-
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.uncaughtExceptions.length > 0 || this.unhandledRejections.length > 0;
|
|
531
|
-
|
|
532
|
-
if (writeLeadingLine) {
|
|
533
|
-
this.lineWriter.writeLine();
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
const last = this.internalErrors[this.internalErrors.length - 1];
|
|
537
|
-
for (const evt of this.internalErrors) {
|
|
538
|
-
if (evt.testFile) {
|
|
539
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error when running ${this.relativeFile(evt.testFile)}`));
|
|
540
|
-
} else {
|
|
541
|
-
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error`));
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
this.lineWriter.writeLine(colors.stack(evt.err.summary));
|
|
545
|
-
this.lineWriter.writeLine(colors.errorStack(evt.err.stack));
|
|
546
|
-
if (evt !== last || writeTrailingLines) {
|
|
547
|
-
this.lineWriter.writeLine();
|
|
548
|
-
this.lineWriter.writeLine();
|
|
549
|
-
this.lineWriter.writeLine();
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
if (this.uncaughtExceptions.length > 0) {
|
|
555
|
-
const writeLeadingLine = this.failures.length === 0 && this.internalErrors.length === 0;
|
|
556
|
-
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.unhandledRejections.length > 0;
|
|
557
|
-
|
|
558
|
-
if (writeLeadingLine) {
|
|
559
|
-
this.lineWriter.writeLine();
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const last = this.uncaughtExceptions[this.uncaughtExceptions.length - 1];
|
|
563
|
-
for (const evt of this.uncaughtExceptions) {
|
|
564
|
-
this.lineWriter.writeLine(colors.title(`Uncaught exception in ${this.relativeFile(evt.testFile)}`));
|
|
565
|
-
this.lineWriter.writeLine();
|
|
566
|
-
this.writeErr(evt);
|
|
567
|
-
if (evt !== last || writeTrailingLines) {
|
|
568
|
-
this.lineWriter.writeLine();
|
|
569
|
-
this.lineWriter.writeLine();
|
|
570
|
-
this.lineWriter.writeLine();
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (this.unhandledRejections.length > 0) {
|
|
576
|
-
const writeLeadingLine = this.failures.length === 0 && this.internalErrors.length === 0 && this.uncaughtExceptions.length === 0;
|
|
577
|
-
const writeTrailingLines = shouldWriteFailFastDisclaimer;
|
|
578
|
-
|
|
579
|
-
if (writeLeadingLine) {
|
|
580
|
-
this.lineWriter.writeLine();
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
const last = this.unhandledRejections[this.unhandledRejections.length - 1];
|
|
584
|
-
for (const evt of this.unhandledRejections) {
|
|
585
|
-
this.lineWriter.writeLine(colors.title(`Unhandled rejection in ${this.relativeFile(evt.testFile)}`));
|
|
586
|
-
this.lineWriter.writeLine();
|
|
587
|
-
this.writeErr(evt);
|
|
588
|
-
if (evt !== last || writeTrailingLines) {
|
|
589
|
-
this.lineWriter.writeLine();
|
|
590
|
-
this.lineWriter.writeLine();
|
|
591
|
-
this.lineWriter.writeLine();
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
if (shouldWriteFailFastDisclaimer) {
|
|
597
|
-
let remaining = '';
|
|
598
|
-
if (this.stats.remainingTests > 0) {
|
|
599
|
-
remaining += `At least ${this.stats.remainingTests} ${plur('test was', 'tests were', this.stats.remainingTests)} skipped`;
|
|
600
|
-
if (this.stats.files > this.stats.finishedWorkers) {
|
|
601
|
-
remaining += ', as well as ';
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (this.stats.files > this.stats.finishedWorkers) {
|
|
606
|
-
const skippedFileCount = this.stats.files - this.stats.finishedWorkers;
|
|
607
|
-
remaining += `${skippedFileCount} ${plur('test file', 'test files', skippedFileCount)}`;
|
|
608
|
-
if (this.stats.remainingTests === 0) {
|
|
609
|
-
remaining += ` ${plur('was', 'were', skippedFileCount)} skipped`;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
this.lineWriter.writeLine(colors.information(`\`--fail-fast\` is on. ${remaining}.`));
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
this.lineWriter.writeLine();
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
module.exports = MiniReporter;
|