Skip to content

Commit

Permalink
feat: Add TestExclude.globSync to find all files (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyfarrell committed Mar 4, 2019
1 parent 9b4b34c commit 2d7ea72
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 2 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Expand Up @@ -8,6 +8,7 @@
"sourceType": "module"
},
"env": {
"es6": true,
"node": true
},
"rules": {
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,6 +1,7 @@
*.tgz
.idea/
node_modules
node_modules/*
packages/*/node_modules/*
coverage
npm-debug.log
docs/
Expand Down
45 changes: 44 additions & 1 deletion packages/test-exclude/index.js
@@ -1,5 +1,6 @@
const path = require('path');
const arrify = require('arrify');
const glob = require('glob');
const minimatch = require('minimatch');
const readPkgUp = require('read-pkg-up');
const requireMainFilename = require('require-main-filename');
Expand All @@ -15,7 +16,8 @@ class TestExclude {
configKey: null, // the key to load config from in package.json.
configPath: null, // optionally override requireMainFilename.
configFound: false,
excludeNodeModules: true
excludeNodeModules: true,
extension: false
},
opts
);
Expand All @@ -28,6 +30,15 @@ class TestExclude {
this.exclude = [this.exclude];
}

if (typeof this.extension === 'string') {
this.extension = [this.extension];
} else if (
!Array.isArray(this.extension) ||
this.extension.length === 0
) {
this.extension = false;
}

if (!this.include && !this.exclude && this.configKey) {
Object.assign(this, this.pkgConf(this.configKey, this.configPath));
}
Expand Down Expand Up @@ -76,6 +87,13 @@ class TestExclude {
}

shouldInstrument(filename, relFile) {
if (
this.extension &&
!this.extension.some(ext => filename.endsWith(ext))
) {
return false;
}

let pathToCheck = filename;

if (this.relativePath) {
Expand Down Expand Up @@ -109,6 +127,20 @@ class TestExclude {

return {};
}

globSync(cwd = this.cwd) {
const globPatterns = getExtensionPattern(this.extension || []);
const globOptions = { cwd, nodir: true, dot: true };
/* If we don't have any excludeNegated then we can optimize glob by telling
* it to not iterate into unwanted directory trees (like node_modules). */
if (this.excludeNegated.length === 0) {
globOptions.ignore = this.exclude;
}

return glob
.sync(globPatterns, globOptions)
.filter(file => this.shouldInstrument(path.resolve(cwd, file)));
}
}

function prepGlobPatterns(patterns) {
Expand All @@ -127,6 +159,17 @@ function prepGlobPatterns(patterns) {
}, []);
}

function getExtensionPattern(extension) {
switch (extension.length) {
case 0:
return '**';
case 1:
return `**/*${extension[0]}`;
default:
return `**/*{${extension.join()}}`;
}
}

const exportFunc = opts => new TestExclude(opts);

exportFunc.defaultExclude = [
Expand Down
50 changes: 50 additions & 0 deletions packages/test-exclude/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/test-exclude/package.json
Expand Up @@ -28,6 +28,7 @@
"homepage": "https://istanbul.js.org/",
"dependencies": {
"arrify": "^1.0.1",
"glob": "^7.1.3",
"minimatch": "^3.0.4",
"read-pkg-up": "^4.0.0",
"require-main-filename": "^1.0.1"
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions packages/test-exclude/test/fixtures/glob/package.json
@@ -0,0 +1 @@
{}
131 changes: 131 additions & 0 deletions packages/test-exclude/test/test-exclude.js
Expand Up @@ -168,6 +168,26 @@ describe('testExclude', function() {
e.shouldInstrument('./batman/robin.js').should.equal(false);
});

it('handles extension option', function() {
const js = exclude({
extension: '.js'
});

js.shouldInstrument('file.js').should.equal(true);
js.shouldInstrument('package.json').should.equal(false);

const any = exclude();
any.shouldInstrument('file.js').should.equal(true);
any.shouldInstrument('package.json').should.equal(true);

const multi = exclude({
extension: ['.js', '.json']
});
multi.shouldInstrument('file.js').should.equal(true);
multi.shouldInstrument('file.png').should.equal(false);
multi.shouldInstrument('package.json').should.equal(true);
});

it('negated exclude patterns unrelated to node_modules do not affect default node_modules exclude behavior', function() {
const e = exclude({
exclude: ['!foo/**']
Expand Down Expand Up @@ -300,6 +320,117 @@ describe('testExclude', function() {
});
});

describe('globSync', function() {
const cwd = path.resolve(__dirname, 'fixtures/glob');
const extension = '.js';

it('should exclude the node_modules folder by default', function() {
exclude({ cwd, extension })
.globSync()
.sort()
.should.deep.equal(['file1.js', 'file2.js']);

exclude({ cwd, extension: ['.json'] })
.globSync()
.sort()
.should.deep.equal(['package.json']);

exclude({ cwd, extension: [] })
.globSync()
.sort()
.should.deep.equal([
'.nycrc',
'file1.js',
'file2.js',
'package.json'
]);

exclude({ cwd, extension: ['.js', '.json'] })
.globSync()
.sort()
.should.deep.equal(['file1.js', 'file2.js', 'package.json']);

exclude({ cwd: path.join(process.cwd(), 'test') })
.globSync(cwd)
.sort()
.should.deep.equal([
'.nycrc',
'file1.js',
'file2.js',
'package.json'
]);
});

it('applies exclude rule ahead of include rule', function() {
const e = exclude({
cwd,
extension,
include: ['file1.js', 'file2.js'],
exclude: ['file1.js']
});

e.globSync()
.sort()
.should.deep.equal(['file2.js']);
});

it('allows node_modules folder to be included, if !node_modules is explicitly provided', function() {
const e = exclude({
cwd,
extension,
exclude: ['!node_modules']
});

e.globSync()
.sort()
.should.deep.equal([
'file1.js',
'file2.js',
'node_modules/something/index.js',
'node_modules/something/other.js'
]);
});

it('allows specific node_modules folder to be included, if !node_modules is explicitly provided', function() {
const e = exclude({
cwd,
extension,
exclude: ['!node_modules/something/other.js']
});

e.globSync()
.sort()
.should.deep.equal([
'file1.js',
'file2.js',
'node_modules/something/other.js'
]);
});

it('allows negated exclude patterns', function() {
const e = exclude({
cwd,
extension,
exclude: ['*.js', '!file1.js']
});

e.globSync()
.sort()
.should.deep.equal(['file1.js']);
});

it('allows negated include patterns', function() {
const e = exclude({
cwd,
include: ['*.js', '!file2.js']
});

e.globSync()
.sort()
.should.deep.equal(['file1.js']);
});
});

// see: https://github.com/istanbuljs/babel-plugin-istanbul/issues/71
it('allows exclude/include rule to be a string', function() {
const e = exclude({
Expand Down

0 comments on commit 2d7ea72

Please sign in to comment.