Skip to content

Commit dbda065

Browse files
committed
full test coverage, adding tests, deleting dead code
1 parent 47e0e45 commit dbda065

File tree

4 files changed

+112
-54
lines changed

4 files changed

+112
-54
lines changed

README.md

-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ Suppress the behavior of treating a leading `!` character as negation.
171171
Returns from negate expressions the same as if they were not negated.
172172
(Ie, true on a hit, false on a miss.)
173173

174-
175174
## Comparisons to other fnmatch/glob implementations
176175

177176
While strict compliance with the existing standards is a worthwhile

minimatch.js

+29-38
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ function filter (pattern, options) {
5656
}
5757

5858
function ext (a, b) {
59-
a = a || {}
6059
b = b || {}
6160
const t = {}
6261
Object.keys(a).forEach(function (k) {
@@ -123,9 +122,6 @@ function minimatch (p, pattern, options) {
123122
return false
124123
}
125124

126-
// "" only matches ""
127-
if (pattern.trim() === '') return p === ''
128-
129125
return new Minimatch(pattern, options).match(p)
130126
}
131127

@@ -137,7 +133,6 @@ function Minimatch (pattern, options) {
137133
assertValidPattern(pattern)
138134

139135
if (!options) options = {}
140-
pattern = pattern.trim()
141136

142137
// windows support: need to use /, not \
143138
if (path.sep !== '/') {
@@ -160,9 +155,6 @@ Minimatch.prototype.debug = function () {}
160155

161156
Minimatch.prototype.make = make
162157
function make () {
163-
// don't do it more than once.
164-
if (this._made) return
165-
166158
var pattern = this.pattern
167159
var options = this.options
168160

@@ -182,7 +174,7 @@ function make () {
182174
// step 2: expand braces
183175
var set = this.globSet = this.braceExpand()
184176

185-
if (options.debug) this.debug = console.error
177+
if (options.debug) this.debug = (...args) => console.error(...args)
186178

187179
this.debug(this.pattern, set)
188180

@@ -304,7 +296,12 @@ function parse (pattern, isSub) {
304296
var options = this.options
305297

306298
// shortcuts
307-
if (!options.noglobstar && pattern === '**') return GLOBSTAR
299+
if (pattern === '**') {
300+
if (!options.noglobstar)
301+
return GLOBSTAR
302+
else
303+
pattern = '*'
304+
}
308305
if (pattern === '') return ''
309306

310307
var re = ''
@@ -360,7 +357,8 @@ function parse (pattern, isSub) {
360357
}
361358

362359
switch (c) {
363-
case '/': /* istanbul ignore next */ {
360+
/* istanbul ignore next */
361+
case '/': {
364362
// completely not allowed, even escaped.
365363
// Should already be path-split by now.
366364
return false
@@ -483,25 +481,23 @@ function parse (pattern, isSub) {
483481

484482
// handle the case where we left a class open.
485483
// "[z-a]" is valid, equivalent to "\[z-a\]"
486-
if (inClass) {
487-
// split where the last [ was, make sure we don't have
488-
// an invalid re. if so, re-walk the contents of the
489-
// would-be class to re-translate any characters that
490-
// were passed through as-is
491-
// TODO: It would probably be faster to determine this
492-
// without a try/catch and a new RegExp, but it's tricky
493-
// to do safely. For now, this is safe and works.
494-
var cs = pattern.substring(classStart + 1, i)
495-
try {
496-
RegExp('[' + cs + ']')
497-
} catch (er) {
498-
// not a valid class!
499-
var sp = this.parse(cs, SUBPARSE)
500-
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
501-
hasMagic = hasMagic || sp[1]
502-
inClass = false
503-
continue
504-
}
484+
// split where the last [ was, make sure we don't have
485+
// an invalid re. if so, re-walk the contents of the
486+
// would-be class to re-translate any characters that
487+
// were passed through as-is
488+
// TODO: It would probably be faster to determine this
489+
// without a try/catch and a new RegExp, but it's tricky
490+
// to do safely. For now, this is safe and works.
491+
var cs = pattern.substring(classStart + 1, i)
492+
try {
493+
RegExp('[' + cs + ']')
494+
} catch (er) {
495+
// not a valid class!
496+
var sp = this.parse(cs, SUBPARSE)
497+
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
498+
hasMagic = hasMagic || sp[1]
499+
inClass = false
500+
continue
505501
}
506502

507503
// finish up the class.
@@ -585,9 +581,7 @@ function parse (pattern, isSub) {
585581
// something that could conceivably capture a dot
586582
var addPatternStart = false
587583
switch (re.charAt(0)) {
588-
case '.':
589-
case '[':
590-
case '(': addPatternStart = true
584+
case '[': case '.': case '(': addPatternStart = true
591585
}
592586

593587
// Hack to work around lack of negative lookbehind in JS
@@ -725,16 +719,13 @@ minimatch.match = function (list, pattern, options) {
725719
return list
726720
}
727721

728-
Minimatch.prototype.match = match
729-
function match (f, partial) {
722+
Minimatch.prototype.match = function match (f) {
730723
this.debug('match', f, this.pattern)
731724
// short-circuit in the case of busted things.
732725
// comments, etc.
733726
if (this.comment) return false
734727
if (this.empty) return f === ''
735728

736-
if (f === '/' && partial) return true
737-
738729
var options = this.options
739730

740731
// windows: need to use /, not \
@@ -768,7 +759,7 @@ function match (f, partial) {
768759
if (options.matchBase && pattern.length === 1) {
769760
file = [filename]
770761
}
771-
var hit = this.matchOne(file, pattern, partial)
762+
var hit = this.matchOne(file, pattern, false)
772763
if (hit) {
773764
if (options.flipNegate) return true
774765
return !this.negate

test/basic.js

+68-12
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
// TODO: Some of these tests do very bad things with backslashes, and will
44
// most likely fail badly on windows. They should probably be skipped.
55

6-
var tap = require('tap')
7-
var globalBefore = Object.keys(global)
8-
var mm = require('../')
9-
var patterns = require('./patterns.js')
10-
var regexps = patterns.regexps
11-
var re = 0
12-
13-
tap.test('basic tests', function (t) {
6+
const t = require('tap')
7+
const globalBefore = Object.keys(global)
8+
const mm = require('../')
9+
const patterns = require('./patterns.js')
10+
const regexps = patterns.regexps
11+
let re = 0
12+
13+
t.test('basic tests', function (t) {
1414
var start = Date.now()
1515

1616
// [ pattern, [matches], MM opts, files, TAP opts]
@@ -58,15 +58,15 @@ tap.test('basic tests', function (t) {
5858
t.end()
5959
})
6060

61-
tap.test('global leak test', function (t) {
61+
t.test('global leak test', function (t) {
6262
var globalAfter = Object.keys(global).filter(function (k) {
6363
return (k !== '__coverage__' && k !== '__core-js_shared__')
6464
})
6565
t.same(globalAfter, globalBefore, 'no new globals, please')
6666
t.end()
6767
})
6868

69-
tap.test('invalid patterns', t => {
69+
t.test('invalid patterns', t => {
7070
const toolong = 'x'.repeat(64 * 1024) + 'y'
7171
const expectTooLong = { message: 'pattern is too long' }
7272
t.throws(() => mm.braceExpand(toolong), expectTooLong)
@@ -95,19 +95,75 @@ tap.test('invalid patterns', t => {
9595
t.end()
9696
})
9797

98-
tap.test('ctor is generator', t => {
98+
t.test('ctor is generator', t => {
9999
const m = mm.Minimatch('asdf')
100100
t.type(m, mm.Minimatch)
101101
t.equal(m.pattern, 'asdf')
102102
t.end()
103103
})
104104

105-
tap.test('nocomment matches nothing', t => {
105+
t.test('nocomment matches nothing', t => {
106106
t.equal(mm('#comment', '#comment', { nocomment: false }), false)
107107
t.equal(mm('#comment', '#comment', { nocomment: true }), true)
108108
t.end()
109109
})
110110

111+
t.test('filter function', t => {
112+
t.same(['a', 'b', 'c'].filter(mm.filter('@(a|b)')), ['a', 'b'])
113+
t.end()
114+
})
115+
116+
t.test('whitespace handling', t => {
117+
t.equal(mm('x/y', 'y'), false)
118+
t.equal(mm('x/y', 'y', { matchBase: true }), true)
119+
t.equal(mm('x/ ', ' '), false)
120+
t.equal(mm('x/ ', ' ', { matchBase: true }), true)
121+
t.equal(mm('x/', ''), false)
122+
t.equal(mm('x/', '', { matchBase: true }), false)
123+
t.equal(mm('', ''), true)
124+
t.equal(mm(' ', ''), false)
125+
t.equal(mm('', ' '), false)
126+
t.equal(mm(' ', ' '), true)
127+
t.end()
128+
})
129+
130+
t.test('mm debug', t => {
131+
const { error } = console
132+
t.teardown(() => console.error = error)
133+
const errs = []
134+
console.error = (...msg) => errs.push(msg)
135+
t.equal(mm('a/b/c', 'a/**/@(b|c)/**', { debug: true }), true)
136+
t.not(errs.length, 0)
137+
t.end()
138+
})
139+
140+
t.test('makeRe repeated', t => {
141+
const mmRE = mm.makeRe('a/*/*')
142+
const m = new mm.Minimatch('a/*/*')
143+
const mRE = m.makeRe()
144+
const mRE2 = m.makeRe()
145+
t.equal(mRE, mRE2)
146+
t.same(mmRE, mRE)
147+
t.end()
148+
})
149+
150+
t.test('in noglobstar mode, ** is equivalent to *', t => {
151+
const re2s = mm.makeRe('**', { noglobstar: true })
152+
const re1s = mm.makeRe('*', { noglobstar: true })
153+
t.same(re2s, re1s)
154+
t.end()
155+
})
156+
157+
t.test('flipNegate', t => {
158+
t.equal(mm('x', '!x', { flipNegate: true }), true)
159+
t.equal(mm('x', '!!x', { flipNegate: true }), true)
160+
t.equal(mm('x', 'x', { flipNegate: true }), true)
161+
162+
t.equal(mm('x', '!y', { flipNegate: true }), false)
163+
t.equal(mm('x', '!!y', { flipNegate: true }), false)
164+
t.equal(mm('x', 'y', { flipNegate: true }), false)
165+
t.end()
166+
})
111167

112168
function alpha (a, b) {
113169
return a > b ? 1 : -1

test/win-path-sep.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
const t = require('tap')
2-
const mm = t.mock('../', { path: { sep: '\\' }})
2+
t.test('path separator \\', t => {
3+
const mm = t.mock('../', { path: { sep: '\\' }})
34

4-
t.equal(mm('x\\y\\z', 'x/y/*/z'), false)
5-
t.equal(mm('x\\y\\w\\z', 'x/y/*/z'), true)
5+
t.equal(mm('x\\y\\z', 'x/y/*/z'), false)
6+
t.equal(mm('x\\y\\w\\z', 'x/y/*/z'), true)
7+
t.end()
8+
})
9+
10+
// just in case Node every adds Mac OS 9 support 😅
11+
t.test('path separator :', t => {
12+
const mm = t.mock('../', { path: { sep: ':' }})
13+
14+
t.equal(mm('x:y:z', 'x/y/*/z'), false)
15+
t.equal(mm('x:y:w:z', 'x/y/*/z'), true)
16+
t.end()
17+
})

0 commit comments

Comments
 (0)