ava 3.11.0 → 3.13.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 +1 -1
- package/lib/api.js +8 -1
- package/lib/assert.js +11 -3
- package/lib/cli.js +13 -8
- package/lib/extensions.js +4 -1
- package/lib/fork.js +84 -20
- package/lib/ipc-flow-control.js +39 -0
- package/lib/load-config.js +8 -2
- package/lib/module-types.js +75 -0
- package/lib/plugin-support/shared-worker-loader.js +252 -0
- package/lib/plugin-support/shared-workers.js +138 -0
- package/lib/provider-manager.js +1 -1
- package/lib/reporters/default.js +83 -12
- package/lib/run-status.js +5 -0
- package/lib/runner.js +3 -0
- package/lib/test.js +2 -1
- package/lib/worker/ipc.js +174 -29
- package/lib/worker/plugin.js +121 -0
- package/lib/worker/subprocess.js +24 -1
- package/package.json +24 -22
- package/plugin.d.ts +81 -0
- package/plugin.js +9 -0
- package/readme.md +4 -3
- package/lib/reporters/while-corked.js +0 -13
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const v8 = require('v8');
|
|
2
|
+
const pkg = require('../../package.json');
|
|
3
|
+
const subprocess = require('./subprocess');
|
|
4
|
+
const options = require('./options');
|
|
5
|
+
|
|
6
|
+
const workers = new Map();
|
|
7
|
+
const workerTeardownFns = new WeakMap();
|
|
8
|
+
|
|
9
|
+
function createSharedWorker(filename, initialData, teardown) {
|
|
10
|
+
const channel = subprocess.registerSharedWorker(filename, initialData, teardown);
|
|
11
|
+
|
|
12
|
+
class ReceivedMessage {
|
|
13
|
+
constructor(id, serializedData) {
|
|
14
|
+
this.id = id;
|
|
15
|
+
this.data = v8.deserialize(new Uint8Array(serializedData));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
reply(data) {
|
|
19
|
+
return publishMessage(data, this.id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Ensure that, no matter how often it's received, we have a stable message
|
|
24
|
+
// object.
|
|
25
|
+
const messageCache = new WeakMap();
|
|
26
|
+
async function * receiveMessages(replyTo) {
|
|
27
|
+
for await (const evt of channel.receive()) {
|
|
28
|
+
if (replyTo === undefined && evt.replyTo !== undefined) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (replyTo !== undefined && evt.replyTo !== replyTo) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let message = messageCache.get(evt);
|
|
37
|
+
if (message === undefined) {
|
|
38
|
+
message = new ReceivedMessage(evt.messageId, evt.serializedData);
|
|
39
|
+
messageCache.set(evt, message);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
yield message;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function publishMessage(data, replyTo) {
|
|
47
|
+
const id = channel.post([...v8.serialize(data)], replyTo);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
id,
|
|
51
|
+
async * replies() {
|
|
52
|
+
yield * receiveMessages(id);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
available: channel.available,
|
|
59
|
+
protocol: 'experimental',
|
|
60
|
+
|
|
61
|
+
get currentlyAvailable() {
|
|
62
|
+
return channel.currentlyAvailable;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
publish(data) {
|
|
66
|
+
return publishMessage(data);
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
async * subscribe() {
|
|
70
|
+
yield * receiveMessages();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const supportsSharedWorkers = process.versions.node >= '12.17.0';
|
|
76
|
+
|
|
77
|
+
function registerSharedWorker({
|
|
78
|
+
filename,
|
|
79
|
+
initialData,
|
|
80
|
+
supportedProtocols,
|
|
81
|
+
teardown
|
|
82
|
+
}) {
|
|
83
|
+
if (!options.get().experiments.sharedWorkers) {
|
|
84
|
+
throw new Error('Shared workers are experimental. Opt in to them in your AVA configuration');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!supportsSharedWorkers) {
|
|
88
|
+
throw new Error('Shared workers require Node.js 12.17 or newer');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!supportedProtocols.includes('experimental')) {
|
|
92
|
+
throw new Error(`This version of AVA (${pkg.version}) does not support any of the desired shared worker protocols: ${supportedProtocols.join()}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let worker = workers.get(filename);
|
|
96
|
+
if (worker === undefined) {
|
|
97
|
+
worker = createSharedWorker(filename, initialData, async () => {
|
|
98
|
+
// Run possibly asynchronous teardown functions serially, in reverse
|
|
99
|
+
// order. Any error will crash the worker.
|
|
100
|
+
const teardownFns = workerTeardownFns.get(worker);
|
|
101
|
+
if (teardownFns !== undefined) {
|
|
102
|
+
for await (const fn of [...teardownFns].reverse()) {
|
|
103
|
+
await fn();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
workers.set(filename, worker);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (teardown !== undefined) {
|
|
111
|
+
if (workerTeardownFns.has(worker)) {
|
|
112
|
+
workerTeardownFns.get(worker).push(teardown);
|
|
113
|
+
} else {
|
|
114
|
+
workerTeardownFns.set(worker, [teardown]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return worker;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
exports.registerSharedWorker = registerSharedWorker;
|
package/lib/worker/subprocess.js
CHANGED
|
@@ -32,6 +32,8 @@ ipc.options.then(async options => {
|
|
|
32
32
|
const dependencyTracking = require('./dependency-tracker');
|
|
33
33
|
const lineNumberSelection = require('./line-numbers');
|
|
34
34
|
|
|
35
|
+
const sharedWorkerTeardowns = [];
|
|
36
|
+
|
|
35
37
|
async function exit(code) {
|
|
36
38
|
if (!process.exitCode) {
|
|
37
39
|
process.exitCode = code;
|
|
@@ -89,7 +91,7 @@ ipc.options.then(async options => {
|
|
|
89
91
|
exit(1);
|
|
90
92
|
});
|
|
91
93
|
|
|
92
|
-
runner.on('finish', () => {
|
|
94
|
+
runner.on('finish', async () => {
|
|
93
95
|
try {
|
|
94
96
|
const {cannotSave, touchedFiles} = runner.saveSnapshotState();
|
|
95
97
|
if (cannotSave) {
|
|
@@ -103,6 +105,14 @@ ipc.options.then(async options => {
|
|
|
103
105
|
return;
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
try {
|
|
109
|
+
await Promise.all(sharedWorkerTeardowns.map(fn => fn()));
|
|
110
|
+
} catch (error) {
|
|
111
|
+
ipc.send({type: 'uncaught-exception', err: serializeError('Shared worker teardown error', false, error, runner.file)});
|
|
112
|
+
exit(1);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
106
116
|
nowAndTimers.setImmediate(() => {
|
|
107
117
|
currentlyUnhandled()
|
|
108
118
|
.filter(rejection => !attributedRejections.has(rejection.promise))
|
|
@@ -129,6 +139,19 @@ ipc.options.then(async options => {
|
|
|
129
139
|
return runner;
|
|
130
140
|
};
|
|
131
141
|
|
|
142
|
+
exports.registerSharedWorker = (filename, initialData, teardown) => {
|
|
143
|
+
const {channel, forceUnref, ready} = ipc.registerSharedWorker(filename, initialData);
|
|
144
|
+
runner.waitForReady.push(ready);
|
|
145
|
+
sharedWorkerTeardowns.push(async () => {
|
|
146
|
+
try {
|
|
147
|
+
await teardown();
|
|
148
|
+
} finally {
|
|
149
|
+
forceUnref();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return channel;
|
|
153
|
+
};
|
|
154
|
+
|
|
132
155
|
// Store value to prevent required modules from modifying it.
|
|
133
156
|
const testPath = options.file;
|
|
134
157
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ava",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "Node.js test runner that lets you develop with confidence.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "avajs/ava",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"lib",
|
|
17
17
|
"*.js",
|
|
18
18
|
"!*.config.js",
|
|
19
|
-
"index.d.ts"
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"*.d.ts"
|
|
20
21
|
],
|
|
21
22
|
"keywords": [
|
|
22
23
|
"🦄",
|
|
@@ -56,14 +57,14 @@
|
|
|
56
57
|
],
|
|
57
58
|
"dependencies": {
|
|
58
59
|
"@concordance/react": "^2.0.0",
|
|
59
|
-
"acorn": "^
|
|
60
|
-
"acorn-walk": "^
|
|
60
|
+
"acorn": "^8.0.1",
|
|
61
|
+
"acorn-walk": "^8.0.0",
|
|
61
62
|
"ansi-styles": "^4.2.1",
|
|
62
63
|
"arrgv": "^1.0.2",
|
|
63
64
|
"arrify": "^2.0.1",
|
|
64
65
|
"callsites": "^3.1.0",
|
|
65
66
|
"chalk": "^4.1.0",
|
|
66
|
-
"chokidar": "^3.4.
|
|
67
|
+
"chokidar": "^3.4.2",
|
|
67
68
|
"chunkd": "^2.0.1",
|
|
68
69
|
"ci-info": "^2.0.0",
|
|
69
70
|
"ci-parallel-vars": "^1.0.1",
|
|
@@ -72,11 +73,11 @@
|
|
|
72
73
|
"cli-truncate": "^2.1.0",
|
|
73
74
|
"code-excerpt": "^3.0.0",
|
|
74
75
|
"common-path-prefix": "^3.0.0",
|
|
75
|
-
"concordance": "^5.0.
|
|
76
|
+
"concordance": "^5.0.1",
|
|
76
77
|
"convert-source-map": "^1.7.0",
|
|
77
78
|
"currently-unhandled": "^0.4.1",
|
|
78
|
-
"debug": "^4.
|
|
79
|
-
"del": "^
|
|
79
|
+
"debug": "^4.2.0",
|
|
80
|
+
"del": "^6.0.0",
|
|
80
81
|
"emittery": "^0.7.1",
|
|
81
82
|
"equal-length": "^1.0.0",
|
|
82
83
|
"figures": "^3.2.0",
|
|
@@ -85,19 +86,20 @@
|
|
|
85
86
|
"import-local": "^3.0.2",
|
|
86
87
|
"indent-string": "^4.0.0",
|
|
87
88
|
"is-error": "^2.2.2",
|
|
88
|
-
"is-plain-object": "^
|
|
89
|
+
"is-plain-object": "^5.0.0",
|
|
89
90
|
"is-promise": "^4.0.0",
|
|
90
|
-
"lodash": "^4.17.
|
|
91
|
+
"lodash": "^4.17.20",
|
|
91
92
|
"matcher": "^3.0.0",
|
|
92
93
|
"md5-hex": "^3.0.1",
|
|
93
|
-
"mem": "^6.1.
|
|
94
|
+
"mem": "^6.1.1",
|
|
94
95
|
"ms": "^2.1.2",
|
|
95
|
-
"ora": "^
|
|
96
|
+
"ora": "^5.1.0",
|
|
97
|
+
"p-event": "^4.2.0",
|
|
96
98
|
"p-map": "^4.0.0",
|
|
97
99
|
"picomatch": "^2.2.2",
|
|
98
100
|
"pkg-conf": "^3.1.0",
|
|
99
101
|
"plur": "^4.0.0",
|
|
100
|
-
"pretty-ms": "^7.0.
|
|
102
|
+
"pretty-ms": "^7.0.1",
|
|
101
103
|
"read-pkg": "^5.2.0",
|
|
102
104
|
"resolve-cwd": "^3.0.0",
|
|
103
105
|
"slash": "^3.0.0",
|
|
@@ -107,9 +109,9 @@
|
|
|
107
109
|
"supertap": "^1.0.0",
|
|
108
110
|
"temp-dir": "^2.0.0",
|
|
109
111
|
"trim-off-newlines": "^1.0.1",
|
|
110
|
-
"update-notifier": "^4.1.
|
|
112
|
+
"update-notifier": "^4.1.1",
|
|
111
113
|
"write-file-atomic": "^3.0.3",
|
|
112
|
-
"yargs": "^
|
|
114
|
+
"yargs": "^16.0.3"
|
|
113
115
|
},
|
|
114
116
|
"devDependencies": {
|
|
115
117
|
"@ava/babel": "^1.0.1",
|
|
@@ -117,25 +119,25 @@
|
|
|
117
119
|
"@babel/plugin-proposal-do-expressions": "^7.10.4",
|
|
118
120
|
"@sinonjs/fake-timers": "^6.0.1",
|
|
119
121
|
"ansi-escapes": "^4.3.1",
|
|
120
|
-
"c8": "^7.
|
|
122
|
+
"c8": "^7.3.1",
|
|
121
123
|
"delay": "^4.4.0",
|
|
122
124
|
"esm": "^3.2.25",
|
|
123
125
|
"execa": "^4.0.3",
|
|
124
|
-
"get-stream": "^
|
|
125
|
-
"
|
|
126
|
+
"get-stream": "^6.0.0",
|
|
127
|
+
"it-first": "^1.0.4",
|
|
126
128
|
"proxyquire": "^2.1.3",
|
|
127
129
|
"react": "^16.13.1",
|
|
128
130
|
"react-test-renderer": "^16.13.1",
|
|
129
131
|
"replace-string": "^3.1.0",
|
|
130
|
-
"sinon": "^9.0.
|
|
132
|
+
"sinon": "^9.0.3",
|
|
131
133
|
"source-map-fixtures": "^2.1.0",
|
|
132
134
|
"tap": "^14.10.8",
|
|
133
135
|
"temp-write": "^4.0.0",
|
|
134
|
-
"tempy": "^0.
|
|
136
|
+
"tempy": "^0.7.1",
|
|
135
137
|
"touch": "^3.1.0",
|
|
136
138
|
"tsd": "^0.13.1",
|
|
137
|
-
"typescript": "^
|
|
138
|
-
"xo": "^0.
|
|
139
|
+
"typescript": "^4.0.3",
|
|
140
|
+
"xo": "^0.33.1",
|
|
139
141
|
"zen-observable": "^0.8.15"
|
|
140
142
|
}
|
|
141
143
|
}
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export namespace SharedWorker {
|
|
2
|
+
export type ProtocolIdentifier = 'experimental';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/method-signature-style */
|
|
5
|
+
export type FactoryOptions = {
|
|
6
|
+
negotiateProtocol <Data = unknown>(supported: readonly ['experimental']): Experimental.Protocol<Data>;
|
|
7
|
+
// Add overloads for additional protocols.
|
|
8
|
+
};
|
|
9
|
+
/* eslint-enable @typescript-eslint/method-signature-style */
|
|
10
|
+
|
|
11
|
+
export type Factory = (options: FactoryOptions) => void;
|
|
12
|
+
|
|
13
|
+
export namespace Experimental {
|
|
14
|
+
export type Protocol<Data = unknown> = {
|
|
15
|
+
readonly initialData: Data;
|
|
16
|
+
readonly protocol: 'experimental';
|
|
17
|
+
broadcast: (data: Data) => BroadcastMessage<Data>;
|
|
18
|
+
ready: () => Protocol<Data>;
|
|
19
|
+
subscribe: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
20
|
+
testWorkers: () => AsyncIterableIterator<TestWorker<Data>>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type BroadcastMessage<Data = unknown> = {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
replies: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type PublishedMessage<Data = unknown> = {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
replies: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ReceivedMessage<Data = unknown> = {
|
|
34
|
+
readonly data: Data;
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly testWorker: TestWorker;
|
|
37
|
+
reply: (data: Data) => PublishedMessage<Data>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type TestWorker<Data = unknown> = {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly file: string;
|
|
43
|
+
publish: (data: Data) => PublishedMessage<Data>;
|
|
44
|
+
subscribe: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
45
|
+
teardown: <TeardownFn extends () => void> (fn: TeardownFn) => TeardownFn;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export namespace Plugin {
|
|
50
|
+
export type RegistrationOptions<Identifier extends ProtocolIdentifier, Data = unknown> = {
|
|
51
|
+
readonly filename: string;
|
|
52
|
+
readonly initialData?: Data;
|
|
53
|
+
readonly supportedProtocols: readonly Identifier[];
|
|
54
|
+
readonly teardown?: () => void;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export namespace Experimental {
|
|
58
|
+
export type Protocol<Data = unknown> = {
|
|
59
|
+
readonly available: Promise<void>;
|
|
60
|
+
readonly currentlyAvailable: boolean;
|
|
61
|
+
readonly protocol: 'experimental';
|
|
62
|
+
publish: (data: Data) => PublishedMessage<Data>;
|
|
63
|
+
subscribe: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type PublishedMessage<Data = unknown> = {
|
|
67
|
+
readonly id: string;
|
|
68
|
+
replies: () => AsyncIterableIterator<ReceivedMessage<Data>>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type ReceivedMessage<Data = unknown> = {
|
|
72
|
+
readonly data: Data;
|
|
73
|
+
readonly id: string;
|
|
74
|
+
reply: (data: Data) => PublishedMessage<Data>;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function registerSharedWorker<Data = unknown>(options: SharedWorker.Plugin.RegistrationOptions<'experimental', Data>): SharedWorker.Plugin.Experimental.Protocol<Data>;
|
|
81
|
+
// Add overloads for additional protocols.
|
package/plugin.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// Ensure the same AVA install is loaded by the test file as by the test worker
|
|
5
|
+
if (process.env.AVA_PATH && process.env.AVA_PATH !== __dirname) {
|
|
6
|
+
module.exports = require(path.join(process.env.AVA_PATH, 'plugin'));
|
|
7
|
+
} else {
|
|
8
|
+
module.exports = require('./lib/worker/plugin');
|
|
9
|
+
}
|
package/readme.md
CHANGED
|
@@ -211,9 +211,9 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
|
|
|
211
211
|
|
|
212
212
|
## Team
|
|
213
213
|
|
|
214
|
-
[](https://github.com/novemberborn) | [](https://github.com/sindresorhus)
|
|
215
|
-
|
|
216
|
-
[Mark Wubben](https://novemberborn.net) | [Sindre Sorhus](https://sindresorhus.com)
|
|
214
|
+
[](https://github.com/novemberborn) | [](https://github.com/sindresorhus)
|
|
215
|
+
---|---
|
|
216
|
+
[Mark Wubben](https://novemberborn.net) | [Sindre Sorhus](https://sindresorhus.com)
|
|
217
217
|
|
|
218
218
|
###### Former
|
|
219
219
|
|
|
@@ -221,6 +221,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
|
|
|
221
221
|
- [James Talmage](https://github.com/jamestalmage)
|
|
222
222
|
- [Juan Soto](https://github.com/sotojuan)
|
|
223
223
|
- [Jeroen Engels](https://github.com/jfmengels)
|
|
224
|
+
- [Vadim Demedes](https://github.com/vadimdemedes)
|
|
224
225
|
|
|
225
226
|
|
|
226
227
|
<div align="center">
|