From 7ed9fa49a0bb24019f3bc31054a77a31326b6fe8 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Tue, 21 Apr 2020 10:17:55 -0700 Subject: [PATCH] fixes some signal handling - `landing` reporter befouls the terminal up if `SIGINT` is issued - `--exit` test used an incorrect description, and also did not reliably handle `SIGINT` when running - `runMocha` helper returns the child process Ref: #4198 --- lib/reporters/landing.js | 8 +++++++ test/integration/helpers.js | 3 ++- test/integration/options/exit.spec.js | 30 +++++++++++++++++++-------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/lib/reporters/landing.js b/lib/reporters/landing.js index a6af946c42..0be3837d7b 100644 --- a/lib/reporters/landing.js +++ b/lib/reporters/landing.js @@ -98,6 +98,14 @@ function Landing(runner, options) { process.stdout.write('\n'); self.epilogue(); }); + + // if cursor is hidden when we ctrl-C, then it will remain hidden unless... + process.once('SIGINT', function() { + cursor.show(); + process.nextTick(function() { + process.kill(process.pid, 'SIGINT'); + }); + }); } /** diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 6cdf7e93cf..799f477539 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -33,6 +33,7 @@ module.exports = { * @param {string[]} args - Extra args to mocha executable * @param {Function} fn - Callback * @param {Object} [opts] - Options for `spawn()` + * @returns {ChildProcess} Mocha process */ runMocha: function(fixturePath, args, fn, opts) { if (typeof args === 'function') { @@ -46,7 +47,7 @@ module.exports = { path = resolveFixturePath(fixturePath); args = args || []; - invokeSubMocha( + return invokeSubMocha( args.concat(['-C', path]), function(err, res) { if (err) { diff --git a/test/integration/options/exit.spec.js b/test/integration/options/exit.spec.js index 376496f4fc..cde3c35b96 100644 --- a/test/integration/options/exit.spec.js +++ b/test/integration/options/exit.spec.js @@ -1,7 +1,6 @@ 'use strict'; -var helpers = require('../helpers'); -var runMochaJSON = helpers.runMochaJSON; +var runMocha = require('../helpers').runMocha; describe('--exit', function() { var behaviors = { @@ -9,13 +8,29 @@ describe('--exit', function() { disabled: '--no-exit' }; + // subprocess + var mocha; + + function killSubprocess() { + mocha.kill('SIGKILL'); + } + + // these two handlers deal with a ctrl-c on command-line + before(function() { + process.on('SIGINT', killSubprocess); + }); + + after(function() { + process.removeListener('SIGINT', killSubprocess); + }); + /** * Returns a test that executes Mocha in a subprocess with either * `--exit`, `--no-exit`, or default behavior. * * @param {boolean} shouldExit - Expected result; `true` if Mocha should * have force-killed the process. - * @param {string} [behavior] - 'enabled' or 'disabled' + * @param {"enabled"|"disabled"} [behavior] - 'enabled' or 'disabled'; omit for default * @returns {Function} async function implementing the test */ var runExit = function(shouldExit, behavior) { @@ -28,8 +43,7 @@ describe('--exit', function() { var timeoutObj; var fixture = 'exit.fixture.js'; var args = behaviors[behavior] ? [behaviors[behavior]] : []; - - var mocha = runMochaJSON(fixture, args, function postmortem(err) { + mocha = runMocha(fixture, args, function postmortem(err) { clearTimeout(timeoutObj); if (err) { return done(err); @@ -41,15 +55,13 @@ describe('--exit', function() { // If this callback happens, then Mocha didn't automatically exit. timeoutObj = setTimeout(function() { didExit = false; - // This is the only way to kill the child, afaik. - // After the process ends, the callback to `run()` above is handled. - mocha.kill('SIGINT'); + killSubprocess(); }, timeout - 500); }; }; describe('default behavior', function() { - it('should force exit after root suite completion', runExit(false)); + it('should not force exit after root suite completion', runExit(false)); }); describe('when enabled', function() {