-
-
Notifications
You must be signed in to change notification settings - Fork 230
/
index.js
136 lines (113 loc) · 3.86 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const arrify = require('arrify')
const minimatch = require('minimatch')
const path = require('path')
const readPkgUp = require('read-pkg-up')
const requireMainFilename = require('require-main-filename')
function TestExclude (opts) {
Object.assign(this, {
cwd: process.cwd(),
include: false,
relativePath: true,
configKey: null, // the key to load config from in package.json.
configPath: null, // optionally override requireMainFilename.
configFound: false,
excludeNodeModules: true
}, opts)
if (typeof this.include === 'string') this.include = [this.include]
if (typeof this.exclude === 'string') this.exclude = [this.exclude]
if (!this.include && !this.exclude && this.configKey) {
Object.assign(this, this.pkgConf(this.configKey, this.configPath))
}
if (!this.exclude || !Array.isArray(this.exclude)) {
this.exclude = exportFunc.defaultExclude
}
if (this.include && this.include.length > 0) {
this.include = prepGlobPatterns(arrify(this.include))
} else {
this.include = false
}
if (this.excludeNodeModules && this.exclude.indexOf('**/node_modules/**') === -1) {
this.exclude.push('**/node_modules/**')
}
this.exclude = prepGlobPatterns(
[].concat(arrify(this.exclude))
)
this.handleNegation()
}
// handle the special case of negative globs
// (!**foo/bar); we create a new this.excludeNegated set
// of rules, which is applied after excludes and we
// move excluded include rules into this.excludes.
TestExclude.prototype.handleNegation = function () {
if (Array.isArray(this.include)) {
const includeNegated = this.include.filter(function (e) {
return e.charAt(0) === '!'
}).map(function (e) {
return e.slice(1)
})
this.exclude.push.apply(this.exclude, prepGlobPatterns(includeNegated))
this.include = this.include.filter(function (e) {
return e.charAt(0) !== '!'
})
}
this.excludeNegated = this.exclude.filter(function (e) {
return e.charAt(0) === '!'
}).map(function (e) {
return e.slice(1)
})
this.exclude = this.exclude.filter(function (e) {
return e.charAt(0) !== '!'
})
this.excludeNegated = prepGlobPatterns(this.excludeNegated)
}
TestExclude.prototype.shouldInstrument = function (filename, relFile) {
var pathToCheck = filename
if (this.relativePath) {
relFile = relFile || path.relative(this.cwd, filename)
// Don't instrument files that are outside of the current working directory.
if (/^\.\./.test(path.relative(this.cwd, filename))) return false
pathToCheck = relFile.replace(/^\.[\\/]/, '') // remove leading './' or '.\'.
}
return (
!this.include ||
this.include.some(include => minimatch(pathToCheck, include, {dot: true}))) &&
(!this.exclude.some(exclude => minimatch(pathToCheck, exclude, {dot: true})) ||
this.excludeNegated.some(exclude => minimatch(pathToCheck, exclude, {dot: true})))
}
TestExclude.prototype.pkgConf = function (key, path) {
const obj = readPkgUp.sync({
cwd: path || requireMainFilename(require)
})
if (obj.pkg && obj.pkg[key] && typeof obj.pkg[key] === 'object') {
this.configFound = true
return obj.pkg[key]
} else {
return {}
}
}
function prepGlobPatterns (patterns) {
return patterns.reduce(function (result, pattern) {
// Allow gitignore style of directory exclusion
if (!/\/\*\*$/.test(pattern)) {
result = result.concat(pattern.replace(/\/$/, '') + '/**')
}
// Any rules of the form **/foo.js, should also match foo.js.
if (/^\*\*\//.test(pattern)) {
result = result.concat(pattern.replace(/^\*\*\//, ''))
}
return result.concat(pattern)
}, [])
}
var exportFunc = function (opts) {
return new TestExclude(opts)
}
exportFunc.defaultExclude = [
'coverage/**',
'packages/*/test/**',
'test/**',
'test{,-*}.js',
'**/*{.,-}test.js',
'**/__tests__/**',
'**/node_modules/**'
]
module.exports = exportFunc