ava 3.15.0 → 4.0.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/entrypoints/cli.mjs +4 -0
- package/entrypoints/eslint-plugin-helper.cjs +109 -0
- package/entrypoints/main.cjs +2 -0
- package/entrypoints/main.mjs +1 -0
- package/entrypoints/plugin.cjs +2 -0
- package/entrypoints/plugin.mjs +4 -0
- package/index.d.ts +6 -816
- package/lib/api.js +108 -49
- package/lib/assert.js +255 -270
- package/lib/chalk.js +9 -14
- package/lib/cli.js +118 -112
- package/lib/code-excerpt.js +12 -17
- package/lib/concordance-options.js +29 -65
- package/lib/context-ref.js +3 -6
- package/lib/create-chain.js +32 -20
- package/lib/environment-variables.js +1 -4
- package/lib/eslint-plugin-helper-worker.js +73 -0
- package/lib/extensions.js +2 -2
- package/lib/fork.js +81 -84
- package/lib/glob-helpers.cjs +140 -0
- package/lib/globs.js +136 -163
- package/lib/{ipc-flow-control.js → ipc-flow-control.cjs} +1 -0
- package/lib/is-ci.js +4 -2
- package/lib/like-selector.js +7 -13
- package/lib/line-numbers.js +11 -18
- package/lib/load-config.js +56 -180
- package/lib/module-types.js +3 -7
- package/lib/node-arguments.js +4 -5
- package/lib/{now-and-timers.js → now-and-timers.cjs} +0 -0
- package/lib/parse-test-args.js +22 -11
- package/lib/pkg.cjs +2 -0
- package/lib/plugin-support/shared-worker-loader.js +45 -48
- package/lib/plugin-support/shared-workers.js +24 -46
- package/lib/provider-manager.js +20 -14
- package/lib/reporters/beautify-stack.js +6 -12
- package/lib/reporters/colors.js +40 -15
- package/lib/reporters/default.js +114 -364
- package/lib/reporters/format-serialized-error.js +7 -18
- package/lib/reporters/improper-usage-messages.js +8 -9
- package/lib/reporters/prefix-title.js +17 -15
- package/lib/reporters/tap.js +18 -25
- package/lib/run-status.js +29 -23
- package/lib/runner.js +157 -172
- package/lib/scheduler.js +53 -0
- package/lib/serialize-error.js +61 -64
- package/lib/snapshot-manager.js +271 -289
- package/lib/test.js +135 -291
- package/lib/watcher.js +69 -44
- package/lib/worker/base.js +208 -0
- package/lib/worker/channel.cjs +290 -0
- package/lib/worker/dependency-tracker.js +24 -23
- package/lib/worker/{ensure-forked.js → guard-environment.cjs} +5 -4
- package/lib/worker/line-numbers.js +58 -20
- package/lib/worker/main.cjs +12 -0
- package/lib/worker/{options.js → options.cjs} +0 -0
- package/lib/worker/{plugin.js → plugin.cjs} +30 -21
- package/lib/worker/state.cjs +5 -0
- package/lib/worker/utils.cjs +6 -0
- package/package.json +71 -68
- package/plugin.d.ts +51 -53
- package/readme.md +5 -13
- package/types/assertions.d.ts +327 -0
- package/types/subscribable.ts +6 -0
- package/types/test-fn.d.ts +231 -0
- package/types/try-fn.d.ts +58 -0
- package/cli.js +0 -11
- package/eslint-plugin-helper.js +0 -201
- package/index.js +0 -8
- package/lib/worker/ipc.js +0 -201
- package/lib/worker/main.js +0 -21
- package/lib/worker/subprocess.js +0 -266
- package/plugin.js +0 -9
package/lib/test.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import concordance from 'concordance';
|
|
2
|
+
import isPromise from 'is-promise';
|
|
3
|
+
import plur from 'plur';
|
|
4
|
+
|
|
5
|
+
import {AssertionError, Assertions, checkAssertionMessage} from './assert.js';
|
|
6
|
+
import concordanceOptions from './concordance-options.js';
|
|
7
|
+
import nowAndTimers from './now-and-timers.cjs';
|
|
8
|
+
import parseTestArgs from './parse-test-args.js';
|
|
9
9
|
|
|
10
10
|
function formatErrorValue(label, error) {
|
|
11
11
|
const formatted = concordance.format(error, concordanceOptions);
|
|
@@ -15,13 +15,13 @@ function formatErrorValue(label, error) {
|
|
|
15
15
|
const captureSavedError = () => {
|
|
16
16
|
const limitBefore = Error.stackTraceLimit;
|
|
17
17
|
Error.stackTraceLimit = 1;
|
|
18
|
-
const
|
|
18
|
+
const error = new Error(); // eslint-disable-line unicorn/error-message
|
|
19
19
|
Error.stackTraceLimit = limitBefore;
|
|
20
|
-
return
|
|
20
|
+
return error;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const testMap = new WeakMap();
|
|
24
|
-
class ExecutionContext extends
|
|
24
|
+
class ExecutionContext extends Assertions {
|
|
25
25
|
constructor(test) {
|
|
26
26
|
super({
|
|
27
27
|
pass: () => {
|
|
@@ -30,18 +30,15 @@ class ExecutionContext extends assert.Assertions {
|
|
|
30
30
|
pending: promise => {
|
|
31
31
|
test.addPendingAssertion(promise);
|
|
32
32
|
},
|
|
33
|
-
fail:
|
|
34
|
-
test.addFailedAssertion(
|
|
33
|
+
fail: error => {
|
|
34
|
+
test.addFailedAssertion(error);
|
|
35
35
|
},
|
|
36
36
|
skip: () => {
|
|
37
37
|
test.countPassedAssertion();
|
|
38
38
|
},
|
|
39
|
-
compareWithSnapshot: options =>
|
|
40
|
-
return test.compareWithSnapshot(options);
|
|
41
|
-
},
|
|
42
|
-
powerAssert: test.powerAssert,
|
|
39
|
+
compareWithSnapshot: options => test.compareWithSnapshot(options),
|
|
43
40
|
experiments: test.experiments,
|
|
44
|
-
disableSnapshots: test.isHook === true
|
|
41
|
+
disableSnapshots: test.isHook === true,
|
|
45
42
|
});
|
|
46
43
|
testMap.set(this, test);
|
|
47
44
|
|
|
@@ -50,11 +47,9 @@ class ExecutionContext extends assert.Assertions {
|
|
|
50
47
|
};
|
|
51
48
|
|
|
52
49
|
this.log = (...inputArgs) => {
|
|
53
|
-
const args = inputArgs.map(value =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
concordance.format(value, concordanceOptions);
|
|
57
|
-
});
|
|
50
|
+
const args = inputArgs.map(value => typeof value === 'string'
|
|
51
|
+
? value
|
|
52
|
+
: concordance.format(value, concordanceOptions));
|
|
58
53
|
if (args.length > 0) {
|
|
59
54
|
test.addLog(args.join(' '));
|
|
60
55
|
}
|
|
@@ -81,97 +76,87 @@ class ExecutionContext extends assert.Assertions {
|
|
|
81
76
|
throw error;
|
|
82
77
|
}
|
|
83
78
|
|
|
84
|
-
const {args,
|
|
79
|
+
const {args, implementation, title} = parseTestArgs(attemptArgs);
|
|
85
80
|
|
|
86
|
-
if (
|
|
81
|
+
if (!implementation) {
|
|
87
82
|
throw new TypeError('Expected an implementation.');
|
|
88
83
|
}
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
if (Array.isArray(implementation)) {
|
|
86
|
+
throw new TypeError('AVA 4 no longer supports t.try() with multiple implementations.');
|
|
87
|
+
}
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
let attemptTitle;
|
|
90
|
+
if (!title.isSet || title.isEmpty) {
|
|
91
|
+
attemptTitle = `${test.title} ─ attempt ${test.attemptCount + 1}`;
|
|
92
|
+
} else if (title.isValid) {
|
|
93
|
+
attemptTitle = `${test.title} ─ ${title.value}`;
|
|
94
|
+
} else {
|
|
95
|
+
throw new TypeError('`t.try()` titles must be strings');
|
|
96
|
+
}
|
|
100
97
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
if (!test.registerUniqueTitle(attemptTitle)) {
|
|
99
|
+
throw new Error(`Duplicate test title: ${attemptTitle}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let committed = false;
|
|
103
|
+
let discarded = false;
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
passed,
|
|
116
|
-
title,
|
|
117
|
-
commit: ({retainLogs = true} = {}) => {
|
|
118
|
-
if (committed) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (discarded) {
|
|
123
|
-
test.saveFirstError(new Error('Can’t commit a result that was previously discarded'));
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
committed = true;
|
|
128
|
-
test.finishAttempt({
|
|
129
|
-
assertCount,
|
|
130
|
-
commit: true,
|
|
131
|
-
deferredSnapshotRecordings,
|
|
132
|
-
errors,
|
|
133
|
-
logs,
|
|
134
|
-
passed,
|
|
135
|
-
retainLogs,
|
|
136
|
-
snapshotCount,
|
|
137
|
-
startingSnapshotCount
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
|
-
discard: ({retainLogs = false} = {}) => {
|
|
141
|
-
if (committed) {
|
|
142
|
-
test.saveFirstError(new Error('Can’t discard a result that was previously committed'));
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (discarded) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
discarded = true;
|
|
151
|
-
test.finishAttempt({
|
|
152
|
-
assertCount: 0,
|
|
153
|
-
commit: false,
|
|
154
|
-
deferredSnapshotRecordings,
|
|
155
|
-
errors,
|
|
156
|
-
logs,
|
|
157
|
-
passed,
|
|
158
|
-
retainLogs,
|
|
159
|
-
snapshotCount,
|
|
160
|
-
startingSnapshotCount
|
|
161
|
-
});
|
|
105
|
+
const {assertCount, deferredSnapshotRecordings, errors, logs, passed, snapshotCount, startingSnapshotCount} = await test.runAttempt(attemptTitle, t => implementation(t, ...args));
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
errors,
|
|
109
|
+
logs: [...logs], // Don't allow modification of logs.
|
|
110
|
+
passed,
|
|
111
|
+
title: attemptTitle,
|
|
112
|
+
commit: ({retainLogs = true} = {}) => {
|
|
113
|
+
if (committed) {
|
|
114
|
+
return;
|
|
162
115
|
}
|
|
163
|
-
};
|
|
164
|
-
});
|
|
165
116
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
117
|
+
if (discarded) {
|
|
118
|
+
test.saveFirstError(new Error('Can’t commit a result that was previously discarded'));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
committed = true;
|
|
123
|
+
test.finishAttempt({
|
|
124
|
+
assertCount,
|
|
125
|
+
commit: true,
|
|
126
|
+
deferredSnapshotRecordings,
|
|
127
|
+
errors,
|
|
128
|
+
logs,
|
|
129
|
+
passed,
|
|
130
|
+
retainLogs,
|
|
131
|
+
snapshotCount,
|
|
132
|
+
startingSnapshotCount,
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
discard: ({retainLogs = false} = {}) => {
|
|
136
|
+
if (committed) {
|
|
137
|
+
test.saveFirstError(new Error('Can’t discard a result that was previously committed'));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
170
140
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
141
|
+
if (discarded) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
discarded = true;
|
|
146
|
+
test.finishAttempt({
|
|
147
|
+
assertCount: 0,
|
|
148
|
+
commit: false,
|
|
149
|
+
deferredSnapshotRecordings,
|
|
150
|
+
errors,
|
|
151
|
+
logs,
|
|
152
|
+
passed,
|
|
153
|
+
retainLogs,
|
|
154
|
+
snapshotCount,
|
|
155
|
+
startingSnapshotCount,
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
};
|
|
175
160
|
}
|
|
176
161
|
|
|
177
162
|
get title() {
|
|
@@ -190,17 +175,9 @@ class ExecutionContext extends assert.Assertions {
|
|
|
190
175
|
const test = testMap.get(this);
|
|
191
176
|
return test.isHook ? test.testPassed : !test.assertError;
|
|
192
177
|
}
|
|
193
|
-
|
|
194
|
-
_throwsArgStart(assertion, file, line) {
|
|
195
|
-
testMap.get(this).trackThrows({assertion, file, line});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
_throwsArgEnd() {
|
|
199
|
-
testMap.get(this).trackThrows(null);
|
|
200
|
-
}
|
|
201
178
|
}
|
|
202
179
|
|
|
203
|
-
class Test {
|
|
180
|
+
export default class Test {
|
|
204
181
|
constructor(options) {
|
|
205
182
|
this.contextRef = options.contextRef;
|
|
206
183
|
this.experiments = options.experiments || {};
|
|
@@ -208,12 +185,12 @@ class Test {
|
|
|
208
185
|
this.fn = options.fn;
|
|
209
186
|
this.isHook = options.isHook === true;
|
|
210
187
|
this.metadata = options.metadata;
|
|
211
|
-
this.powerAssert = options.powerAssert;
|
|
212
188
|
this.title = options.title;
|
|
213
189
|
this.testPassed = options.testPassed;
|
|
214
190
|
this.registerUniqueTitle = options.registerUniqueTitle;
|
|
215
191
|
this.logs = [];
|
|
216
192
|
this.teardowns = [];
|
|
193
|
+
this.notifyTimeoutUpdate = options.notifyTimeoutUpdate;
|
|
217
194
|
|
|
218
195
|
const {snapshotBelongsTo = this.title, nextSnapshotIndex = 0} = options;
|
|
219
196
|
this.snapshotBelongsTo = snapshotBelongsTo;
|
|
@@ -222,24 +199,20 @@ class Test {
|
|
|
222
199
|
|
|
223
200
|
const deferRecording = this.metadata.inline;
|
|
224
201
|
this.deferredSnapshotRecordings = [];
|
|
225
|
-
this.compareWithSnapshot = ({expected,
|
|
202
|
+
this.compareWithSnapshot = ({expected, message}) => {
|
|
226
203
|
this.snapshotCount++;
|
|
227
204
|
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
const label = id ? '' : message || `Snapshot ${index + 1}`; // Human-readable labels start counting at 1.
|
|
205
|
+
const belongsTo = snapshotBelongsTo;
|
|
206
|
+
const index = this.nextSnapshotIndex++;
|
|
207
|
+
const label = message;
|
|
232
208
|
|
|
233
|
-
const {taskIndex, associatedTaskIndex} = this.metadata;
|
|
234
209
|
const {record, ...result} = options.compareTestSnapshot({
|
|
235
210
|
belongsTo,
|
|
236
211
|
deferRecording,
|
|
237
212
|
expected,
|
|
238
213
|
index,
|
|
239
214
|
label,
|
|
240
|
-
taskIndex,
|
|
241
|
-
snapIndex: this.snapshotCount,
|
|
242
|
-
associatedTaskIndex
|
|
215
|
+
taskIndex: this.metadata.taskIndex,
|
|
243
216
|
});
|
|
244
217
|
if (record) {
|
|
245
218
|
this.deferredSnapshotRecordings.push(record);
|
|
@@ -250,16 +223,20 @@ class Test {
|
|
|
250
223
|
|
|
251
224
|
this.skipSnapshot = () => {
|
|
252
225
|
if (typeof options.skipSnapshot === 'function') {
|
|
253
|
-
options.skipSnapshot(
|
|
226
|
+
const record = options.skipSnapshot({
|
|
227
|
+
belongsTo: snapshotBelongsTo,
|
|
228
|
+
index: this.nextSnapshotIndex,
|
|
229
|
+
deferRecording,
|
|
230
|
+
taskIndex: this.metadata.taskIndex,
|
|
231
|
+
});
|
|
232
|
+
if (record) {
|
|
233
|
+
this.deferredSnapshotRecordings.push(record);
|
|
234
|
+
}
|
|
254
235
|
}
|
|
255
236
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
this.nextSnapshotIndex++;
|
|
260
|
-
this.snapshotCount++;
|
|
261
|
-
this.countPassedAssertion();
|
|
262
|
-
}
|
|
237
|
+
this.nextSnapshotIndex++;
|
|
238
|
+
this.snapshotCount++;
|
|
239
|
+
this.countPassedAssertion();
|
|
263
240
|
};
|
|
264
241
|
|
|
265
242
|
this.runAttempt = async (title, fn) => {
|
|
@@ -274,11 +251,11 @@ class Test {
|
|
|
274
251
|
const attempt = new Test({
|
|
275
252
|
...options,
|
|
276
253
|
fn,
|
|
277
|
-
metadata: {...options.metadata,
|
|
254
|
+
metadata: {...options.metadata, failing: false, inline: true},
|
|
278
255
|
contextRef: contextRef.copy(),
|
|
279
256
|
snapshotBelongsTo,
|
|
280
257
|
nextSnapshotIndex,
|
|
281
|
-
title
|
|
258
|
+
title,
|
|
282
259
|
});
|
|
283
260
|
|
|
284
261
|
const {deferredSnapshotRecordings, error, logs, passed, assertCount, snapshotCount} = await attempt.run();
|
|
@@ -291,53 +268,17 @@ class Test {
|
|
|
291
268
|
this.attemptCount = 0;
|
|
292
269
|
this.calledEnd = false;
|
|
293
270
|
this.duration = null;
|
|
294
|
-
this.endCallbackFinisher = null;
|
|
295
|
-
this.finishDueToAttributedError = null;
|
|
296
271
|
this.finishDueToInactivity = null;
|
|
297
272
|
this.finishDueToTimeout = null;
|
|
298
273
|
this.finishing = false;
|
|
299
274
|
this.pendingAssertionCount = 0;
|
|
300
275
|
this.pendingAttemptCount = 0;
|
|
301
|
-
this.pendingThrowsAssertion = null;
|
|
302
276
|
this.planCount = null;
|
|
303
277
|
this.startedAt = 0;
|
|
304
278
|
this.timeoutMs = 0;
|
|
305
279
|
this.timeoutTimer = null;
|
|
306
280
|
}
|
|
307
281
|
|
|
308
|
-
bindEndCallback() {
|
|
309
|
-
if (this.metadata.callback) {
|
|
310
|
-
return (error, savedError) => {
|
|
311
|
-
this.endCallback(error, savedError);
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const error_ = this.metadata.inline ? new Error('`t.end()` is not supported inside `t.try()`') : new Error('`t.end()` is not supported in this context. To use `t.end()` as a callback, you must use "callback mode" via `test.cb(testName, fn)`');
|
|
316
|
-
throw error_;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
endCallback(error, savedError) {
|
|
320
|
-
if (this.calledEnd) {
|
|
321
|
-
this.saveFirstError(new Error('`t.end()` called more than once'));
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
this.calledEnd = true;
|
|
326
|
-
|
|
327
|
-
if (error) {
|
|
328
|
-
this.saveFirstError(new assert.AssertionError({
|
|
329
|
-
actual: error,
|
|
330
|
-
message: 'Callback called with an error',
|
|
331
|
-
savedError,
|
|
332
|
-
values: [formatErrorValue('Callback called with an error:', error)]
|
|
333
|
-
}));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (this.endCallbackFinisher) {
|
|
337
|
-
this.endCallbackFinisher();
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
282
|
createExecutionContext() {
|
|
342
283
|
return new ExecutionContext(this);
|
|
343
284
|
}
|
|
@@ -374,7 +315,7 @@ class Test {
|
|
|
374
315
|
|
|
375
316
|
promise
|
|
376
317
|
.catch(error => this.saveFirstError(error))
|
|
377
|
-
.then(() => {
|
|
318
|
+
.then(() => {
|
|
378
319
|
this.pendingAssertionCount--;
|
|
379
320
|
this.refreshTimeout();
|
|
380
321
|
});
|
|
@@ -451,7 +392,7 @@ class Test {
|
|
|
451
392
|
}
|
|
452
393
|
|
|
453
394
|
timeout(ms, message) {
|
|
454
|
-
const result =
|
|
395
|
+
const result = checkAssertionMessage('timeout', message);
|
|
455
396
|
if (result !== true) {
|
|
456
397
|
this.saveFirstError(result);
|
|
457
398
|
// Allow the timeout to be set even when the message is invalid.
|
|
@@ -471,6 +412,8 @@ class Test {
|
|
|
471
412
|
this.finishDueToTimeout();
|
|
472
413
|
}
|
|
473
414
|
}, ms);
|
|
415
|
+
|
|
416
|
+
this.notifyTimeoutUpdate(this.timeoutMs);
|
|
474
417
|
}
|
|
475
418
|
|
|
476
419
|
refreshTimeout() {
|
|
@@ -509,11 +452,7 @@ class Test {
|
|
|
509
452
|
}
|
|
510
453
|
|
|
511
454
|
async runTeardowns() {
|
|
512
|
-
const teardowns = [...this.teardowns];
|
|
513
|
-
|
|
514
|
-
if (this.experiments.reverseTeardowns) {
|
|
515
|
-
teardowns.reverse();
|
|
516
|
-
}
|
|
455
|
+
const teardowns = [...this.teardowns].reverse();
|
|
517
456
|
|
|
518
457
|
for (const teardown of teardowns) {
|
|
519
458
|
try {
|
|
@@ -526,11 +465,11 @@ class Test {
|
|
|
526
465
|
|
|
527
466
|
verifyPlan() {
|
|
528
467
|
if (!this.assertError && this.planCount !== null && this.planCount !== this.assertCount) {
|
|
529
|
-
this.saveFirstError(new
|
|
468
|
+
this.saveFirstError(new AssertionError({
|
|
530
469
|
assertion: 'plan',
|
|
531
470
|
message: `Planned for ${this.planCount} ${plur('assertion', this.planCount)}, but got ${this.assertCount}.`,
|
|
532
471
|
operator: '===',
|
|
533
|
-
savedError: this.planError
|
|
472
|
+
savedError: this.planError,
|
|
534
473
|
}));
|
|
535
474
|
}
|
|
536
475
|
}
|
|
@@ -561,70 +500,16 @@ class Test {
|
|
|
561
500
|
}
|
|
562
501
|
}
|
|
563
502
|
|
|
564
|
-
trackThrows(pending) {
|
|
565
|
-
this.pendingThrowsAssertion = pending;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
detectImproperThrows(error) {
|
|
569
|
-
if (!this.pendingThrowsAssertion) {
|
|
570
|
-
return false;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const pending = this.pendingThrowsAssertion;
|
|
574
|
-
this.pendingThrowsAssertion = null;
|
|
575
|
-
|
|
576
|
-
const values = [];
|
|
577
|
-
if (error) {
|
|
578
|
-
values.push(formatErrorValue(`The following error was thrown, possibly before \`t.${pending.assertion}()\` could be called:`, error));
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
this.saveFirstError(new assert.AssertionError({
|
|
582
|
-
assertion: pending.assertion,
|
|
583
|
-
fixedSource: {file: pending.file, line: pending.line},
|
|
584
|
-
improperUsage: true,
|
|
585
|
-
message: `Improper usage of \`t.${pending.assertion}()\` detected`,
|
|
586
|
-
savedError: error instanceof Error && error,
|
|
587
|
-
values
|
|
588
|
-
}));
|
|
589
|
-
return true;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
waitForPendingThrowsAssertion() {
|
|
593
|
-
return new Promise(resolve => {
|
|
594
|
-
this.finishDueToAttributedError = () => {
|
|
595
|
-
resolve(this.finish());
|
|
596
|
-
};
|
|
597
|
-
|
|
598
|
-
this.finishDueToInactivity = () => {
|
|
599
|
-
this.detectImproperThrows();
|
|
600
|
-
resolve(this.finish());
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
// Wait up to a second to see if an error can be attributed to the
|
|
604
|
-
// pending assertion.
|
|
605
|
-
nowAndTimers.setTimeout(() => this.finishDueToInactivity(), 1000).unref();
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
attributeLeakedError(error) {
|
|
610
|
-
if (!this.detectImproperThrows(error)) {
|
|
611
|
-
return false;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
this.finishDueToAttributedError();
|
|
615
|
-
return true;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
503
|
callFn() {
|
|
619
504
|
try {
|
|
620
505
|
return {
|
|
621
506
|
ok: true,
|
|
622
|
-
retval: this.fn.call(null, this.createExecutionContext())
|
|
507
|
+
retval: this.fn.call(null, this.createExecutionContext()),
|
|
623
508
|
};
|
|
624
509
|
} catch (error) {
|
|
625
510
|
return {
|
|
626
511
|
ok: false,
|
|
627
|
-
error
|
|
512
|
+
error,
|
|
628
513
|
};
|
|
629
514
|
}
|
|
630
515
|
}
|
|
@@ -634,13 +519,11 @@ class Test {
|
|
|
634
519
|
|
|
635
520
|
const result = this.callFn();
|
|
636
521
|
if (!result.ok) {
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}));
|
|
643
|
-
}
|
|
522
|
+
this.saveFirstError(new AssertionError({
|
|
523
|
+
message: 'Error thrown in test',
|
|
524
|
+
savedError: result.error instanceof Error && result.error,
|
|
525
|
+
values: [formatErrorValue('Error thrown in test:', result.error)],
|
|
526
|
+
}));
|
|
644
527
|
|
|
645
528
|
return this.finish();
|
|
646
529
|
}
|
|
@@ -653,7 +536,7 @@ class Test {
|
|
|
653
536
|
promise = new Promise((resolve, reject) => {
|
|
654
537
|
result.retval.subscribe({
|
|
655
538
|
error: reject,
|
|
656
|
-
complete: () => resolve()
|
|
539
|
+
complete: () => resolve(),
|
|
657
540
|
});
|
|
658
541
|
});
|
|
659
542
|
} else if (returnedPromise) {
|
|
@@ -661,37 +544,6 @@ class Test {
|
|
|
661
544
|
promise = Promise.resolve(result.retval);
|
|
662
545
|
}
|
|
663
546
|
|
|
664
|
-
if (this.metadata.callback) {
|
|
665
|
-
if (returnedObservable || returnedPromise) {
|
|
666
|
-
const asyncType = returnedObservable ? 'observables' : 'promises';
|
|
667
|
-
this.saveFirstError(new Error(`Do not return ${asyncType} from tests declared via \`test.cb(…)\`. Use \`test.cb(…)\` for legacy callback APIs. When using promises, observables or async functions, use \`test(…)\`.`));
|
|
668
|
-
return this.finish();
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
if (this.calledEnd) {
|
|
672
|
-
return this.finish();
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
return new Promise(resolve => {
|
|
676
|
-
this.endCallbackFinisher = () => {
|
|
677
|
-
resolve(this.finish());
|
|
678
|
-
};
|
|
679
|
-
|
|
680
|
-
this.finishDueToAttributedError = () => {
|
|
681
|
-
resolve(this.finish());
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
this.finishDueToTimeout = () => {
|
|
685
|
-
resolve(this.finish());
|
|
686
|
-
};
|
|
687
|
-
|
|
688
|
-
this.finishDueToInactivity = () => {
|
|
689
|
-
this.saveFirstError(new Error('`t.end()` was never called'));
|
|
690
|
-
resolve(this.finish());
|
|
691
|
-
};
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
|
|
695
547
|
if (promise) {
|
|
696
548
|
return new Promise(resolve => {
|
|
697
549
|
this.finishDueToAttributedError = () => {
|
|
@@ -703,24 +555,22 @@ class Test {
|
|
|
703
555
|
};
|
|
704
556
|
|
|
705
557
|
this.finishDueToInactivity = () => {
|
|
706
|
-
const error = returnedObservable
|
|
707
|
-
new Error('Observable returned by test never completed')
|
|
708
|
-
new Error('Promise returned by test never resolved');
|
|
558
|
+
const error = returnedObservable
|
|
559
|
+
? new Error('Observable returned by test never completed')
|
|
560
|
+
: new Error('Promise returned by test never resolved');
|
|
709
561
|
this.saveFirstError(error);
|
|
710
562
|
resolve(this.finish());
|
|
711
563
|
};
|
|
712
564
|
|
|
713
565
|
promise
|
|
714
566
|
.catch(error => {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}));
|
|
721
|
-
}
|
|
567
|
+
this.saveFirstError(new AssertionError({
|
|
568
|
+
message: 'Rejected promise returned by test',
|
|
569
|
+
savedError: error instanceof Error && error,
|
|
570
|
+
values: [formatErrorValue('Rejected promise returned by test. Reason:', error)],
|
|
571
|
+
}));
|
|
722
572
|
})
|
|
723
|
-
.then(() => resolve(this.finish()));
|
|
573
|
+
.then(() => resolve(this.finish()));
|
|
724
574
|
});
|
|
725
575
|
}
|
|
726
576
|
|
|
@@ -730,10 +580,6 @@ class Test {
|
|
|
730
580
|
async finish() {
|
|
731
581
|
this.finishing = true;
|
|
732
582
|
|
|
733
|
-
if (!this.assertError && this.pendingThrowsAssertion) {
|
|
734
|
-
return this.waitForPendingThrowsAssertion();
|
|
735
|
-
}
|
|
736
|
-
|
|
737
583
|
this.clearTimeout();
|
|
738
584
|
this.verifyPlan();
|
|
739
585
|
this.verifyAssertions();
|
|
@@ -759,9 +605,7 @@ class Test {
|
|
|
759
605
|
passed,
|
|
760
606
|
snapshotCount: this.snapshotCount,
|
|
761
607
|
assertCount: this.assertCount,
|
|
762
|
-
title: this.title
|
|
608
|
+
title: this.title,
|
|
763
609
|
};
|
|
764
610
|
}
|
|
765
611
|
}
|
|
766
|
-
|
|
767
|
-
module.exports = Test;
|