Skip to content

Commit aeec37a

Browse files
committed
prefer all mocha flags over node flags; closes #4417
- no more `require` special-case - future-proofs `mocha` against the introduction of conflicting flags in `node`
1 parent 4d7a171 commit aeec37a

File tree

3 files changed

+50
-30
lines changed

3 files changed

+50
-30
lines changed

lib/cli/node-flags.js

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

99
const nodeFlags = process.allowedNodeEnvironmentFlags;
10+
const {isMochaFlag} = require('./run-option-metadata');
1011
const unparse = require('yargs-unparser');
1112

1213
/**
@@ -43,16 +44,14 @@ exports.isNodeFlag = (flag, bareword = true) => {
4344
flag = flag.replace(/^--?/, '');
4445
}
4546
return (
46-
// treat --require/-r as Mocha flag even though it's also a node flag
47-
!(flag === 'require' || flag === 'r') &&
4847
// check actual node flags from `process.allowedNodeEnvironmentFlags`,
4948
// then historical support for various V8 and non-`NODE_OPTIONS` flags
5049
// and also any V8 flags with `--v8-` prefix
51-
((nodeFlags && nodeFlags.has(flag)) ||
52-
debugFlags.has(flag) ||
53-
/(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc(?:[_-]global)?$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
54-
flag
55-
))
50+
(!isMochaFlag(flag) && nodeFlags && nodeFlags.has(flag)) ||
51+
debugFlags.has(flag) ||
52+
/(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc(?:[_-]global)?$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
53+
flag
54+
)
5655
);
5756
};
5857

lib/cli/run-option-metadata.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* @type {{string:string[]}}
1313
* @private
1414
*/
15-
exports.types = {
15+
const TYPES = (exports.types = {
1616
array: [
1717
'extension',
1818
'file',
@@ -58,7 +58,7 @@ exports.types = {
5858
'slow',
5959
'timeout'
6060
]
61-
};
61+
});
6262

6363
/**
6464
* Option aliases keyed by canonical option name.
@@ -88,3 +88,26 @@ exports.aliases = {
8888
ui: ['u'],
8989
watch: ['w']
9090
};
91+
92+
const ALL_MOCHA_FLAGS = Object.keys(TYPES).reduce((acc, key) => {
93+
// gets all flags from each of the fields in `types`, adds those,
94+
// then adds aliases of each flag (if any)
95+
TYPES[key].forEach(flag => {
96+
acc.add(flag);
97+
const aliases = exports.aliases[flag] || [];
98+
aliases.forEach(alias => {
99+
acc.add(alias);
100+
});
101+
});
102+
return acc;
103+
}, new Set());
104+
105+
/**
106+
* Returns `true` if the provided `flag` is known to Mocha.
107+
* @param {string} flag - Flag to check
108+
* @returns {boolean} If `true`, this is a Mocha flag
109+
* @private
110+
*/
111+
exports.isMochaFlag = flag => {
112+
return ALL_MOCHA_FLAGS.has(flag.replace(/^--?/, ''));
113+
};

test/node-unit/cli/node-flags.spec.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
'use strict';
22

3-
const nodeEnvFlags = process.allowedNodeEnvironmentFlags;
3+
const nodeEnvFlags = [...process.allowedNodeEnvironmentFlags];
44
const {
55
isNodeFlag,
66
impliesNoTimeouts,
77
unparseNodeFlags
88
} = require('../../../lib/cli/node-flags');
99

10+
const {isMochaFlag} = require('../../../lib/cli/run-option-metadata');
11+
1012
describe('node-flags', function() {
1113
describe('isNodeFlag()', function() {
1214
describe('for all allowed node environment flags', function() {
13-
// NOTE: this is not stubbing nodeEnvFlags in any way, so relies on
14-
// the userland polyfill to be correct.
15-
nodeEnvFlags.forEach(envFlag => {
16-
it(`${envFlag} should return true`, function() {
17-
expect(isNodeFlag(envFlag), 'to be true');
15+
nodeEnvFlags
16+
.filter(flag => !isMochaFlag(flag))
17+
.forEach(envFlag => {
18+
it(`${envFlag} should return true`, function() {
19+
expect(isNodeFlag(envFlag), 'to be true');
20+
});
21+
});
22+
});
23+
24+
describe('for all allowed node env flags which conflict with mocha flags', function() {
25+
nodeEnvFlags
26+
.filter(flag => isMochaFlag(flag))
27+
.forEach(envFlag => {
28+
it(`${envFlag} should return false`, function() {
29+
expect(isNodeFlag(envFlag), 'to be false');
30+
});
1831
});
19-
});
2032
});
2133

2234
describe('when expecting leading dashes', function() {
2335
it('should require leading dashes', function() {
2436
expect(isNodeFlag('throw-deprecation', false), 'to be false');
2537
expect(isNodeFlag('--throw-deprecation', false), 'to be true');
2638
});
27-
28-
it('should return false for --require/-r', function() {
29-
expect(isNodeFlag('--require', false), 'to be false');
30-
expect(isNodeFlag('-r', false), 'to be false');
31-
});
3239
});
3340

3441
describe('special cases', function() {
@@ -132,14 +139,5 @@ describe('node-flags', function() {
132139
['--v8-numeric-one=1', '--v8-boolean-one', '--v8-numeric-two=2']
133140
);
134141
});
135-
136-
it('should special-case "--require"', function() {
137-
// note the only way for this to happen IN REAL LIFE is if you use "--require esm";
138-
// mocha eats all --require args otherwise.
139-
expect(unparseNodeFlags({require: 'mcrib'}), 'to equal', [
140-
'--require',
141-
'mcrib'
142-
]);
143-
});
144142
});
145143
});

0 commit comments

Comments
 (0)