Skip to content

Commit 67d8477

Browse files
committed
fix --inspect and its ilk; closes #3681
1 parent 61e37cd commit 67d8477

File tree

5 files changed

+80
-5
lines changed

5 files changed

+80
-5
lines changed

bin/mocha

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212
const {deprecate} = require('../lib/utils');
1313
const {spawn} = require('child_process');
1414
const {loadOptions} = require('../lib/cli/options');
15-
const {isNodeFlag, impliesNoTimeouts} = require('../lib/cli/node-flags');
15+
const {
16+
unparseNodeFlags,
17+
isNodeFlag,
18+
impliesNoTimeouts
19+
} = require('../lib/cli/node-flags');
1620
const unparse = require('yargs-unparser');
17-
const debug = require('debug')('mocha:cli');
21+
const debug = require('debug')('mocha:cli:mocha');
1822
const {aliases} = require('../lib/cli/run-option-metadata');
1923

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

94+
debug('node opts', nodeOpts);
95+
9096
const args = [].concat(
91-
unparse(nodeOpts),
97+
unparseNodeFlags(nodeOpts),
9298
mochaPath,
9399
unparse(childOpts, {alias: aliases})
94100
);

lib/cli/node-flags.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
const nodeFlags = require('node-environment-flags');
10+
const unparse = require('yargs-unparser');
1011

1112
/**
1213
* These flags are considered "debug" flags.
@@ -46,3 +47,22 @@ exports.isNodeFlag = flag =>
4647
* @private
4748
*/
4849
exports.impliesNoTimeouts = flag => debugFlags.has(flag);
50+
51+
/**
52+
* All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.
53+
* Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.
54+
* There's probably an easier or more robust way to do this; fixes welcome
55+
* @param {Object} opts - Arguments object
56+
* @returns {string[]} Unparsed arguments using `=` to specify values
57+
* @private
58+
*/
59+
exports.unparseNodeFlags = opts => {
60+
var args = unparse(opts);
61+
return args.length
62+
? args
63+
.join(' ')
64+
.split(/\b/)
65+
.map(arg => (arg === ' ' ? '=' : arg))
66+
.join('')
67+
: [];
68+
};

lib/cli/options.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ module.exports.loadPkgRc = loadPkgRc;
259259
* @returns {external:yargsParser.Arguments} Parsed args from everything
260260
*/
261261
const loadOptions = (argv = []) => {
262+
// save node-specific args having
263+
const nodeArgOptionalValues = new Map(
264+
argv
265+
.filter(arg => arg.includes('='))
266+
.map(arg => arg.substring(2).split('='))
267+
);
268+
262269
let args = parse(argv);
263270
// short-circuit: look for a flag that would abort loading of mocha.opts
264271
if (
@@ -299,6 +306,10 @@ const loadOptions = (argv = []) => {
299306
delete args.spec;
300307
}
301308

309+
nodeArgOptionalValues.forEach((value, key) => {
310+
args[key] = value;
311+
});
312+
302313
return args;
303314
};
304315

lib/cli/run-option-metadata.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,15 @@ exports.types = {
4242
'recursive',
4343
'reporters',
4444
'sort',
45-
'watch'
45+
'watch',
46+
47+
// these are special-cased args for node which have optional values.
48+
// if we don't treat them as boolean, they get greedy and might eat subsequent positional arguments.
49+
// instead, we will save their "real" values before parsing via yargs-parser.
50+
'debug',
51+
'debug-brk',
52+
'inspect',
53+
'inspect-brk'
4654
],
4755
number: ['retries', 'slow', 'timeout'],
4856
string: ['fgrep', 'grep', 'package', 'reporter', 'ui']

test/integration/options/debug.spec.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('--debug', function() {
1414

1515
it('should invoke --inspect', function(done) {
1616
invokeMocha(
17-
['--debug', '--file', DEFAULT_FIXTURE],
17+
['--debug', DEFAULT_FIXTURE],
1818
function(err, res) {
1919
if (err) {
2020
return done(err);
@@ -29,4 +29,34 @@ describe('--debug', function() {
2929
);
3030
});
3131
});
32+
33+
describe('Node.js v6', function() {
34+
before(function() {
35+
if (process.version.substring(0, 2) !== 'v6') {
36+
this.skip();
37+
}
38+
});
39+
40+
it('should start native debugger', function(done) {
41+
var proc = invokeMocha(
42+
['--debug', DEFAULT_FIXTURE],
43+
function(err, res) {
44+
if (err) {
45+
return done(err);
46+
}
47+
expect(res, 'to have passed').and(
48+
'to contain output',
49+
/Debugger listening/i
50+
);
51+
done();
52+
},
53+
{stdio: 'pipe'}
54+
);
55+
56+
// native debugger must be manually killed
57+
setTimeout(function() {
58+
proc.kill('SIGINT');
59+
}, 500);
60+
});
61+
});
3262
});

0 commit comments

Comments
 (0)