Skip to content

Commit 27cae39

Browse files
committed
properly dispose Mocha instance in watch mode; closes #4495
Signed-off-by: Christopher Hiller <boneskull@boneskull.com>
1 parent 5c004a9 commit 27cae39

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

lib/cli/watch-run.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ exports.watchParallelRun = (
4141
// I don't know why we're cloning the root suite.
4242
const rootSuite = mocha.suite.clone();
4343

44+
// ensure we aren't leaking event listeners
45+
mocha.dispose();
46+
4447
// this `require` is needed because the require cache has been cleared. the dynamic
4548
// exports set via the below call to `mocha.ui()` won't work properly if a
4649
// test depends on this module (see `required-tokens.spec.js`).
@@ -100,6 +103,9 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
100103
// I don't know why we're cloning the root suite.
101104
const rootSuite = mocha.suite.clone();
102105

106+
// ensure we aren't leaking event listeners
107+
mocha.dispose();
108+
103109
// this `require` is needed because the require cache has been cleared. the dynamic
104110
// exports set via the below call to `mocha.ui()` won't work properly if a
105111
// test depends on this module (see `required-tokens.spec.js`).

test/integration/helpers.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,12 @@ async function runMochaWatchAsync(args, opts, change) {
415415
if (typeof opts === 'string') {
416416
opts = {cwd: opts};
417417
}
418-
opts = {sleepMs: 2000, ...opts, fork: process.platform === 'win32'};
419-
opts.stdio = ['pipe', 'pipe', 'inherit'];
418+
opts = {
419+
sleepMs: 2000,
420+
stdio: ['pipe', 'pipe', 'inherit'],
421+
...opts,
422+
fork: process.platform === 'win32'
423+
};
420424
const [mochaProcess, resultPromise] = invokeMochaAsync(
421425
[...args, '--watch'],
422426
opts
@@ -539,24 +543,25 @@ function sleep(time) {
539543
module.exports = {
540544
DEFAULT_FIXTURE,
541545
SPLIT_DOT_REPORTER_REGEXP,
546+
copyFixture,
542547

543548
createTempDir,
549+
escapeRegExp,
550+
getSummary,
544551
invokeMocha,
545552
invokeMochaAsync,
546553
invokeNode,
547-
getSummary,
554+
replaceFileContents,
548555
resolveFixturePath,
549-
toJSONResult,
550-
escapeRegExp,
551556
runMocha,
552-
runMochaJSON,
553557
runMochaAsync,
558+
runMochaJSON,
554559
runMochaJSONAsync,
555560
runMochaWatchAsync,
556561
runMochaWatchJSONAsync,
557-
copyFixture,
558-
touchFile,
559-
replaceFileContents
562+
sleep,
563+
toJSONResult,
564+
touchFile
560565
};
561566

562567
/**

test/integration/options/watch.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const path = require('path');
55
const {
66
copyFixture,
77
runMochaWatchJSONAsync,
8+
sleep,
9+
runMochaWatchAsync,
810
touchFile,
911
replaceFileContents,
1012
createTempDir,
@@ -343,5 +345,33 @@ describe('--watch', function() {
343345
it('mochaHooks.afterAll runs as expected', setupHookTest('afterAll'));
344346
it('mochaHooks.afterEach runs as expected', setupHookTest('afterEach'));
345347
});
348+
349+
it('should not leak event listeners', function() {
350+
this.timeout(20000);
351+
const testFile = path.join(tempDir, 'test.js');
352+
copyFixture(DEFAULT_FIXTURE, testFile);
353+
354+
return expect(
355+
runMochaWatchAsync(
356+
[testFile],
357+
{cwd: tempDir, stdio: 'pipe'},
358+
async () => {
359+
// we want to cause _n + 1_ reruns, which should cause the warning
360+
// to occur if the listeners aren't properly destroyed
361+
const iterations = new Array(process.getMaxListeners() + 1);
362+
// eslint-disable-next-line no-unused-vars
363+
for await (const _ of iterations) {
364+
touchFile(testFile);
365+
await sleep(1000);
366+
}
367+
}
368+
),
369+
'when fulfilled',
370+
'to satisfy',
371+
{
372+
output: expect.it('not to match', /MaxListenersExceededWarning/)
373+
}
374+
);
375+
});
346376
});
347377
});

0 commit comments

Comments
 (0)