From 91de23c6bf59e323aa2e9c355449ba225cebb3ef Mon Sep 17 00:00:00 2001 From: AndrewFinlay Date: Fri, 22 Feb 2019 11:25:51 +1100 Subject: [PATCH] fix: Exclude negated not working with '--all' switch (#977) * Add tests for nyc --all negated excludes * Update file walker to allow negated excludes Previously the call to glob.sync was knocking out all files in the exclude patterns, this would also knock out any files that were intended to be restored by the exclude negated patterns. This would prevent node_modules exclude negated files from being covered when run with --all. --- .gitignore | 2 + index.js | 21 ++++++---- package-lock.json | 5 +++ package.json | 1 + .../cli/include-exclude/exclude-negated.js | 2 + test/fixtures/cli/include-exclude/excluded.js | 2 + .../include-exclude/node_modules/cover-me.js | 2 + test/nyc-bin.js | 42 +++++++++++++++++++ 8 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/cli/include-exclude/exclude-negated.js create mode 100644 test/fixtures/cli/include-exclude/excluded.js create mode 100644 test/fixtures/cli/include-exclude/node_modules/cover-me.js diff --git a/.gitignore b/.gitignore index 397b8d1ea..f47f288c0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ test/build/ *.covered.js *.swp needs-transpile.js + +!*test/fixtures/cli/include-exclude/node_modules/ diff --git a/index.js b/index.js index f98122e93..77d492678 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ /* global __coverage__ */ +const arrayUniq = require('array-uniq') const arrify = require('arrify') const cachingTransform = require('caching-transform') const util = require('util') @@ -247,16 +248,20 @@ NYC.prototype.instrumentAllFiles = function (input, output, cb) { } NYC.prototype.walkAllFiles = function (dir, visitor) { - var pattern = null - if (this.extensions.length === 1) { - pattern = '**/*' + this.extensions[0] - } else { - pattern = '**/*{' + this.extensions.join() + '}' - } + const pattern = (this.extensions.length === 1) + ? `**/*${this.extensions[0]}` + : `**/*{${this.extensions.join()}}` - glob.sync(pattern, { cwd: dir, nodir: true, ignore: this.exclude.exclude }).forEach(function (filename) { - visitor(filename) + let filesToWalk = glob.sync(pattern, { cwd: dir, nodir: true, ignore: this.exclude.exclude }) + + // package node-glob no longer observes negated excludes, so we need to restore these files ourselves + const excludeNegatedPaths = this.exclude.excludeNegated + excludeNegatedPaths.forEach(pattern => { + filesToWalk = filesToWalk.concat(glob.sync(pattern, { cwd: dir, nodir: true })) }) + filesToWalk = arrayUniq(filesToWalk) + + filesToWalk.forEach(visitor) } NYC.prototype._maybeInstrumentSource = function (code, filename, relFile) { diff --git a/package-lock.json b/package-lock.json index 10f0767a9..5f98c1fe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -215,6 +215,11 @@ "es-abstract": "^1.7.0" } }, + "array-uniq": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.0.0.tgz", + "integrity": "sha512-O3QZEr+3wDj7otzF7PjNGs6CA3qmYMLvt5xGkjY/V0VxS+ovvqVo/5wKM/OVOAyuX4DTh9H31zE/yKtO66hTkg==" + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", diff --git a/package.json b/package.json index 326571721..1d789a7ed 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "license": "ISC", "dependencies": { "archy": "^1.0.0", + "array-uniq": "^2.0.0", "arrify": "^1.0.1", "caching-transform": "^3.0.1", "convert-source-map": "^1.6.0", diff --git a/test/fixtures/cli/include-exclude/exclude-negated.js b/test/fixtures/cli/include-exclude/exclude-negated.js new file mode 100644 index 000000000..239a04e74 --- /dev/null +++ b/test/fixtures/cli/include-exclude/exclude-negated.js @@ -0,0 +1,2 @@ +'use strict'; +console.log('Hello, World!') diff --git a/test/fixtures/cli/include-exclude/excluded.js b/test/fixtures/cli/include-exclude/excluded.js new file mode 100644 index 000000000..239a04e74 --- /dev/null +++ b/test/fixtures/cli/include-exclude/excluded.js @@ -0,0 +1,2 @@ +'use strict'; +console.log('Hello, World!') diff --git a/test/fixtures/cli/include-exclude/node_modules/cover-me.js b/test/fixtures/cli/include-exclude/node_modules/cover-me.js new file mode 100644 index 000000000..239a04e74 --- /dev/null +++ b/test/fixtures/cli/include-exclude/node_modules/cover-me.js @@ -0,0 +1,2 @@ +'use strict'; +console.log('Hello, World!') diff --git a/test/nyc-bin.js b/test/nyc-bin.js index 1aae65b97..3529ee9ba 100644 --- a/test/nyc-bin.js +++ b/test/nyc-bin.js @@ -101,6 +101,48 @@ describe('the nyc cli', function () { done() }) }) + + it('should allow negated exclude patterns', function (done) { + const args = [bin, '--all', '--exclude', '**/include-exclude/**', '--exclude', '!**/exclude-negated.js', process.execPath, './half-covered.js'] + + const proc = spawn(process.execPath, args, { + cwd: fixturesCLI, + env: env + }) + + let stdout = '' + proc.stdout.on('data', chunk => { + stdout += chunk + }) + + proc.on('close', code => { + code.should.equal(0) + stdout.should.not.match(/excluded\.js/) + stdout.should.match(/exclude-negated\.js/) + done() + }) + }) + + it('should include \'node_modules\' using exclude patterns', function (done) { + const args = [bin, '--all', '--exclude', '!**/node_modules/**', process.execPath, './half-covered.js'] + + const proc = spawn(process.execPath, args, { + cwd: fixturesCLI, + env: env + }) + + let stdout = '' + proc.stdout.on('data', chunk => { + stdout += chunk + }) + + proc.on('close', code => { + code.should.equal(0) + stdout.should.match(/include-exclude\/node_modules/) + stdout.should.match(/cover-me\.js/) + done() + }) + }) }) describe('--ignore-class-method', function () {