mochajs / mocha

☕️ simple, flexible, fun javascript test framework for node.js & the browser
https://mochajs.org
MIT License
22.64k stars 3.02k forks source link

Spec path starting with a dot breaks exclude globs #4785

Closed the-spyke closed 11 months ago

the-spyke commented 3 years ago

Prerequisites

Description

Steps to Reproduce

Having .mocharc.json file:

{
  "exclude": [
    "node_modules/**"
  ]
}

And running Mocha like this: npx mocha './**/*.spec.ts'

Expected behavior: should run tests from all files excluding node_modules

Actual behavior:

Fails inside a spec file of a dependency inside node_modules which means exclude doesn't work:

$ npx mocha './**/*.spec.ts'
/Users/user/project/node_modules/runtypes/src/asynccontract.spec.ts:1
import { AsyncContract, Number } from '.';
^^^^^^

And runs as it should if I remove ./ from the path like so:

$ npx mocha '**/*.spec.ts'

Reproduces how often: 100%

Versions

Additional Information

juergba commented 2 years ago

@the-spyke

I did some testing:

Mocha first processes the globs (both spec and exclude) and then resolves the path of resulting files. Since the string ./node_modules/runtypes/src/asynccontract.spec.ts doesn't match the pattern node_modules/**, the exclusion doesn't work. On the other hand when defining the globs consistently, either both with ./ or both without, then the exclusion works.

Imo we shouldn't fiddle around with user's globs and my proposition is to leave things as is.

Anyway it's better to not put your tests in the root folder, and add a separate test folder for this purpose.

the-spyke commented 2 years ago

@juergba Giving you some context:

juergba commented 2 years ago

There is an open issue on Minimatch, dated back in 2014.

Your ideas are welcome. As a work-around you can set: "exclude": ["node_modules/**", "./node_modules/**"]

JoshuaKGoldberg commented 11 months ago

https://github.com/isaacs/minimatch/issues/30#issuecomment-1040599045 indicates this isn't a bug in minimatch:

** does not match . unless {dot:true} is set, and even if it is set, it does not ever match . or .. as path portions.

Paths starting with ./ and ../ never match a pattern that doesn't start explicitly with ./ or ../, even if {dot:true} is set.

This is by design, and matches the behavior of bash 4.3+.

Given there's a quick workaround (https://github.com/mochajs/mocha/issues/4785#issuecomment-988050232), closing as wontfix. Someone please yell at me if I've misunderstood!