ava 3.7.1 → 3.9.0
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 +18 -1
- package/lib/api.js +9 -2
- package/lib/assert.js +62 -6
- package/lib/cli.js +28 -15
- package/lib/code-excerpt.js +1 -1
- package/lib/concordance-options.js +0 -1
- package/lib/fork.js +3 -1
- package/lib/globs.js +17 -13
- package/lib/like-selector.js +37 -0
- package/lib/line-numbers.js +64 -0
- package/lib/load-config.js +1 -1
- package/lib/reporters/beautify-stack.js +73 -0
- package/lib/reporters/colors.js +1 -0
- package/lib/reporters/default.js +834 -0
- package/lib/reporters/tap.js +3 -2
- package/lib/run-status.js +8 -2
- package/lib/runner.js +21 -3
- package/lib/serialize-error.js +30 -17
- package/lib/test.js +43 -1
- package/lib/watcher.js +4 -1
- package/lib/worker/line-numbers.js +90 -0
- package/lib/worker/subprocess.js +21 -6
- package/package.json +27 -72
- package/readme.md +1 -1
- package/lib/beautify-stack.js +0 -75
- package/lib/reporters/mini.js +0 -573
- package/lib/reporters/verbose.js +0 -440
package/lib/reporters/tap.js
CHANGED
|
@@ -7,6 +7,7 @@ const stripAnsi = require('strip-ansi');
|
|
|
7
7
|
const supertap = require('supertap');
|
|
8
8
|
const indentString = require('indent-string');
|
|
9
9
|
|
|
10
|
+
const beautifyStack = require('./beautify-stack');
|
|
10
11
|
const prefixTitle = require('./prefix-title');
|
|
11
12
|
|
|
12
13
|
function dumpError(error) {
|
|
@@ -29,7 +30,7 @@ function dumpError(error) {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
if (error.values.length > 0) {
|
|
32
|
-
object.values = error.values.reduce((acc, value) => {
|
|
33
|
+
object.values = error.values.reduce((acc, value) => { // eslint-disable-line unicorn/no-reduce
|
|
33
34
|
acc[value.label] = stripAnsi(value.formatted);
|
|
34
35
|
return acc;
|
|
35
36
|
}, {});
|
|
@@ -42,7 +43,7 @@ function dumpError(error) {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
if (error.stack) {
|
|
45
|
-
object.at = error.stack;
|
|
46
|
+
object.at = error.shouldBeautifyStack ? beautifyStack(error.stack).join('\n') : error.stack;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
return object;
|
package/lib/run-status.js
CHANGED
|
@@ -35,7 +35,7 @@ class RunStatus extends Emittery {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
observeWorker(worker, testFile) {
|
|
38
|
+
observeWorker(worker, testFile, stats) {
|
|
39
39
|
this.stats.byFile.set(testFile, {
|
|
40
40
|
declaredTests: 0,
|
|
41
41
|
failedHooks: 0,
|
|
@@ -45,10 +45,12 @@ class RunStatus extends Emittery {
|
|
|
45
45
|
passedKnownFailingTests: 0,
|
|
46
46
|
passedTests: 0,
|
|
47
47
|
selectedTests: 0,
|
|
48
|
+
selectingLines: false,
|
|
48
49
|
skippedTests: 0,
|
|
49
50
|
todoTests: 0,
|
|
50
51
|
uncaughtExceptions: 0,
|
|
51
|
-
unhandledRejections: 0
|
|
52
|
+
unhandledRejections: 0,
|
|
53
|
+
...stats
|
|
52
54
|
});
|
|
53
55
|
|
|
54
56
|
this.pendingTests.set(testFile, new Set());
|
|
@@ -169,6 +171,10 @@ class RunStatus extends Emittery {
|
|
|
169
171
|
return 1;
|
|
170
172
|
}
|
|
171
173
|
|
|
174
|
+
if ([...this.stats.byFile.values()].some(stats => stats.selectingLines && stats.selectedTests === 0)) {
|
|
175
|
+
return 1;
|
|
176
|
+
}
|
|
177
|
+
|
|
172
178
|
return 0;
|
|
173
179
|
}
|
|
174
180
|
|
package/lib/runner.js
CHANGED
|
@@ -16,6 +16,7 @@ class Runner extends Emittery {
|
|
|
16
16
|
this.failFast = options.failFast === true;
|
|
17
17
|
this.failWithoutAssertions = options.failWithoutAssertions !== false;
|
|
18
18
|
this.file = options.file;
|
|
19
|
+
this.checkSelectedByLineNumbers = options.checkSelectedByLineNumbers;
|
|
19
20
|
this.match = options.match || [];
|
|
20
21
|
this.powerAssert = undefined; // Assigned later.
|
|
21
22
|
this.projectDir = options.projectDir;
|
|
@@ -75,6 +76,10 @@ class Runner extends Emittery {
|
|
|
75
76
|
|
|
76
77
|
const {args, buildTitle, implementations, rawTitle} = parseTestArgs(testArgs);
|
|
77
78
|
|
|
79
|
+
if (this.checkSelectedByLineNumbers) {
|
|
80
|
+
metadata.selected = this.checkSelectedByLineNumbers();
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
if (metadata.todo) {
|
|
79
84
|
if (implementations.length > 0) {
|
|
80
85
|
throw new TypeError('`todo` tests are not allowed to have an implementation. Use `test.skip()` for tests with an implementation.');
|
|
@@ -236,7 +241,7 @@ class Runner extends Emittery {
|
|
|
236
241
|
};
|
|
237
242
|
|
|
238
243
|
let waitForSerial = Promise.resolve();
|
|
239
|
-
await runnables.reduce((previous, runnable) => {
|
|
244
|
+
await runnables.reduce((previous, runnable) => { // eslint-disable-line unicorn/no-reduce
|
|
240
245
|
if (runnable.metadata.serial || this.serial) {
|
|
241
246
|
waitForSerial = previous.then(() => {
|
|
242
247
|
// Serial runnables run as long as there was no previous failure, unless
|
|
@@ -283,6 +288,7 @@ class Runner extends Emittery {
|
|
|
283
288
|
metadata: task.metadata,
|
|
284
289
|
powerAssert: this.powerAssert,
|
|
285
290
|
title: `${task.title}${titleSuffix || ''}`,
|
|
291
|
+
isHook: true,
|
|
286
292
|
testPassed
|
|
287
293
|
}));
|
|
288
294
|
const outcome = await this.runMultiple(hooks, this.serial);
|
|
@@ -347,7 +353,7 @@ class Runner extends Emittery {
|
|
|
347
353
|
this.emit('stateChange', {
|
|
348
354
|
type: 'test-failed',
|
|
349
355
|
title: result.title,
|
|
350
|
-
err: serializeError('Test failure', true, result.error),
|
|
356
|
+
err: serializeError('Test failure', true, result.error, this.file),
|
|
351
357
|
duration: result.duration,
|
|
352
358
|
knownFailing: result.metadata.failing,
|
|
353
359
|
logs: result.logs
|
|
@@ -368,6 +374,10 @@ class Runner extends Emittery {
|
|
|
368
374
|
continue;
|
|
369
375
|
}
|
|
370
376
|
|
|
377
|
+
if (this.checkSelectedByLineNumbers && !task.metadata.selected) {
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
|
|
371
381
|
this.emit('stateChange', {
|
|
372
382
|
type: 'selected-test',
|
|
373
383
|
title: task.title,
|
|
@@ -386,6 +396,10 @@ class Runner extends Emittery {
|
|
|
386
396
|
continue;
|
|
387
397
|
}
|
|
388
398
|
|
|
399
|
+
if (this.checkSelectedByLineNumbers && !task.metadata.selected) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
389
403
|
this.emit('stateChange', {
|
|
390
404
|
type: 'selected-test',
|
|
391
405
|
title: task.title,
|
|
@@ -408,6 +422,10 @@ class Runner extends Emittery {
|
|
|
408
422
|
continue;
|
|
409
423
|
}
|
|
410
424
|
|
|
425
|
+
if (this.checkSelectedByLineNumbers && !task.metadata.selected) {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
|
|
411
429
|
this.emit('stateChange', {
|
|
412
430
|
type: 'selected-test',
|
|
413
431
|
title: task.title,
|
|
@@ -433,7 +451,7 @@ class Runner extends Emittery {
|
|
|
433
451
|
return false;
|
|
434
452
|
}
|
|
435
453
|
|
|
436
|
-
return serialTests.reduce(async (previous, task) => {
|
|
454
|
+
return serialTests.reduce(async (previous, task) => { // eslint-disable-line unicorn/no-reduce
|
|
437
455
|
const previousOk = await previous;
|
|
438
456
|
// Don't start tests after an interrupt.
|
|
439
457
|
if (this.interrupted) {
|
package/lib/serialize-error.js
CHANGED
|
@@ -3,9 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const cleanYamlObject = require('clean-yaml-object');
|
|
4
4
|
const concordance = require('concordance');
|
|
5
5
|
const isError = require('is-error');
|
|
6
|
+
const slash = require('slash');
|
|
6
7
|
const StackUtils = require('stack-utils');
|
|
7
8
|
const assert = require('./assert');
|
|
8
|
-
const beautifyStack = require('./beautify-stack');
|
|
9
9
|
const concordanceOptions = require('./concordance-options').default;
|
|
10
10
|
|
|
11
11
|
function isAvaAssertionError(source) {
|
|
@@ -17,13 +17,29 @@ function filter(propertyName, isRoot) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const stackUtils = new StackUtils();
|
|
20
|
-
function extractSource(stack) {
|
|
21
|
-
if (!stack) {
|
|
20
|
+
function extractSource(stack, testFile) {
|
|
21
|
+
if (!stack || !testFile) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
// Normalize the test file so it matches `callSite.file`.
|
|
26
|
+
const relFile = path.relative(process.cwd(), testFile);
|
|
27
|
+
const normalizedFile = process.platform === 'win32' ? slash(relFile) : relFile;
|
|
28
|
+
for (const line of stack.split('\n')) {
|
|
29
|
+
try {
|
|
30
|
+
const callSite = stackUtils.parseLine(line);
|
|
31
|
+
if (callSite.file === normalizedFile) {
|
|
32
|
+
return {
|
|
33
|
+
isDependency: false,
|
|
34
|
+
isWithinProject: true,
|
|
35
|
+
file: path.resolve(process.cwd(), callSite.file),
|
|
36
|
+
line: callSite.line
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
27
43
|
}
|
|
28
44
|
|
|
29
45
|
function buildSource(source) {
|
|
@@ -51,22 +67,19 @@ function buildSource(source) {
|
|
|
51
67
|
};
|
|
52
68
|
}
|
|
53
69
|
|
|
54
|
-
function trySerializeError(err, shouldBeautifyStack) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (shouldBeautifyStack) {
|
|
58
|
-
stack = beautifyStack(stack);
|
|
59
|
-
}
|
|
70
|
+
function trySerializeError(err, shouldBeautifyStack, testFile) {
|
|
71
|
+
const stack = err.savedError ? err.savedError.stack : err.stack;
|
|
60
72
|
|
|
61
73
|
const retval = {
|
|
62
74
|
avaAssertionError: isAvaAssertionError(err),
|
|
63
75
|
nonErrorObject: false,
|
|
64
|
-
source:
|
|
65
|
-
stack
|
|
76
|
+
source: extractSource(stack, testFile),
|
|
77
|
+
stack,
|
|
78
|
+
shouldBeautifyStack
|
|
66
79
|
};
|
|
67
80
|
|
|
68
81
|
if (err.actualStack) {
|
|
69
|
-
retval.stack =
|
|
82
|
+
retval.stack = err.actualStack;
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
if (retval.avaAssertionError) {
|
|
@@ -133,7 +146,7 @@ function trySerializeError(err, shouldBeautifyStack) {
|
|
|
133
146
|
return retval;
|
|
134
147
|
}
|
|
135
148
|
|
|
136
|
-
function serializeError(origin, shouldBeautifyStack, err) {
|
|
149
|
+
function serializeError(origin, shouldBeautifyStack, err, testFile) {
|
|
137
150
|
if (!isError(err)) {
|
|
138
151
|
return {
|
|
139
152
|
avaAssertionError: false,
|
|
@@ -143,8 +156,8 @@ function serializeError(origin, shouldBeautifyStack, err) {
|
|
|
143
156
|
}
|
|
144
157
|
|
|
145
158
|
try {
|
|
146
|
-
return trySerializeError(err, shouldBeautifyStack);
|
|
147
|
-
} catch
|
|
159
|
+
return trySerializeError(err, shouldBeautifyStack, testFile);
|
|
160
|
+
} catch {
|
|
148
161
|
const replacement = new Error(`${origin}: Could not serialize error`);
|
|
149
162
|
return {
|
|
150
163
|
avaAssertionError: false,
|
package/lib/test.js
CHANGED
|
@@ -39,7 +39,8 @@ class ExecutionContext extends assert.Assertions {
|
|
|
39
39
|
compareWithSnapshot: options => {
|
|
40
40
|
return test.compareWithSnapshot(options);
|
|
41
41
|
},
|
|
42
|
-
powerAssert: test.powerAssert
|
|
42
|
+
powerAssert: test.powerAssert,
|
|
43
|
+
experiments: test.experiments
|
|
43
44
|
});
|
|
44
45
|
testMap.set(this, test);
|
|
45
46
|
|
|
@@ -68,6 +69,10 @@ class ExecutionContext extends assert.Assertions {
|
|
|
68
69
|
test.timeout(ms);
|
|
69
70
|
};
|
|
70
71
|
|
|
72
|
+
this.teardown = callback => {
|
|
73
|
+
test.addTeardown(callback);
|
|
74
|
+
};
|
|
75
|
+
|
|
71
76
|
this.try = async (...attemptArgs) => {
|
|
72
77
|
const {args, buildTitle, implementations, receivedImplementationArray} = parseTestArgs(attemptArgs);
|
|
73
78
|
|
|
@@ -193,12 +198,14 @@ class Test {
|
|
|
193
198
|
this.experiments = options.experiments || {};
|
|
194
199
|
this.failWithoutAssertions = options.failWithoutAssertions;
|
|
195
200
|
this.fn = options.fn;
|
|
201
|
+
this.isHook = options.isHook === true;
|
|
196
202
|
this.metadata = options.metadata;
|
|
197
203
|
this.powerAssert = options.powerAssert;
|
|
198
204
|
this.title = options.title;
|
|
199
205
|
this.testPassed = options.testPassed;
|
|
200
206
|
this.registerUniqueTitle = options.registerUniqueTitle;
|
|
201
207
|
this.logs = [];
|
|
208
|
+
this.teardowns = [];
|
|
202
209
|
|
|
203
210
|
const {snapshotBelongsTo = this.title, nextSnapshotIndex = 0} = options;
|
|
204
211
|
this.snapshotBelongsTo = snapshotBelongsTo;
|
|
@@ -457,6 +464,40 @@ class Test {
|
|
|
457
464
|
this.timeoutTimer = null;
|
|
458
465
|
}
|
|
459
466
|
|
|
467
|
+
addTeardown(callback) {
|
|
468
|
+
if (this.isHook) {
|
|
469
|
+
this.saveFirstError(new Error('`t.teardown()` is not allowed in hooks'));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (this.finishing) {
|
|
474
|
+
this.saveFirstError(new Error('`t.teardown()` cannot be used during teardown'));
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (typeof callback !== 'function') {
|
|
479
|
+
throw new TypeError('Expected a function');
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
this.teardowns.push(callback);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async runTeardowns() {
|
|
486
|
+
const teardowns = [...this.teardowns];
|
|
487
|
+
|
|
488
|
+
if (this.experiments.reverseTeardowns) {
|
|
489
|
+
teardowns.reverse();
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
for (const teardown of teardowns) {
|
|
493
|
+
try {
|
|
494
|
+
await teardown(); // eslint-disable-line no-await-in-loop
|
|
495
|
+
} catch (error) {
|
|
496
|
+
this.saveFirstError(error);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
460
501
|
verifyPlan() {
|
|
461
502
|
if (!this.assertError && this.planCount !== null && this.planCount !== this.assertCount) {
|
|
462
503
|
this.saveFirstError(new assert.AssertionError({
|
|
@@ -670,6 +711,7 @@ class Test {
|
|
|
670
711
|
this.clearTimeout();
|
|
671
712
|
this.verifyPlan();
|
|
672
713
|
this.verifyAssertions();
|
|
714
|
+
await this.runTeardowns();
|
|
673
715
|
|
|
674
716
|
this.duration = nowAndTimers.now() - this.startedAt;
|
|
675
717
|
|
package/lib/watcher.js
CHANGED
|
@@ -85,6 +85,9 @@ class Watcher {
|
|
|
85
85
|
this.runVector = 0;
|
|
86
86
|
this.previousFiles = [];
|
|
87
87
|
this.globs = {cwd: projectDir, ...globs};
|
|
88
|
+
|
|
89
|
+
const patternFilters = filter.map(({pattern}) => pattern);
|
|
90
|
+
|
|
88
91
|
this.providers = providers.filter(({level}) => level >= providerLevels.pathRewrites);
|
|
89
92
|
this.run = (specificFiles = [], updateSnapshots = false) => {
|
|
90
93
|
const clearLogOnNextRun = this.clearLogOnNextRun && this.runVector > 0;
|
|
@@ -106,7 +109,7 @@ class Watcher {
|
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
if (filter.length > 0) {
|
|
109
|
-
specificFiles = applyTestFileFilter({cwd: projectDir, filter, testFiles: specificFiles});
|
|
112
|
+
specificFiles = applyTestFileFilter({cwd: projectDir, filter: patternFilters, testFiles: specificFiles});
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
this.pruneFailures(specificFiles);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function parse(file) {
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const acorn = require('acorn');
|
|
4
|
+
const walk = require('acorn-walk');
|
|
5
|
+
|
|
6
|
+
const ast = acorn.parse(fs.readFileSync(file, 'utf8'), {
|
|
7
|
+
ecmaVersion: 11,
|
|
8
|
+
locations: true
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const locations = [];
|
|
12
|
+
walk.simple(ast, {
|
|
13
|
+
CallExpression(node) {
|
|
14
|
+
locations.push(node.loc);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Walking is depth-first, but we want to sort these breadth-first.
|
|
19
|
+
locations.sort((a, b) => {
|
|
20
|
+
if (a.start.line === b.start.line) {
|
|
21
|
+
return a.start.column - b.start.column;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return a.start.line - b.start.line;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return locations;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function findTest(locations, declaration) {
|
|
31
|
+
// Find all calls that span the test declaration.
|
|
32
|
+
const spans = locations.filter(loc => {
|
|
33
|
+
if (loc.start.line > declaration.line || loc.end.line < declaration.line) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (loc.start.line === declaration.line && loc.start.column > declaration.column) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (loc.end.line === declaration.line && loc.end.column < declaration.column) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return true;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Locations should be sorted by source order, so the last span must be the test.
|
|
49
|
+
return spans.pop();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const range = (start, end) => new Array(end - start + 1).fill(start).map((element, index) => element + index);
|
|
53
|
+
|
|
54
|
+
module.exports = ({file, lineNumbers = []}) => {
|
|
55
|
+
if (lineNumbers.length === 0) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Avoid loading these until we actually need to select tests by line number.
|
|
60
|
+
const callsites = require('callsites');
|
|
61
|
+
const sourceMapSupport = require('source-map-support');
|
|
62
|
+
|
|
63
|
+
const locations = parse(file);
|
|
64
|
+
const selected = new Set(lineNumbers);
|
|
65
|
+
|
|
66
|
+
return () => {
|
|
67
|
+
// Assume this is called from a test declaration, which is located in the file.
|
|
68
|
+
// If not… don't select the test!
|
|
69
|
+
const callSite = callsites().find(callSite => callSite.getFileName() === file);
|
|
70
|
+
if (!callSite) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// FIXME: This assumes the callSite hasn't already been adjusted. It's likely
|
|
75
|
+
// that if `source-map-support/register` has been loaded, this would result
|
|
76
|
+
// in the wrong location.
|
|
77
|
+
const sourceCallSite = sourceMapSupport.wrapCallSite(callSite);
|
|
78
|
+
const start = {
|
|
79
|
+
line: sourceCallSite.getLineNumber(),
|
|
80
|
+
column: sourceCallSite.getColumnNumber() - 1 // Use 0-indexed columns.
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const test = findTest(locations, start);
|
|
84
|
+
if (!test) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return range(test.start.line, test.end.line).some(line => selected.has(line));
|
|
89
|
+
};
|
|
90
|
+
};
|
package/lib/worker/subprocess.js
CHANGED
|
@@ -30,6 +30,7 @@ ipc.options.then(async options => {
|
|
|
30
30
|
const Runner = require('../runner');
|
|
31
31
|
const serializeError = require('../serialize-error');
|
|
32
32
|
const dependencyTracking = require('./dependency-tracker');
|
|
33
|
+
const lineNumberSelection = require('./line-numbers');
|
|
33
34
|
|
|
34
35
|
async function exit(code) {
|
|
35
36
|
if (!process.exitCode) {
|
|
@@ -41,7 +42,21 @@ ipc.options.then(async options => {
|
|
|
41
42
|
process.exit(); // eslint-disable-line unicorn/no-process-exit
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
// TODO: Initialize providers here, then pass to lineNumberSelection() so they
|
|
46
|
+
// can be used to parse the test file.
|
|
47
|
+
let checkSelectedByLineNumbers;
|
|
48
|
+
try {
|
|
49
|
+
checkSelectedByLineNumbers = lineNumberSelection({
|
|
50
|
+
file: options.file,
|
|
51
|
+
lineNumbers: options.lineNumbers
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
ipc.send({type: 'line-number-selection-error', err: serializeError('Line number selection error', false, error, options.file)});
|
|
55
|
+
checkSelectedByLineNumbers = () => false;
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
const runner = new Runner({
|
|
59
|
+
checkSelectedByLineNumbers,
|
|
45
60
|
experiments: options.experiments,
|
|
46
61
|
failFast: options.failFast,
|
|
47
62
|
failWithoutAssertions: options.failWithoutAssertions,
|
|
@@ -70,7 +85,7 @@ ipc.options.then(async options => {
|
|
|
70
85
|
runner.on('stateChange', state => ipc.send(state));
|
|
71
86
|
|
|
72
87
|
runner.on('error', error => {
|
|
73
|
-
ipc.send({type: 'internal-error', err: serializeError('Internal runner error', false, error)});
|
|
88
|
+
ipc.send({type: 'internal-error', err: serializeError('Internal runner error', false, error, runner.file)});
|
|
74
89
|
exit(1);
|
|
75
90
|
});
|
|
76
91
|
|
|
@@ -81,7 +96,7 @@ ipc.options.then(async options => {
|
|
|
81
96
|
ipc.send({type: 'touched-files', files: touchedFiles});
|
|
82
97
|
}
|
|
83
98
|
} catch (error) {
|
|
84
|
-
ipc.send({type: 'internal-error', err: serializeError('Internal runner error', false, error)});
|
|
99
|
+
ipc.send({type: 'internal-error', err: serializeError('Internal runner error', false, error, runner.file)});
|
|
85
100
|
exit(1);
|
|
86
101
|
return;
|
|
87
102
|
}
|
|
@@ -90,7 +105,7 @@ ipc.options.then(async options => {
|
|
|
90
105
|
currentlyUnhandled()
|
|
91
106
|
.filter(rejection => !attributedRejections.has(rejection.promise))
|
|
92
107
|
.forEach(rejection => {
|
|
93
|
-
ipc.send({type: 'unhandled-rejection', err: serializeError('Unhandled rejection', true, rejection.reason)});
|
|
108
|
+
ipc.send({type: 'unhandled-rejection', err: serializeError('Unhandled rejection', true, rejection.reason, runner.file)});
|
|
94
109
|
});
|
|
95
110
|
|
|
96
111
|
exit(0);
|
|
@@ -102,7 +117,7 @@ ipc.options.then(async options => {
|
|
|
102
117
|
return;
|
|
103
118
|
}
|
|
104
119
|
|
|
105
|
-
ipc.send({type: 'uncaught-exception', err: serializeError('Uncaught exception', true, error)});
|
|
120
|
+
ipc.send({type: 'uncaught-exception', err: serializeError('Uncaught exception', true, error, runner.file)});
|
|
106
121
|
exit(1);
|
|
107
122
|
});
|
|
108
123
|
|
|
@@ -181,7 +196,7 @@ ipc.options.then(async options => {
|
|
|
181
196
|
if (Reflect.has(mod, Symbol.for('esm:package'))) {
|
|
182
197
|
requireFn = mod(module);
|
|
183
198
|
}
|
|
184
|
-
} catch
|
|
199
|
+
} catch {}
|
|
185
200
|
}
|
|
186
201
|
|
|
187
202
|
// Install dependency tracker after the require configuration has been evaluated
|
|
@@ -207,7 +222,7 @@ ipc.options.then(async options => {
|
|
|
207
222
|
exit(1);
|
|
208
223
|
}
|
|
209
224
|
} catch (error) {
|
|
210
|
-
ipc.send({type: 'uncaught-exception', err: serializeError('Uncaught exception', true, error)});
|
|
225
|
+
ipc.send({type: 'uncaught-exception', err: serializeError('Uncaught exception', true, error, runner.file)});
|
|
211
226
|
exit(1);
|
|
212
227
|
}
|
|
213
228
|
}).catch(error => {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ava",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.9.0",
|
|
4
|
+
"description": "Node.js test runner that lets you develop with confidence.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "avajs/ava",
|
|
7
7
|
"homepage": "https://avajs.dev",
|
|
8
8
|
"bin": "cli.js",
|
|
9
9
|
"engines": {
|
|
10
|
-
"node": ">=10.18.0 <11 || >=12.14.0 <13 || >=
|
|
10
|
+
"node": ">=10.18.0 <11 || >=12.14.0 <12.17.0 || >=12.17.0 <13 || >=14.0.0"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"test": "xo && tsd &&
|
|
13
|
+
"test": "xo && tsd && c8 --report=none tap && c8 --report=none --no-clean test-ava && c8 report"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"lib",
|
|
@@ -56,51 +56,53 @@
|
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@concordance/react": "^2.0.0",
|
|
59
|
+
"acorn": "^7.3.1",
|
|
60
|
+
"acorn-walk": "^7.1.1",
|
|
59
61
|
"ansi-styles": "^4.2.1",
|
|
60
62
|
"arrgv": "^1.0.2",
|
|
61
63
|
"arrify": "^2.0.1",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
+
"callsites": "^3.1.0",
|
|
65
|
+
"chalk": "^4.1.0",
|
|
66
|
+
"chokidar": "^3.4.0",
|
|
64
67
|
"chunkd": "^2.0.1",
|
|
65
68
|
"ci-info": "^2.0.0",
|
|
66
69
|
"ci-parallel-vars": "^1.0.0",
|
|
67
|
-
"clean-stack": "^2.2.0",
|
|
68
70
|
"clean-yaml-object": "^0.1.0",
|
|
69
71
|
"cli-cursor": "^3.1.0",
|
|
70
72
|
"cli-truncate": "^2.1.0",
|
|
71
73
|
"code-excerpt": "^2.1.1",
|
|
72
74
|
"common-path-prefix": "^3.0.0",
|
|
73
|
-
"concordance": "^
|
|
75
|
+
"concordance": "^5.0.0",
|
|
74
76
|
"convert-source-map": "^1.7.0",
|
|
75
77
|
"currently-unhandled": "^0.4.1",
|
|
76
78
|
"debug": "^4.1.1",
|
|
77
79
|
"del": "^5.1.0",
|
|
78
|
-
"emittery": "^0.
|
|
80
|
+
"emittery": "^0.7.0",
|
|
79
81
|
"equal-length": "^1.0.0",
|
|
80
82
|
"figures": "^3.2.0",
|
|
81
|
-
"globby": "^11.0.
|
|
82
|
-
"ignore-by-default": "^
|
|
83
|
+
"globby": "^11.0.1",
|
|
84
|
+
"ignore-by-default": "^2.0.0",
|
|
83
85
|
"import-local": "^3.0.2",
|
|
84
86
|
"indent-string": "^4.0.0",
|
|
85
87
|
"is-error": "^2.2.2",
|
|
86
88
|
"is-plain-object": "^3.0.0",
|
|
87
|
-
"is-promise": "^
|
|
89
|
+
"is-promise": "^4.0.0",
|
|
88
90
|
"lodash": "^4.17.15",
|
|
89
|
-
"matcher": "^
|
|
91
|
+
"matcher": "^3.0.0",
|
|
90
92
|
"md5-hex": "^3.0.1",
|
|
91
93
|
"mem": "^6.1.0",
|
|
92
94
|
"ms": "^2.1.2",
|
|
93
|
-
"ora": "^4.0.
|
|
95
|
+
"ora": "^4.0.4",
|
|
94
96
|
"p-map": "^4.0.0",
|
|
95
97
|
"picomatch": "^2.2.2",
|
|
96
98
|
"pkg-conf": "^3.1.0",
|
|
97
99
|
"plur": "^4.0.0",
|
|
98
|
-
"pretty-ms": "^
|
|
100
|
+
"pretty-ms": "^7.0.0",
|
|
99
101
|
"read-pkg": "^5.2.0",
|
|
100
102
|
"resolve-cwd": "^3.0.0",
|
|
101
103
|
"slash": "^3.0.0",
|
|
102
|
-
"source-map-support": "^0.5.
|
|
103
|
-
"stack-utils": "^2.0.
|
|
104
|
+
"source-map-support": "^0.5.19",
|
|
105
|
+
"stack-utils": "^2.0.2",
|
|
104
106
|
"strip-ansi": "^6.0.0",
|
|
105
107
|
"supertap": "^1.0.0",
|
|
106
108
|
"temp-dir": "^2.0.0",
|
|
@@ -111,18 +113,20 @@
|
|
|
111
113
|
},
|
|
112
114
|
"devDependencies": {
|
|
113
115
|
"@ava/babel": "^1.0.1",
|
|
116
|
+
"@ava/test": "github:avajs/test",
|
|
117
|
+
"@babel/plugin-proposal-do-expressions": "^7.10.1",
|
|
114
118
|
"@sinonjs/fake-timers": "^6.0.1",
|
|
115
119
|
"ansi-escapes": "^4.3.1",
|
|
120
|
+
"c8": "^7.2.0",
|
|
116
121
|
"delay": "^4.3.0",
|
|
117
122
|
"esm": "^3.2.25",
|
|
118
|
-
"execa": "^4.0.
|
|
123
|
+
"execa": "^4.0.2",
|
|
119
124
|
"get-stream": "^5.1.0",
|
|
120
|
-
"
|
|
121
|
-
"p-event": "^4.1.0",
|
|
125
|
+
"p-event": "^4.2.0",
|
|
122
126
|
"proxyquire": "^2.1.3",
|
|
123
127
|
"react": "^16.13.1",
|
|
124
128
|
"react-test-renderer": "^16.13.1",
|
|
125
|
-
"replace-string": "^3.
|
|
129
|
+
"replace-string": "^3.1.0",
|
|
126
130
|
"sinon": "^9.0.2",
|
|
127
131
|
"source-map-fixtures": "^2.1.0",
|
|
128
132
|
"tap": "^14.10.7",
|
|
@@ -130,57 +134,8 @@
|
|
|
130
134
|
"tempy": "^0.5.0",
|
|
131
135
|
"touch": "^3.1.0",
|
|
132
136
|
"tsd": "^0.11.0",
|
|
133
|
-
"typescript": "^3.
|
|
134
|
-
"xo": "^0.
|
|
137
|
+
"typescript": "^3.9.5",
|
|
138
|
+
"xo": "^0.32.0",
|
|
135
139
|
"zen-observable": "^0.8.15"
|
|
136
|
-
},
|
|
137
|
-
"xo": {
|
|
138
|
-
"ignores": [
|
|
139
|
-
"media/**",
|
|
140
|
-
"test-tap/fixture/ava-paths/target/test.js",
|
|
141
|
-
"test-tap/fixture/{source-map-initial,syntax-error}.js",
|
|
142
|
-
"test-tap/fixture/snapshots/test-sourcemaps/build/**",
|
|
143
|
-
"test-tap/fixture/power-assert.js"
|
|
144
|
-
],
|
|
145
|
-
"rules": {
|
|
146
|
-
"no-use-extend-native/no-use-extend-native": "off",
|
|
147
|
-
"@typescript-eslint/no-var-requires": "off"
|
|
148
|
-
},
|
|
149
|
-
"overrides": [
|
|
150
|
-
{
|
|
151
|
-
"files": "*.d.ts",
|
|
152
|
-
"rules": {
|
|
153
|
-
"@typescript-eslint/member-ordering": "off",
|
|
154
|
-
"@typescript-eslint/prefer-readonly-parameter-types": "off",
|
|
155
|
-
"@typescript-eslint/prefer-function-type": "off",
|
|
156
|
-
"@typescript-eslint/unified-signatures": "off"
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
"files": "test-{d,tap}/**/*.ts",
|
|
161
|
-
"rules": {
|
|
162
|
-
"@typescript-eslint/explicit-function-return-type": "off",
|
|
163
|
-
"@typescript-eslint/no-empty-function": "off",
|
|
164
|
-
"@typescript-eslint/no-unsafe-call": "off",
|
|
165
|
-
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
166
|
-
"@typescript-eslint/no-unsafe-return": "off",
|
|
167
|
-
"@typescript-eslint/no-unused-vars": "off",
|
|
168
|
-
"@typescript-eslint/prefer-readonly-parameter-types": "off",
|
|
169
|
-
"no-unused-vars": "off"
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
"files": "test-tap/**/*.js",
|
|
174
|
-
"rules": {
|
|
175
|
-
"promise/prefer-await-to-then": "off"
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"files": "test-tap/fixture/**/*.js",
|
|
180
|
-
"rules": {
|
|
181
|
-
"import/no-extraneous-dependencies": "off"
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
140
|
}
|
|
186
141
|
}
|