ava 5.1.0 → 5.2.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/eslint-plugin-helper.cjs +4 -4
- package/lib/assert.js +6 -3
- package/lib/eslint-plugin-helper-worker.js +2 -2
- package/lib/fork.js +8 -3
- package/lib/glob-helpers.cjs +2 -2
- package/lib/module-types.js +22 -8
- package/lib/now-and-timers.cjs +1 -1
- package/lib/plugin-support/shared-worker-loader.js +6 -7
- package/lib/plugin-support/shared-workers.js +34 -24
- package/lib/reporters/tap.js +50 -17
- package/lib/run-status.js +47 -16
- package/lib/watcher.js +5 -2
- package/lib/worker/base.js +9 -3
- package/lib/worker/channel.cjs +5 -5
- package/lib/worker/guard-environment.cjs +2 -2
- package/lib/worker/main.cjs +1 -1
- package/lib/worker/utils.cjs +2 -2
- package/package.json +13 -14
- package/readme.md +5 -2
- package/types/assertions.d.cts +12 -7
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const url = require('url');
|
|
4
|
-
const v8 = require('v8');
|
|
5
|
-
const {Worker} = require('worker_threads');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const url = require('node:url');
|
|
4
|
+
const v8 = require('node:v8');
|
|
5
|
+
const {Worker} = require('node:worker_threads');
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
classify,
|
package/lib/assert.js
CHANGED
|
@@ -50,7 +50,7 @@ export class AssertionError extends Error {
|
|
|
50
50
|
// use the values for custom diff views
|
|
51
51
|
this.raw = options.raw;
|
|
52
52
|
|
|
53
|
-
this.savedError = options.savedError
|
|
53
|
+
this.savedError = options.savedError || getErrorWithLongStackTrace();
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -143,14 +143,17 @@ function validateExpectations(assertion, expectations, numberArgs) { // eslint-d
|
|
|
143
143
|
case 'is':
|
|
144
144
|
case 'message':
|
|
145
145
|
case 'name':
|
|
146
|
-
case 'code':
|
|
146
|
+
case 'code': {
|
|
147
147
|
continue;
|
|
148
|
-
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
default: {
|
|
149
151
|
throw new AssertionError({
|
|
150
152
|
assertion,
|
|
151
153
|
message: `The second argument to \`t.${assertion}()\` contains unexpected properties`,
|
|
152
154
|
values: [formatWithLabel('Called with:', expectations)],
|
|
153
155
|
});
|
|
156
|
+
}
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
}
|
|
@@ -33,7 +33,7 @@ const buildGlobs = ({conf, providers, projectDir, overrideExtensions, overrideFi
|
|
|
33
33
|
cwd: projectDir,
|
|
34
34
|
...normalizeGlobs({
|
|
35
35
|
extensions,
|
|
36
|
-
files: overrideFiles
|
|
36
|
+
files: overrideFiles || conf.files,
|
|
37
37
|
providers,
|
|
38
38
|
}),
|
|
39
39
|
};
|
|
@@ -69,5 +69,5 @@ const handleMessage = async ({projectDir, overrideExtensions, overrideFiles}) =>
|
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
parentPort.on('message', handleMessage);
|
|
72
|
-
handleMessage(workerData.firstMessage);
|
|
72
|
+
handleMessage(workerData.firstMessage); // eslint-disable-line unicorn/prefer-top-level-await
|
|
73
73
|
delete workerData.firstMessage;
|
package/lib/fork.js
CHANGED
|
@@ -109,9 +109,11 @@ export default function loadFork(file, options, execArgv = process.execArgv) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
switch (message.ava.type) {
|
|
112
|
-
case 'ready-for-options':
|
|
112
|
+
case 'ready-for-options': {
|
|
113
113
|
send({type: 'options', options});
|
|
114
114
|
break;
|
|
115
|
+
}
|
|
116
|
+
|
|
115
117
|
case 'shared-worker-connect': {
|
|
116
118
|
const {channelId, filename, initialData, port} = message.ava;
|
|
117
119
|
emitter.emit('connectSharedWorker', {
|
|
@@ -125,11 +127,14 @@ export default function loadFork(file, options, execArgv = process.execArgv) {
|
|
|
125
127
|
break;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
case 'ping':
|
|
130
|
+
case 'ping': {
|
|
129
131
|
send({type: 'pong'});
|
|
130
132
|
break;
|
|
131
|
-
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
default: {
|
|
132
136
|
emitStateChange(message.ava);
|
|
137
|
+
}
|
|
133
138
|
}
|
|
134
139
|
});
|
|
135
140
|
|
package/lib/glob-helpers.cjs
CHANGED
package/lib/module-types.js
CHANGED
|
@@ -6,21 +6,28 @@ const requireTrueValue = value => {
|
|
|
6
6
|
|
|
7
7
|
const normalize = (extension, type, defaultModuleType) => {
|
|
8
8
|
switch (extension) {
|
|
9
|
-
case 'cjs':
|
|
9
|
+
case 'cjs': {
|
|
10
10
|
requireTrueValue(type);
|
|
11
11
|
return 'commonjs';
|
|
12
|
-
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
case 'mjs': {
|
|
13
15
|
requireTrueValue(type);
|
|
14
16
|
return 'module';
|
|
15
|
-
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
case 'js': {
|
|
16
20
|
requireTrueValue(type);
|
|
17
21
|
return defaultModuleType;
|
|
18
|
-
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
default: {
|
|
19
25
|
if (type !== 'commonjs' && type !== 'module') {
|
|
20
26
|
throw new TypeError(`Module type for ’${extension}’ must be ’commonjs’ or ’module’`);
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
return type;
|
|
30
|
+
}
|
|
24
31
|
}
|
|
25
32
|
};
|
|
26
33
|
|
|
@@ -37,17 +44,24 @@ const deriveFromArray = (extensions, defaultModuleType) => {
|
|
|
37
44
|
const moduleTypes = {};
|
|
38
45
|
for (const extension of extensions) {
|
|
39
46
|
switch (extension) {
|
|
40
|
-
case 'cjs':
|
|
47
|
+
case 'cjs': {
|
|
41
48
|
moduleTypes.cjs = 'commonjs';
|
|
42
49
|
break;
|
|
43
|
-
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
case 'mjs': {
|
|
44
53
|
moduleTypes.mjs = 'module';
|
|
45
54
|
break;
|
|
46
|
-
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
case 'js': {
|
|
47
58
|
moduleTypes.js = defaultModuleType;
|
|
48
59
|
break;
|
|
49
|
-
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
default: {
|
|
50
63
|
moduleTypes[extension] = 'commonjs';
|
|
64
|
+
}
|
|
51
65
|
}
|
|
52
66
|
}
|
|
53
67
|
|
package/lib/now-and-timers.cjs
CHANGED
|
@@ -166,7 +166,8 @@ let signalAvailable = () => {
|
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
let fatal;
|
|
169
|
-
|
|
169
|
+
try {
|
|
170
|
+
const factory = await loadFactory(workerData.filename);
|
|
170
171
|
if (typeof factory !== 'function') {
|
|
171
172
|
throw new TypeError(`Missing default factory function export for shared worker plugin at ${workerData.filename}`);
|
|
172
173
|
}
|
|
@@ -236,14 +237,12 @@ loadFactory(workerData.filename).then(factory => {
|
|
|
236
237
|
};
|
|
237
238
|
},
|
|
238
239
|
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
}).finally(() => {
|
|
240
|
+
} catch (error) {
|
|
241
|
+
fatal = fatal ?? error;
|
|
242
|
+
} finally {
|
|
244
243
|
if (fatal !== undefined) {
|
|
245
244
|
process.nextTick(() => {
|
|
246
245
|
throw fatal;
|
|
247
246
|
});
|
|
248
247
|
}
|
|
249
|
-
}
|
|
248
|
+
}
|
|
@@ -49,35 +49,54 @@ function launchWorker(filename, initialData) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export async function observeWorkerProcess(fork, runStatus) {
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
52
|
+
let signalDone;
|
|
53
|
+
|
|
54
|
+
const done = new Promise(resolve => {
|
|
55
|
+
signalDone = () => {
|
|
56
|
+
resolve();
|
|
57
|
+
};
|
|
56
58
|
});
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
const activeInstances = new Set();
|
|
61
|
+
|
|
62
|
+
const removeInstance = instance => {
|
|
63
|
+
instance.worker.unref();
|
|
64
|
+
activeInstances.delete(instance);
|
|
65
|
+
|
|
66
|
+
if (activeInstances.size === 0) {
|
|
67
|
+
signalDone();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const removeAllInstances = () => {
|
|
72
|
+
if (activeInstances.size === 0) {
|
|
73
|
+
signalDone();
|
|
74
|
+
return;
|
|
61
75
|
}
|
|
76
|
+
|
|
77
|
+
for (const instance of activeInstances) {
|
|
78
|
+
removeInstance(instance);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
fork.promise.finally(() => {
|
|
83
|
+
removeAllInstances();
|
|
62
84
|
});
|
|
63
85
|
|
|
64
86
|
fork.onConnectSharedWorker(async ({filename, initialData, port, signalError}) => {
|
|
65
87
|
const launched = launchWorker(filename, initialData);
|
|
88
|
+
activeInstances.add(launched);
|
|
66
89
|
|
|
67
90
|
const handleWorkerMessage = async message => {
|
|
68
91
|
if (message.type === 'deregistered-test-worker' && message.id === fork.threadId) {
|
|
69
92
|
launched.worker.off('message', handleWorkerMessage);
|
|
70
|
-
|
|
71
|
-
registrationCount--;
|
|
72
|
-
if (registrationCount === 0) {
|
|
73
|
-
signalDeregistered();
|
|
74
|
-
}
|
|
93
|
+
removeInstance(launched);
|
|
75
94
|
}
|
|
76
95
|
};
|
|
77
96
|
|
|
78
97
|
launched.statePromises.error.then(error => {
|
|
79
|
-
signalDeregistered();
|
|
80
98
|
launched.worker.off('message', handleWorkerMessage);
|
|
99
|
+
removeAllInstances();
|
|
81
100
|
runStatus.emitStateChange({type: 'shared-worker-error', err: serializeError('Shared worker error', true, error)});
|
|
82
101
|
signalError();
|
|
83
102
|
});
|
|
@@ -85,8 +104,6 @@ export async function observeWorkerProcess(fork, runStatus) {
|
|
|
85
104
|
try {
|
|
86
105
|
await launched.statePromises.available;
|
|
87
106
|
|
|
88
|
-
registrationCount++;
|
|
89
|
-
|
|
90
107
|
port.postMessage({type: 'ready'});
|
|
91
108
|
|
|
92
109
|
launched.worker.postMessage({
|
|
@@ -104,15 +121,8 @@ export async function observeWorkerProcess(fork, runStatus) {
|
|
|
104
121
|
});
|
|
105
122
|
|
|
106
123
|
launched.worker.on('message', handleWorkerMessage);
|
|
107
|
-
} catch {
|
|
108
|
-
return;
|
|
109
|
-
} finally {
|
|
110
|
-
// Attaching listeners has the side-effect of referencing the worker.
|
|
111
|
-
// Explicitly unreference it now so it does not prevent the main process
|
|
112
|
-
// from exiting.
|
|
113
|
-
launched.worker.unref();
|
|
114
|
-
}
|
|
124
|
+
} catch {}
|
|
115
125
|
});
|
|
116
126
|
|
|
117
|
-
return
|
|
127
|
+
return done;
|
|
118
128
|
}
|
package/lib/reporters/tap.js
CHANGED
|
@@ -153,26 +153,38 @@ export default class TapReporter {
|
|
|
153
153
|
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
|
|
154
154
|
|
|
155
155
|
switch (evt.type) {
|
|
156
|
-
case 'declared-test':
|
|
156
|
+
case 'declared-test': {
|
|
157
157
|
// Ignore
|
|
158
158
|
break;
|
|
159
|
-
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
case 'hook-failed': {
|
|
160
162
|
this.writeTest(evt, {passed: false, todo: false, skip: false});
|
|
161
163
|
break;
|
|
162
|
-
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
case 'hook-finished': {
|
|
163
167
|
this.writeComment(evt, {});
|
|
164
168
|
break;
|
|
165
|
-
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
case 'internal-error': {
|
|
166
172
|
this.writeCrash(evt);
|
|
167
173
|
break;
|
|
168
|
-
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
case 'missing-ava-import': {
|
|
169
177
|
this.filesWithMissingAvaImports.add(evt.testFile);
|
|
170
178
|
this.writeCrash(evt, `No tests found in ${this.relativeFile(evt.testFile)}, make sure to import "ava" at the top of your test file`);
|
|
171
179
|
break;
|
|
172
|
-
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
case 'process-exit': {
|
|
173
183
|
this.writeProcessExit(evt);
|
|
174
184
|
break;
|
|
175
|
-
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
case 'selected-test': {
|
|
176
188
|
if (evt.skip) {
|
|
177
189
|
this.writeTest(evt, {passed: true, todo: false, skip: true});
|
|
178
190
|
} else if (evt.todo) {
|
|
@@ -180,25 +192,39 @@ export default class TapReporter {
|
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
break;
|
|
183
|
-
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
case 'stats': {
|
|
184
198
|
this.stats = evt.stats;
|
|
185
199
|
break;
|
|
186
|
-
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
case 'test-failed': {
|
|
187
203
|
this.writeTest(evt, {passed: false, todo: false, skip: false});
|
|
188
204
|
break;
|
|
189
|
-
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
case 'test-passed': {
|
|
190
208
|
this.writeTest(evt, {passed: true, todo: false, skip: false});
|
|
191
209
|
break;
|
|
192
|
-
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
case 'timeout': {
|
|
193
213
|
this.writeTimeout(evt);
|
|
194
214
|
break;
|
|
195
|
-
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
case 'uncaught-exception': {
|
|
196
218
|
this.writeCrash(evt);
|
|
197
219
|
break;
|
|
198
|
-
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
case 'unhandled-rejection': {
|
|
199
223
|
this.writeCrash(evt);
|
|
200
224
|
break;
|
|
201
|
-
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
case 'worker-failed': {
|
|
202
228
|
if (!this.filesWithMissingAvaImports.has(evt.testFile)) {
|
|
203
229
|
if (evt.nonZeroExitCode) {
|
|
204
230
|
this.writeCrash(evt, `${this.relativeFile(evt.testFile)} exited with a non-zero exit code: ${evt.nonZeroExitCode}`);
|
|
@@ -208,7 +234,9 @@ export default class TapReporter {
|
|
|
208
234
|
}
|
|
209
235
|
|
|
210
236
|
break;
|
|
211
|
-
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
case 'worker-finished': {
|
|
212
240
|
if (!evt.forcedExit && !this.filesWithMissingAvaImports.has(evt.testFile)) {
|
|
213
241
|
if (fileStats.declaredTests === 0) {
|
|
214
242
|
this.writeCrash(evt, `No tests found in ${this.relativeFile(evt.testFile)}`);
|
|
@@ -218,12 +246,17 @@ export default class TapReporter {
|
|
|
218
246
|
}
|
|
219
247
|
|
|
220
248
|
break;
|
|
249
|
+
}
|
|
250
|
+
|
|
221
251
|
case 'worker-stderr':
|
|
222
|
-
case 'worker-stdout':
|
|
252
|
+
case 'worker-stdout': {
|
|
223
253
|
this.stdStream.write(evt.chunk);
|
|
224
254
|
break;
|
|
225
|
-
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
default: {
|
|
226
258
|
break;
|
|
259
|
+
}
|
|
227
260
|
}
|
|
228
261
|
}
|
|
229
262
|
}
|
package/lib/run-status.js
CHANGED
|
@@ -72,22 +72,28 @@ export default class RunStatus extends Emittery {
|
|
|
72
72
|
|
|
73
73
|
let changedStats = true;
|
|
74
74
|
switch (event.type) {
|
|
75
|
-
case 'declared-test':
|
|
75
|
+
case 'declared-test': {
|
|
76
76
|
stats.declaredTests++;
|
|
77
77
|
fileStats.declaredTests++;
|
|
78
78
|
break;
|
|
79
|
-
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
case 'hook-failed': {
|
|
80
82
|
stats.failedHooks++;
|
|
81
83
|
fileStats.failedHooks++;
|
|
82
84
|
break;
|
|
83
|
-
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 'internal-error': {
|
|
84
88
|
stats.internalErrors++;
|
|
85
89
|
if (event.testFile) {
|
|
86
90
|
fileStats.internalErrors++;
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
break;
|
|
90
|
-
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
case 'selected-test': {
|
|
91
97
|
stats.selectedTests++;
|
|
92
98
|
fileStats.selectedTests++;
|
|
93
99
|
if (event.skip) {
|
|
@@ -103,17 +109,23 @@ export default class RunStatus extends Emittery {
|
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
break;
|
|
106
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
case 'shared-worker-error': {
|
|
107
115
|
stats.sharedWorkerErrors++;
|
|
108
116
|
break;
|
|
109
|
-
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
case 'test-failed': {
|
|
110
120
|
stats.failedTests++;
|
|
111
121
|
fileStats.failedTests++;
|
|
112
122
|
stats.remainingTests--;
|
|
113
123
|
fileStats.remainingTests--;
|
|
114
124
|
this.removePendingTest(event);
|
|
115
125
|
break;
|
|
116
|
-
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case 'test-passed': {
|
|
117
129
|
if (event.knownFailing) {
|
|
118
130
|
stats.passedKnownFailingTests++;
|
|
119
131
|
fileStats.passedKnownFailingTests++;
|
|
@@ -126,10 +138,14 @@ export default class RunStatus extends Emittery {
|
|
|
126
138
|
fileStats.remainingTests--;
|
|
127
139
|
this.removePendingTest(event);
|
|
128
140
|
break;
|
|
129
|
-
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'test-register-log-reference': {
|
|
130
144
|
this.addPendingTestLogs(event);
|
|
131
145
|
break;
|
|
132
|
-
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
case 'timeout': {
|
|
133
149
|
stats.timeouts++;
|
|
134
150
|
event.pendingTests = this.pendingTests;
|
|
135
151
|
event.pendingTestsLogs = this.pendingTestsLogs;
|
|
@@ -140,35 +156,50 @@ export default class RunStatus extends Emittery {
|
|
|
140
156
|
}
|
|
141
157
|
|
|
142
158
|
break;
|
|
143
|
-
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
case 'interrupt': {
|
|
144
162
|
event.pendingTests = this.pendingTests;
|
|
145
163
|
event.pendingTestsLogs = this.pendingTestsLogs;
|
|
146
164
|
this.pendingTests = new Map();
|
|
147
165
|
this.pendingTestsLogs = new Map();
|
|
148
166
|
break;
|
|
149
|
-
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
case 'process-exit': {
|
|
150
170
|
event.pendingTests = this.pendingTests;
|
|
151
171
|
event.pendingTestsLogs = this.pendingTestsLogs;
|
|
152
172
|
this.pendingTests = new Map();
|
|
153
173
|
this.pendingTestsLogs = new Map();
|
|
154
174
|
break;
|
|
155
|
-
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
case 'uncaught-exception': {
|
|
156
178
|
stats.uncaughtExceptions++;
|
|
157
179
|
fileStats.uncaughtExceptions++;
|
|
158
180
|
break;
|
|
159
|
-
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
case 'unhandled-rejection': {
|
|
160
184
|
stats.unhandledRejections++;
|
|
161
185
|
fileStats.unhandledRejections++;
|
|
162
186
|
break;
|
|
163
|
-
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
case 'worker-failed': {
|
|
164
190
|
stats.failedWorkers++;
|
|
165
191
|
break;
|
|
166
|
-
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
case 'worker-finished': {
|
|
167
195
|
stats.finishedWorkers++;
|
|
168
196
|
break;
|
|
169
|
-
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
default: {
|
|
170
200
|
changedStats = false;
|
|
171
201
|
break;
|
|
202
|
+
}
|
|
172
203
|
}
|
|
173
204
|
|
|
174
205
|
if (changedStats) {
|
package/lib/watcher.js
CHANGED
|
@@ -298,11 +298,14 @@ export default class Watcher {
|
|
|
298
298
|
case 'test-failed':
|
|
299
299
|
case 'uncaught-exception':
|
|
300
300
|
case 'unhandled-rejection':
|
|
301
|
-
case 'worker-failed':
|
|
301
|
+
case 'worker-failed': {
|
|
302
302
|
this.countFailure(evt.testFile, currentVector);
|
|
303
303
|
break;
|
|
304
|
-
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
default: {
|
|
305
307
|
break;
|
|
308
|
+
}
|
|
306
309
|
}
|
|
307
310
|
});
|
|
308
311
|
});
|
package/lib/worker/base.js
CHANGED
|
@@ -222,12 +222,18 @@ const onError = error => {
|
|
|
222
222
|
});
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
+
let options;
|
|
225
226
|
if (isRunningInThread) {
|
|
226
227
|
channel.send({type: 'starting'}); // AVA won't terminate the worker thread until it's seen this message.
|
|
227
|
-
|
|
228
|
+
({options} = workerData);
|
|
228
229
|
delete workerData.options; // Don't allow user code access.
|
|
229
|
-
run(options).catch(onError);
|
|
230
230
|
} else if (isRunningInChildProcess) {
|
|
231
231
|
channel.send({type: 'ready-for-options'});
|
|
232
|
-
channel.options
|
|
232
|
+
options = await channel.options;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
await run(options);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
onError(error);
|
|
233
239
|
}
|
package/lib/worker/channel.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const events = require('events');
|
|
3
|
-
const process = require('process');
|
|
4
|
-
const {MessageChannel, threadId} = require('worker_threads');
|
|
2
|
+
const events = require('node:events');
|
|
3
|
+
const process = require('node:process');
|
|
4
|
+
const {MessageChannel, threadId} = require('node:worker_threads');
|
|
5
5
|
|
|
6
6
|
const timers = require('../now-and-timers.cjs');
|
|
7
7
|
|
|
@@ -125,7 +125,7 @@ if (isRunningInChildProcess) {
|
|
|
125
125
|
const {controlFlow} = require('../ipc-flow-control.cjs');
|
|
126
126
|
handle = new IpcHandle(controlFlow(process));
|
|
127
127
|
} else if (isRunningInThread) {
|
|
128
|
-
const {parentPort} = require('worker_threads');
|
|
128
|
+
const {parentPort} = require('node:worker_threads');
|
|
129
129
|
handle = new MessagePortHandle(parentPort);
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -133,7 +133,7 @@ if (isRunningInChildProcess) {
|
|
|
133
133
|
// Node.js. In order to keep track, explicitly reference before attaching.
|
|
134
134
|
handle.ref();
|
|
135
135
|
|
|
136
|
-
exports.options = pEvent(handle.channel, 'message', selectAvaMessage('options')).then(message => message.ava.options);
|
|
136
|
+
exports.options = pEvent(handle.channel, 'message', selectAvaMessage('options')).then(message => message.ava.options); // eslint-disable-line unicorn/prefer-top-level-await
|
|
137
137
|
exports.peerFailed = pEvent(handle.channel, 'message', selectAvaMessage('peer-failed'));
|
|
138
138
|
exports.send = handle.send.bind(handle);
|
|
139
139
|
exports.unref = handle.unref.bind(handle);
|
package/lib/worker/main.cjs
CHANGED
package/lib/worker/utils.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const process = require('process');
|
|
3
|
-
const {isMainThread} = require('worker_threads');
|
|
2
|
+
const process = require('node:process');
|
|
3
|
+
const {isMainThread} = require('node:worker_threads');
|
|
4
4
|
|
|
5
5
|
exports.isRunningInThread = isMainThread === false;
|
|
6
6
|
exports.isRunningInChildProcess = typeof process.send === 'function';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ava",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Node.js test runner that lets you develop with confidence.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "avajs/ava",
|
|
@@ -88,10 +88,10 @@
|
|
|
88
88
|
"arrify": "^3.0.0",
|
|
89
89
|
"callsites": "^4.0.0",
|
|
90
90
|
"cbor": "^8.1.0",
|
|
91
|
-
"chalk": "^5.
|
|
91
|
+
"chalk": "^5.2.0",
|
|
92
92
|
"chokidar": "^3.5.3",
|
|
93
93
|
"chunkd": "^2.0.1",
|
|
94
|
-
"ci-info": "^3.
|
|
94
|
+
"ci-info": "^3.7.1",
|
|
95
95
|
"ci-parallel-vars": "^1.0.1",
|
|
96
96
|
"clean-yaml-object": "^0.1.0",
|
|
97
97
|
"cli-truncate": "^3.1.0",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"del": "^7.0.0",
|
|
104
104
|
"emittery": "^1.0.1",
|
|
105
105
|
"figures": "^5.0.0",
|
|
106
|
-
"globby": "^13.1.
|
|
106
|
+
"globby": "^13.1.3",
|
|
107
107
|
"ignore-by-default": "^2.1.0",
|
|
108
108
|
"indent-string": "^5.0.0",
|
|
109
109
|
"is-error": "^2.2.2",
|
|
@@ -131,23 +131,22 @@
|
|
|
131
131
|
"@ava/test": "github:avajs/test",
|
|
132
132
|
"@ava/typescript": "^3.0.1",
|
|
133
133
|
"@sindresorhus/tsconfig": "^3.0.1",
|
|
134
|
-
"@sinonjs/fake-timers": "^10.0.0",
|
|
135
134
|
"ansi-escapes": "^6.0.0",
|
|
136
135
|
"c8": "^7.12.0",
|
|
137
136
|
"delay": "^5.0.0",
|
|
138
137
|
"execa": "^6.1.0",
|
|
139
|
-
"fs-extra": "^
|
|
138
|
+
"fs-extra": "^11.1.0",
|
|
140
139
|
"get-stream": "^6.0.1",
|
|
141
140
|
"replace-string": "^4.0.0",
|
|
142
|
-
"sinon": "^
|
|
143
|
-
"tap": "^16.3.
|
|
141
|
+
"sinon": "^15.0.1",
|
|
142
|
+
"tap": "^16.3.3",
|
|
144
143
|
"temp-write": "^5.0.0",
|
|
145
144
|
"tempy": "^3.0.0",
|
|
146
145
|
"touch": "^3.1.0",
|
|
147
|
-
"tsd": "^0.
|
|
148
|
-
"typescript": "^4.
|
|
149
|
-
"xo": "^0.
|
|
150
|
-
"zen-observable": "^0.
|
|
146
|
+
"tsd": "^0.25.0",
|
|
147
|
+
"typescript": "^4.9.4",
|
|
148
|
+
"xo": "^0.53.1",
|
|
149
|
+
"zen-observable": "^0.10.0"
|
|
151
150
|
},
|
|
152
151
|
"peerDependencies": {
|
|
153
152
|
"@ava/typescript": "*"
|
|
@@ -158,7 +157,7 @@
|
|
|
158
157
|
}
|
|
159
158
|
},
|
|
160
159
|
"volta": {
|
|
161
|
-
"node": "18.
|
|
162
|
-
"npm": "
|
|
160
|
+
"node": "18.13.0",
|
|
161
|
+
"npm": "9.3.0"
|
|
163
162
|
}
|
|
164
163
|
}
|
package/readme.md
CHANGED
|
@@ -45,11 +45,12 @@ Your `package.json` will then look like this (exact version notwithstanding):
|
|
|
45
45
|
```json
|
|
46
46
|
{
|
|
47
47
|
"name": "awesome-package",
|
|
48
|
+
"type": "module",
|
|
48
49
|
"scripts": {
|
|
49
50
|
"test": "ava"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
|
-
"ava": "^
|
|
53
|
+
"ava": "^5.0.0"
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
```
|
|
@@ -72,7 +73,9 @@ Don't forget to configure the `test` script in your `package.json` as per above.
|
|
|
72
73
|
|
|
73
74
|
### Create your test file
|
|
74
75
|
|
|
75
|
-
Create a file named `test.js` in the project root directory
|
|
76
|
+
Create a file named `test.js` in the project root directory.
|
|
77
|
+
|
|
78
|
+
_Note that AVA's documentation assumes you're using ES modules._
|
|
76
79
|
|
|
77
80
|
```js
|
|
78
81
|
import test from 'ava';
|
package/types/assertions.d.cts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
export type ErrorConstructor
|
|
1
|
+
export type ErrorConstructor<ErrorType extends Error = Error> = {
|
|
2
|
+
new (...args: any[]): ErrorType;
|
|
3
|
+
readonly prototype: ErrorType;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type ThrownError<ErrorType extends ErrorConstructor | Error> = ErrorType extends ErrorConstructor ? ErrorType['prototype'] : ErrorType;
|
|
2
7
|
|
|
3
8
|
/** Specify one or more expectations the thrown error must satisfy. */
|
|
4
|
-
export type ThrowsExpectation = {
|
|
9
|
+
export type ThrowsExpectation<ErrorType extends ErrorConstructor | Error> = {
|
|
5
10
|
/** The thrown error must have a code that equals the given string or number. */
|
|
6
11
|
code?: string | number;
|
|
7
12
|
|
|
8
13
|
/** The thrown error must be an instance of this constructor. */
|
|
9
|
-
instanceOf?: ErrorConstructor;
|
|
14
|
+
instanceOf?: ErrorType extends ErrorConstructor ? ErrorType : ErrorType extends Error ? ErrorConstructor<ErrorType> : never;
|
|
10
15
|
|
|
11
16
|
/** The thrown error must be strictly equal to this value. */
|
|
12
|
-
is?:
|
|
17
|
+
is?: ErrorType extends ErrorConstructor ? ErrorType['prototype'] : ErrorType;
|
|
13
18
|
|
|
14
19
|
/** The thrown error must have a message that equals the given string, or matches the regular expression. */
|
|
15
20
|
message?: string | RegExp | ((message: string) => boolean);
|
|
@@ -293,7 +298,7 @@ export type ThrowsAssertion = {
|
|
|
293
298
|
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
|
|
294
299
|
* The error must satisfy all expectations. Returns undefined when the assertion fails.
|
|
295
300
|
*/
|
|
296
|
-
<
|
|
301
|
+
<ErrorType extends ErrorConstructor | Error>(fn: () => any, expectations?: ThrowsExpectation<ErrorType>, message?: string): ThrownError<ErrorType> | undefined;
|
|
297
302
|
|
|
298
303
|
/** Skip this assertion. */
|
|
299
304
|
skip(fn: () => any, expectations?: any, message?: string): void;
|
|
@@ -304,14 +309,14 @@ export type ThrowsAsyncAssertion = {
|
|
|
304
309
|
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
|
|
305
310
|
* value. Returns undefined when the assertion fails. You must await the result. The error must satisfy all expectations.
|
|
306
311
|
*/
|
|
307
|
-
<
|
|
312
|
+
<ErrorType extends ErrorConstructor | Error>(fn: () => PromiseLike<any>, expectations?: ThrowsExpectation<ErrorType>, message?: string): Promise<ThrownError<ErrorType> | undefined>;
|
|
308
313
|
|
|
309
314
|
/**
|
|
310
315
|
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
|
|
311
316
|
* rejection reason. Returns undefined when the assertion fails. You must await the result. The error must satisfy all
|
|
312
317
|
* expectations.
|
|
313
318
|
*/
|
|
314
|
-
<
|
|
319
|
+
<ErrorType extends ErrorConstructor | Error>(promise: PromiseLike<any>, expectations?: ThrowsExpectation<ErrorType>, message?: string): Promise<ThrownError<ErrorType> | undefined>;
|
|
315
320
|
|
|
316
321
|
/** Skip this assertion. */
|
|
317
322
|
skip(thrower: any, expectations?: any, message?: string): void;
|