Click for details
faq labelnode node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend that you _not_ install Mocha globally.Using opts configuration, the glob pattern {controllers,test}/**/*.test.js used to expand into:
controllers/**/*.test.jstest/**/*.test.jsUsing RC configration files, this glob partten gets tokenized into invalid ones:
[mocha/lib/cli/options.js] > parse() > yargsParser.detailed() > result.argv.spec [ '{controllers', 'test}/**/*.test.js' ]
Warning: Cannot find any files matching pattern "{controllers"
Warning: Cannot find any files matching pattern "test}/**/*.test.js"
coerce: coerceOpts fixes the glob tokenization, even though it isn't a long-term fix.coerceOtps function can be found here: https://github.com/mochajs/mocha/blob/master/lib/cli/options.js#L63As a side I should add that these two following spec values give the results highlighted above
spec: '{controllers,test}/**/*.test.js',spec: [ '{controllers,test}/**/*.test.js' ],I created a barebone repository to highlight the issue: https://github.com/TheOptimisticFactory/mocha-glob-issue
git clone [email protected]:TheOptimisticFactory/mocha-glob-issue.gitcd mocha-glob-issue && npm inpm run test-legacy-working: Check tests passes when using lecacy opts test/mocha.optsnpm run test-bugged-baseline: tests WONT BE FOUND when using .mocharc.jsnpm run test-bugged-showcase: Dumps the BROKEN file patterns when using .mocha.multi-paths.jsLEGACY behavior: [What used to happen]
LEGACY configuration file: /test/mocha.opts
javascript
--require test/setup.js
{controllers,test}/**/*.test.js
--exit
npm run test-legacy-working

Actual behavior: [What actually happens]
Using .mocharc.js
```javascript
'use strict';
module.exports = {
exit: true,
require: 'test/setup.js',
spec: '{controllers,test}/*/.test.js',
};
```
npm run test-bugged-baseline

Using .mocharc.multi-paths.js
```javascript
'use strict';
module.exports = {
exit: true,
require: 'test/setup.js',
spec: [ '{controllers,test}//.test.js', 'test//.test.js' ],
};
```
npm run test-bugged-showcase

Reproduces how often: [What percentage of the time does it reproduce?]
About 100% of the time :)

I confirm, I have the same problem.
@TheOptimisticFactory thank you for your detailed description.
I haven't tested, but I guess you are correct.
It's the list function which splits the parsed string by the , separator.
As a work around you can use: spec: [ 'controllers/**/*.test.js', 'test/**/*.test.js' ]
@juergba From the looks of it, one possible fix would be to do an additional globbing pass over the raw spec values (thus performing brace expansion if necessary) before parsing them any further.
@rgroothuijsen I don't know. I don't really like the idea to have two glob expansion steps in two different places. There could be more comma-delimited glob patterns than just brace expansion?
spec is kind of a bastard option form. In our first parsing step by _yargs-parser_, it's an option. In our second parsing step by _yargs,_ it's a positional argument.
We could disallow comma-delimited lists in spec:
node mocha test1 test2node mocha -- test1 test2node mocha --spec test1 --spec test2node mocha --spec test1,test2@juergba Just as a note, commas are sometimes necessary in forms like this: {,!(node_modules)/**/}*.js, and there the workaround doesn't work.
IMO the best way to solve this, is to remove the comma splitting for options which could contain glob patterns: --spec and --ignore.
As per _yargs_ configuration comma-delimited lists are not customized for these two option/positional argument anyway.
@TheOptimisticFactory @adjerbetian if you have some time left ...
Could you check wether the following patch in _lib/cli/option.js_ is working, please?
const globOptions = ['spec', 'ignore']; // new
const coerceOpts = Object.assign(
types.array.reduce(
(acc, arg) =>
Object.assign(acc, {
[arg]: v => Array.from(new Set(globOptions.includes(arg) ? v : list(v))) // modified
}),
{}
),
....
@juergba I just tested, it works with me :+1:
IMO the best way to solve this, is to remove the comma splitting for options which could contain glob patterns:
--specand--ignore.
As per _yargs_ configuration comma-delimited lists are not customized for these two option/positional argument anyway.@TheOptimisticFactory @adjerbetian if you have some time left ...
Could you check wether the following patch in _lib/cli/option.js_ is working, please?const globOptions = ['spec', 'ignore']; // new const coerceOpts = Object.assign( types.array.reduce( (acc, arg) => Object.assign(acc, { [arg]: v => Array.from(new Set(globOptions.includes(arg) ? v : list(v))) // modified }), {} ), ....
@juergba I also confirm your diff fixes the issue in all my projects :+1:
@adjerbetian @TheOptimisticFactory thank you!
Most helpful comment
IMO the best way to solve this, is to remove the comma splitting for options which could contain glob patterns:
--specand--ignore.As per _yargs_ configuration comma-delimited lists are not customized for these two option/positional argument anyway.
@TheOptimisticFactory @adjerbetian if you have some time left ...
Could you check wether the following patch in _lib/cli/option.js_ is working, please?