Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 033d0bb

Browse filesBrowse files
committed
test_runner: emit test:watch:drained event
PR-URL: #48259 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent 618a9e1 commit 033d0bb
Copy full SHA for 033d0bb

File tree

Expand file treeCollapse file tree

3 files changed

+37
-12
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+37
-12
lines changed
Open diff view settings
Collapse file

‎doc/api/test.md‎

Copy file name to clipboardExpand all lines: doc/api/test.md
+4Lines changed: 4 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,10 @@ This event is only emitted if `--test` flag is passed.
14731473
Emitted when a running test writes to `stdout`.
14741474
This event is only emitted if `--test` flag is passed.
14751475

1476+
### Event: `'test:watch:drained'`
1477+
1478+
Emitted when no more tests are queued for execution in watch mode.
1479+
14761480
## Class: `TestContext`
14771481

14781482
<!-- YAML
Collapse file

‎lib/internal/test_runner/runner.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/runner.js
+23-12Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -341,25 +341,25 @@ class FileTest extends Test {
341341
}
342342
}
343343

344-
const runningProcesses = new SafeMap();
345-
const runningSubtests = new SafeMap();
346-
347344
function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) {
345+
const watchMode = filesWatcher != null;
348346
const subtest = root.createSubtest(FileTest, path, async (t) => {
349347
const args = getRunArgs({ path, inspectPort, testNamePatterns });
350348
const stdio = ['pipe', 'pipe', 'pipe'];
351349
const env = { ...process.env, NODE_TEST_CONTEXT: 'child-v8' };
352-
if (filesWatcher) {
350+
if (watchMode) {
353351
stdio.push('ipc');
354352
env.WATCH_REPORT_DEPENDENCIES = '1';
355353
}
356354

357355
const child = spawn(process.execPath, args, { signal: t.signal, encoding: 'utf8', env, stdio });
358-
runningProcesses.set(path, child);
356+
if (watchMode) {
357+
filesWatcher.runningProcesses.set(path, child);
358+
filesWatcher.watcher.watchChildProcessModules(child, path);
359+
}
359360

360361
let err;
361362

362-
filesWatcher?.watchChildProcessModules(child, path);
363363

364364
child.on('error', (error) => {
365365
err = error;
@@ -391,8 +391,14 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) {
391391
finished(child.stdout, { signal: t.signal }),
392392
]);
393393

394-
runningProcesses.delete(path);
395-
runningSubtests.delete(path);
394+
if (watchMode) {
395+
filesWatcher.runningProcesses.delete(path);
396+
filesWatcher.runningSubtests.delete(path);
397+
if (filesWatcher.runningSubtests.size === 0) {
398+
root.reporter[kEmitMessage]('test:watch:drained');
399+
}
400+
}
401+
396402
if (code !== 0 || signal !== null) {
397403
if (!err) {
398404
const failureType = subtest.failedSubtests ? kSubtestsFailed : kTestCodeFailure;
@@ -413,9 +419,13 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) {
413419
}
414420

415421
function watchFiles(testFiles, root, inspectPort, signal, testNamePatterns) {
416-
const filesWatcher = new FilesWatcher({ throttle: 500, mode: 'filter', signal });
417-
filesWatcher.on('changed', ({ owners }) => {
418-
filesWatcher.unfilterFilesOwnedBy(owners);
422+
const runningProcesses = new SafeMap();
423+
const runningSubtests = new SafeMap();
424+
const watcher = new FilesWatcher({ throttle: 500, mode: 'filter', signal });
425+
const filesWatcher = { __proto__: null, watcher, runningProcesses, runningSubtests };
426+
427+
watcher.on('changed', ({ owners }) => {
428+
watcher.unfilterFilesOwnedBy(owners);
419429
PromisePrototypeThen(SafePromiseAllReturnVoid(testFiles, async (file) => {
420430
if (!owners.has(file)) {
421431
return;
@@ -436,6 +446,7 @@ function watchFiles(testFiles, root, inspectPort, signal, testNamePatterns) {
436446
}));
437447
});
438448
signal?.addEventListener('abort', () => root.postRun(), { __proto__: null, once: true });
449+
439450
return filesWatcher;
440451
}
441452

@@ -485,7 +496,7 @@ function run(options) {
485496
root.harness.bootstrapComplete = true;
486497
return SafePromiseAllSettledReturnVoid(testFiles, (path) => {
487498
const subtest = runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns);
488-
runningSubtests.set(path, subtest);
499+
filesWatcher?.runningSubtests.set(path, subtest);
489500
return subtest;
490501
});
491502
};
Collapse file

‎test/parallel/test-runner-run.mjs‎

Copy file name to clipboardExpand all lines: test/parallel/test-runner-run.mjs
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,14 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
132132
.toArray();
133133
assert.deepStrictEqual(result, ['this should pass']);
134134
});
135+
136+
it('should emit "test:watch:drained" event on watch mode', async () => {
137+
const controller = new AbortController();
138+
await run({ files: [join(testFixtures, 'test/random.cjs')], watch: true, signal: controller.signal })
139+
.on('data', function({ type }) {
140+
if (type === 'test:watch:drained') {
141+
controller.abort();
142+
}
143+
});
144+
});
135145
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.