Skip to content

Commit

Permalink
fix --inspect and its ilk; closes #3681
Browse files Browse the repository at this point in the history
  • Loading branch information
boneskull committed Jan 28, 2019
1 parent 61e37cd commit 67d8477
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 5 deletions.
12 changes: 9 additions & 3 deletions bin/mocha
Expand Up @@ -12,9 +12,13 @@
const {deprecate} = require('../lib/utils');
const {spawn} = require('child_process');
const {loadOptions} = require('../lib/cli/options');
const {isNodeFlag, impliesNoTimeouts} = require('../lib/cli/node-flags');
const {
unparseNodeFlags,
isNodeFlag,
impliesNoTimeouts
} = require('../lib/cli/node-flags');
const unparse = require('yargs-unparser');
const debug = require('debug')('mocha:cli');
const debug = require('debug')('mocha:cli:mocha');
const {aliases} = require('../lib/cli/run-option-metadata');

const mochaPath = require.resolve('./_mocha');
Expand Down Expand Up @@ -87,8 +91,10 @@ if (/^(debug|inspect)$/.test(childOpts._[0])) {
];
}

debug('node opts', nodeOpts);

const args = [].concat(
unparse(nodeOpts),
unparseNodeFlags(nodeOpts),
mochaPath,
unparse(childOpts, {alias: aliases})
);
Expand Down
20 changes: 20 additions & 0 deletions lib/cli/node-flags.js
Expand Up @@ -7,6 +7,7 @@
*/

const nodeFlags = require('node-environment-flags');
const unparse = require('yargs-unparser');

/**
* These flags are considered "debug" flags.
Expand Down Expand Up @@ -46,3 +47,22 @@ exports.isNodeFlag = flag =>
* @private
*/
exports.impliesNoTimeouts = flag => debugFlags.has(flag);

/**
* All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.
* Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.
* There's probably an easier or more robust way to do this; fixes welcome
* @param {Object} opts - Arguments object
* @returns {string[]} Unparsed arguments using `=` to specify values
* @private
*/
exports.unparseNodeFlags = opts => {
var args = unparse(opts);
return args.length
? args
.join(' ')
.split(/\b/)
.map(arg => (arg === ' ' ? '=' : arg))
.join('')
: [];
};
11 changes: 11 additions & 0 deletions lib/cli/options.js
Expand Up @@ -259,6 +259,13 @@ module.exports.loadPkgRc = loadPkgRc;
* @returns {external:yargsParser.Arguments} Parsed args from everything
*/
const loadOptions = (argv = []) => {
// save node-specific args having
const nodeArgOptionalValues = new Map(
argv
.filter(arg => arg.includes('='))
.map(arg => arg.substring(2).split('='))
);

let args = parse(argv);
// short-circuit: look for a flag that would abort loading of mocha.opts
if (
Expand Down Expand Up @@ -299,6 +306,10 @@ const loadOptions = (argv = []) => {
delete args.spec;
}

nodeArgOptionalValues.forEach((value, key) => {
args[key] = value;
});

return args;
};

Expand Down
10 changes: 9 additions & 1 deletion lib/cli/run-option-metadata.js
Expand Up @@ -42,7 +42,15 @@ exports.types = {
'recursive',
'reporters',
'sort',
'watch'
'watch',

// these are special-cased args for node which have optional values.
// if we don't treat them as boolean, they get greedy and might eat subsequent positional arguments.
// instead, we will save their "real" values before parsing via yargs-parser.
'debug',
'debug-brk',
'inspect',
'inspect-brk'
],
number: ['retries', 'slow', 'timeout'],
string: ['fgrep', 'grep', 'package', 'reporter', 'ui']
Expand Down
32 changes: 31 additions & 1 deletion test/integration/options/debug.spec.js
Expand Up @@ -14,7 +14,7 @@ describe('--debug', function() {

it('should invoke --inspect', function(done) {
invokeMocha(
['--debug', '--file', DEFAULT_FIXTURE],
['--debug', DEFAULT_FIXTURE],
function(err, res) {
if (err) {
return done(err);
Expand All @@ -29,4 +29,34 @@ describe('--debug', function() {
);
});
});

describe('Node.js v6', function() {
before(function() {
if (process.version.substring(0, 2) !== 'v6') {
this.skip();
}
});

it('should start native debugger', function(done) {
var proc = invokeMocha(
['--debug', DEFAULT_FIXTURE],
function(err, res) {
if (err) {
return done(err);
}
expect(res, 'to have passed').and(
'to contain output',
/Debugger listening/i
);
done();
},
{stdio: 'pipe'}
);

// native debugger must be manually killed
setTimeout(function() {
proc.kill('SIGINT');
}, 500);
});
});
});

0 comments on commit 67d8477

Please sign in to comment.