minimatch 0.2.10 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.npmignore ADDED
@@ -0,0 +1 @@
1
+ node_modules
package/README.md CHANGED
@@ -19,6 +19,7 @@ var minimatch = require("minimatch")
19
19
 
20
20
  minimatch("bar.foo", "*.foo") // true!
21
21
  minimatch("bar.foo", "*.bar") // false!
22
+ minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
22
23
  ```
23
24
 
24
25
  ## Features
@@ -36,44 +37,6 @@ See:
36
37
  * `man 3 fnmatch`
37
38
  * `man 5 gitignore`
38
39
 
39
- ### Comparisons to other fnmatch/glob implementations
40
-
41
- While strict compliance with the existing standards is a worthwhile
42
- goal, some discrepancies exist between minimatch and other
43
- implementations, and are intentional.
44
-
45
- If the pattern starts with a `!` character, then it is negated. Set the
46
- `nonegate` flag to suppress this behavior, and treat leading `!`
47
- characters normally. This is perhaps relevant if you wish to start the
48
- pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
49
- characters at the start of a pattern will negate the pattern multiple
50
- times.
51
-
52
- If a pattern starts with `#`, then it is treated as a comment, and
53
- will not match anything. Use `\#` to match a literal `#` at the
54
- start of a line, or set the `nocomment` flag to suppress this behavior.
55
-
56
- The double-star character `**` is supported by default, unless the
57
- `noglobstar` flag is set. This is supported in the manner of bsdglob
58
- and bash 4.1, where `**` only has special significance if it is the only
59
- thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
60
- `a/**b` will not. **Note that this is different from the way that `**` is
61
- handled by ruby's `Dir` class.**
62
-
63
- If an escaped pattern has no matches, and the `nonull` flag is set,
64
- then minimatch.match returns the pattern as-provided, rather than
65
- interpreting the character escapes. For example,
66
- `minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
67
- `"*a?"`. This is akin to setting the `nullglob` option in bash, except
68
- that it does not resolve escaped pattern characters.
69
-
70
- If brace expansion is not disabled, then it is performed before any
71
- other interpretation of the glob pattern. Thus, a pattern like
72
- `+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
73
- **first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
74
- checked for validity. Since those two are valid, matching proceeds.
75
-
76
-
77
40
  ## Minimatch Class
78
41
 
79
42
  Create a minimatch object by instanting the `minimatch.Minimatch` class.
@@ -216,3 +179,40 @@ Suppress the behavior of treating a leading `!` character as negation.
216
179
 
217
180
  Returns from negate expressions the same as if they were not negated.
218
181
  (Ie, true on a hit, false on a miss.)
182
+
183
+
184
+ ## Comparisons to other fnmatch/glob implementations
185
+
186
+ While strict compliance with the existing standards is a worthwhile
187
+ goal, some discrepancies exist between minimatch and other
188
+ implementations, and are intentional.
189
+
190
+ If the pattern starts with a `!` character, then it is negated. Set the
191
+ `nonegate` flag to suppress this behavior, and treat leading `!`
192
+ characters normally. This is perhaps relevant if you wish to start the
193
+ pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
194
+ characters at the start of a pattern will negate the pattern multiple
195
+ times.
196
+
197
+ If a pattern starts with `#`, then it is treated as a comment, and
198
+ will not match anything. Use `\#` to match a literal `#` at the
199
+ start of a line, or set the `nocomment` flag to suppress this behavior.
200
+
201
+ The double-star character `**` is supported by default, unless the
202
+ `noglobstar` flag is set. This is supported in the manner of bsdglob
203
+ and bash 4.1, where `**` only has special significance if it is the only
204
+ thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
205
+ `a/**b` will not.
206
+
207
+ If an escaped pattern has no matches, and the `nonull` flag is set,
208
+ then minimatch.match returns the pattern as-provided, rather than
209
+ interpreting the character escapes. For example,
210
+ `minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
211
+ `"*a?"`. This is akin to setting the `nullglob` option in bash, except
212
+ that it does not resolve escaped pattern characters.
213
+
214
+ If brace expansion is not disabled, then it is performed before any
215
+ other interpretation of the glob pattern. Thus, a pattern like
216
+ `+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
217
+ **first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
218
+ checked for validity. Since those two are valid, matching proceeds.
package/minimatch.js CHANGED
@@ -68,17 +68,6 @@ function charSet (s) {
68
68
  // normalizes slashes.
69
69
  var slashSplit = /\/+/
70
70
 
71
- minimatch.monkeyPatch = monkeyPatch
72
- function monkeyPatch () {
73
- var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
74
- var orig = desc.value
75
- desc.value = function (p) {
76
- if (p instanceof Minimatch) return p.match(this)
77
- return orig.call(this, p)
78
- }
79
- Object.defineProperty(String.prototype, desc)
80
- }
81
-
82
71
  minimatch.filter = filter
83
72
  function filter (pattern, options) {
84
73
  options = options || {}
@@ -178,6 +167,8 @@ function Minimatch (pattern, options) {
178
167
  this.make()
179
168
  }
180
169
 
170
+ Minimatch.prototype.debug = function() {}
171
+
181
172
  Minimatch.prototype.make = make
182
173
  function make () {
183
174
  // don't do it more than once.
@@ -202,7 +193,9 @@ function make () {
202
193
  // step 2: expand braces
203
194
  var set = this.globSet = this.braceExpand()
204
195
 
205
- if (options.debug) console.error(this.pattern, set)
196
+ if (options.debug) this.debug = console.error
197
+
198
+ this.debug(this.pattern, set)
206
199
 
207
200
  // step 3: now we have a set, so turn each one into a series of path-portion
208
201
  // matching patterns.
@@ -213,21 +206,21 @@ function make () {
213
206
  return s.split(slashSplit)
214
207
  })
215
208
 
216
- if (options.debug) console.error(this.pattern, set)
209
+ this.debug(this.pattern, set)
217
210
 
218
211
  // glob --> regexps
219
212
  set = set.map(function (s, si, set) {
220
213
  return s.map(this.parse, this)
221
214
  }, this)
222
215
 
223
- if (options.debug) console.error(this.pattern, set)
216
+ this.debug(this.pattern, set)
224
217
 
225
218
  // filter out everything that didn't compile properly.
226
219
  set = set.filter(function (s) {
227
220
  return -1 === s.indexOf(false)
228
221
  })
229
222
 
230
- if (options.debug) console.error(this.pattern, set)
223
+ this.debug(this.pattern, set)
231
224
 
232
225
  this.set = set
233
226
  }
@@ -302,11 +295,11 @@ function braceExpand (pattern, options) {
302
295
  // So, we pluck that off, and work with the rest,
303
296
  // and then prepend it to everything we find.
304
297
  if (pattern.charAt(0) !== "{") {
305
- // console.error(pattern)
298
+ this.debug(pattern)
306
299
  var prefix = null
307
300
  for (var i = 0, l = pattern.length; i < l; i ++) {
308
301
  var c = pattern.charAt(i)
309
- // console.error(i, c)
302
+ this.debug(i, c)
310
303
  if (c === "\\") {
311
304
  escaping = !escaping
312
305
  } else if (c === "{" && !escaping) {
@@ -317,11 +310,11 @@ function braceExpand (pattern, options) {
317
310
 
318
311
  // actually no sets, all { were escaped.
319
312
  if (prefix === null) {
320
- // console.error("no sets")
313
+ this.debug("no sets")
321
314
  return [pattern]
322
315
  }
323
316
 
324
- var tail = braceExpand(pattern.substr(i), options)
317
+ var tail = braceExpand.call(this, pattern.substr(i), options)
325
318
  return tail.map(function (t) {
326
319
  return prefix + t
327
320
  })
@@ -336,8 +329,8 @@ function braceExpand (pattern, options) {
336
329
  // first, handle numeric sets, since they're easier
337
330
  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
338
331
  if (numset) {
339
- // console.error("numset", numset[1], numset[2])
340
- var suf = braceExpand(pattern.substr(numset[0].length), options)
332
+ this.debug("numset", numset[1], numset[2])
333
+ var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
341
334
  , start = +numset[1]
342
335
  , end = +numset[2]
343
336
  , inc = start > end ? -1 : 1
@@ -369,10 +362,10 @@ function braceExpand (pattern, options) {
369
362
  member = ""
370
363
  }
371
364
 
372
- // console.error("Entering for")
365
+ this.debug("Entering for")
373
366
  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
374
367
  var c = pattern.charAt(i)
375
- // console.error("", i, c)
368
+ this.debug("", i, c)
376
369
 
377
370
  if (escaping) {
378
371
  escaping = false
@@ -420,22 +413,22 @@ function braceExpand (pattern, options) {
420
413
  // pattern.substr(i), or we have *not* closed the set,
421
414
  // and need to escape the leading brace
422
415
  if (depth !== 0) {
423
- // console.error("didn't close", pattern)
424
- return braceExpand("\\" + pattern, options)
416
+ this.debug("didn't close", pattern)
417
+ return braceExpand.call(this, "\\" + pattern, options)
425
418
  }
426
419
 
427
420
  // x{y,z} -> ["xy", "xz"]
428
- // console.error("set", set)
429
- // console.error("suffix", pattern.substr(i))
430
- var suf = braceExpand(pattern.substr(i), options)
421
+ this.debug("set", set)
422
+ this.debug("suffix", pattern.substr(i))
423
+ var suf = braceExpand.call(this, pattern.substr(i), options)
431
424
  // ["b", "c{d,e}","{f,g}h"] ->
432
425
  // [["b"], ["cd", "ce"], ["fh", "gh"]]
433
426
  var addBraces = set.length === 1
434
- // console.error("set pre-expanded", set)
427
+ this.debug("set pre-expanded", set)
435
428
  set = set.map(function (p) {
436
- return braceExpand(p, options)
437
- })
438
- // console.error("set expanded", set)
429
+ return braceExpand.call(this, p, options)
430
+ }, this)
431
+ this.debug("set expanded", set)
439
432
 
440
433
 
441
434
  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
@@ -496,6 +489,7 @@ function parse (pattern, isSub) {
496
489
  // not (start or / followed by . or .. followed by / or end)
497
490
  : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
498
491
  : "(?!\\.)"
492
+ , self = this
499
493
 
500
494
  function clearStateChar () {
501
495
  if (stateChar) {
@@ -514,6 +508,7 @@ function parse (pattern, isSub) {
514
508
  re += "\\"+stateChar
515
509
  break
516
510
  }
511
+ self.debug('clearStateChar %j %j', stateChar, re)
517
512
  stateChar = false
518
513
  }
519
514
  }
@@ -522,9 +517,7 @@ function parse (pattern, isSub) {
522
517
  ; (i < len) && (c = pattern.charAt(i))
523
518
  ; i ++ ) {
524
519
 
525
- if (options.debug) {
526
- console.error("%s\t%s %s %j", pattern, i, re, c)
527
- }
520
+ this.debug("%s\t%s %s %j", pattern, i, re, c)
528
521
 
529
522
  // skip over any that are escaped.
530
523
  if (escaping && reSpecials[c]) {
@@ -551,13 +544,12 @@ function parse (pattern, isSub) {
551
544
  case "+":
552
545
  case "@":
553
546
  case "!":
554
- if (options.debug) {
555
- console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
556
- }
547
+ this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
557
548
 
558
549
  // all of those are literals inside a class, except that
559
550
  // the glob [!a] means [^a] in regexp
560
551
  if (inClass) {
552
+ this.debug(' in class')
561
553
  if (c === "!" && i === classStart + 1) c = "^"
562
554
  re += c
563
555
  continue
@@ -566,6 +558,7 @@ function parse (pattern, isSub) {
566
558
  // if we already have a stateChar, then it means
567
559
  // that there was something like ** or +? in there.
568
560
  // Handle the stateChar, then proceed with this one.
561
+ self.debug('call clearStateChar %j', stateChar)
569
562
  clearStateChar()
570
563
  stateChar = c
571
564
  // if extglob is disabled, then +(asdf|foo) isn't a thing.
@@ -591,6 +584,7 @@ function parse (pattern, isSub) {
591
584
  , reStart: re.length })
592
585
  // negation is (?:(?!js)[^/]*)
593
586
  re += stateChar === "!" ? "(?:(?!" : "(?:"
587
+ this.debug('plType %j %j', stateChar, re)
594
588
  stateChar = false
595
589
  continue
596
590
 
@@ -600,6 +594,7 @@ function parse (pattern, isSub) {
600
594
  continue
601
595
  }
602
596
 
597
+ clearStateChar()
603
598
  hasMagic = true
604
599
  re += ")"
605
600
  plType = patternListStack.pop().type
@@ -623,6 +618,7 @@ function parse (pattern, isSub) {
623
618
  continue
624
619
  }
625
620
 
621
+ clearStateChar()
626
622
  re += "|"
627
623
  continue
628
624
 
@@ -715,7 +711,7 @@ function parse (pattern, isSub) {
715
711
  return $1 + $1 + $2 + "|"
716
712
  })
717
713
 
718
- // console.error("tail=%j\n %s", tail, tail)
714
+ this.debug("tail=%j\n %s", tail, tail)
719
715
  var t = pl.type === "*" ? star
720
716
  : pl.type === "?" ? qmark
721
717
  : "\\" + pl.type
@@ -804,7 +800,7 @@ function makeRe () {
804
800
 
805
801
  // must match entire pattern
806
802
  // ending in a * or ** will make it less strict.
807
- re = "^" + re + "$"
803
+ re = "^(?:" + re + ")$"
808
804
 
809
805
  // can match anything, as long as it's not this.
810
806
  if (this.negate) re = "^(?!" + re + ").*$"
@@ -829,7 +825,7 @@ minimatch.match = function (list, pattern, options) {
829
825
 
830
826
  Minimatch.prototype.match = match
831
827
  function match (f, partial) {
832
- // console.error("match", f, this.pattern)
828
+ this.debug("match", f, this.pattern)
833
829
  // short-circuit in the case of busted things.
834
830
  // comments, etc.
835
831
  if (this.comment) return false
@@ -847,9 +843,7 @@ function match (f, partial) {
847
843
 
848
844
  // treat the test path as a set of pathparts.
849
845
  f = f.split(slashSplit)
850
- if (options.debug) {
851
- console.error(this.pattern, "split", f)
852
- }
846
+ this.debug(this.pattern, "split", f)
853
847
 
854
848
  // just ONE of the pattern sets in this.set needs to match
855
849
  // in order for it to be valid. If negating, then just one
@@ -857,11 +851,16 @@ function match (f, partial) {
857
851
  // Either way, return on the first hit.
858
852
 
859
853
  var set = this.set
860
- // console.error(this.pattern, "set", set)
854
+ this.debug(this.pattern, "set", set)
855
+
856
+ var splitFile = path.basename(f.join("/")).split("/")
861
857
 
862
858
  for (var i = 0, l = set.length; i < l; i ++) {
863
- var pattern = set[i]
864
- var hit = this.matchOne(f, pattern, partial)
859
+ var pattern = set[i], file = f
860
+ if (options.matchBase && pattern.length === 1) {
861
+ file = splitFile
862
+ }
863
+ var hit = this.matchOne(file, pattern, partial)
865
864
  if (hit) {
866
865
  if (options.flipNegate) return true
867
866
  return !this.negate
@@ -882,20 +881,12 @@ function match (f, partial) {
882
881
  Minimatch.prototype.matchOne = function (file, pattern, partial) {
883
882
  var options = this.options
884
883
 
885
- if (options.debug) {
886
- console.error("matchOne",
887
- { "this": this
888
- , file: file
889
- , pattern: pattern })
890
- }
891
-
892
- if (options.matchBase && pattern.length === 1) {
893
- file = path.basename(file.join("/")).split("/")
894
- }
884
+ this.debug("matchOne",
885
+ { "this": this
886
+ , file: file
887
+ , pattern: pattern })
895
888
 
896
- if (options.debug) {
897
- console.error("matchOne", file.length, pattern.length)
898
- }
889
+ this.debug("matchOne", file.length, pattern.length)
899
890
 
900
891
  for ( var fi = 0
901
892
  , pi = 0
@@ -904,23 +895,18 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
904
895
  ; (fi < fl) && (pi < pl)
905
896
  ; fi ++, pi ++ ) {
906
897
 
907
- if (options.debug) {
908
- console.error("matchOne loop")
909
- }
898
+ this.debug("matchOne loop")
910
899
  var p = pattern[pi]
911
900
  , f = file[fi]
912
901
 
913
- if (options.debug) {
914
- console.error(pattern, p, f)
915
- }
902
+ this.debug(pattern, p, f)
916
903
 
917
904
  // should be impossible.
918
905
  // some invalid regexp stuff in the set.
919
906
  if (p === false) return false
920
907
 
921
908
  if (p === GLOBSTAR) {
922
- if (options.debug)
923
- console.error('GLOBSTAR', [pattern, p, f])
909
+ this.debug('GLOBSTAR', [pattern, p, f])
924
910
 
925
911
  // "**"
926
912
  // a/**/b/**/c would match the following:
@@ -947,8 +933,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
947
933
  var fr = fi
948
934
  , pr = pi + 1
949
935
  if (pr === pl) {
950
- if (options.debug)
951
- console.error('** at the end')
936
+ this.debug('** at the end')
952
937
  // a ** at the end will just swallow the rest.
953
938
  // We have found a match.
954
939
  // however, it will not swallow /.x, unless
@@ -966,15 +951,12 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
966
951
  WHILE: while (fr < fl) {
967
952
  var swallowee = file[fr]
968
953
 
969
- if (options.debug) {
970
- console.error('\nglobstar while',
971
- file, fr, pattern, pr, swallowee)
972
- }
954
+ this.debug('\nglobstar while',
955
+ file, fr, pattern, pr, swallowee)
973
956
 
974
957
  // XXX remove this slice. Just pass the start index.
975
958
  if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
976
- if (options.debug)
977
- console.error('globstar found match!', fr, fl, swallowee)
959
+ this.debug('globstar found match!', fr, fl, swallowee)
978
960
  // found a match.
979
961
  return true
980
962
  } else {
@@ -982,14 +964,12 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
982
964
  // can only swallow ".foo" when explicitly asked.
983
965
  if (swallowee === "." || swallowee === ".." ||
984
966
  (!options.dot && swallowee.charAt(0) === ".")) {
985
- if (options.debug)
986
- console.error("dot detected!", file, fr, pattern, pr)
967
+ this.debug("dot detected!", file, fr, pattern, pr)
987
968
  break WHILE
988
969
  }
989
970
 
990
971
  // ** swallows a segment, and continue.
991
- if (options.debug)
992
- console.error('globstar swallow a segment, and continue')
972
+ this.debug('globstar swallow a segment, and continue')
993
973
  fr ++
994
974
  }
995
975
  }
@@ -998,7 +978,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
998
978
  // If there's more *pattern* left, then
999
979
  if (partial) {
1000
980
  // ran out of file
1001
- // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
981
+ this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
1002
982
  if (fr === fl) return true
1003
983
  }
1004
984
  return false
@@ -1014,14 +994,10 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
1014
994
  } else {
1015
995
  hit = f === p
1016
996
  }
1017
- if (options.debug) {
1018
- console.error("string match", p, f, hit)
1019
- }
997
+ this.debug("string match", p, f, hit)
1020
998
  } else {
1021
999
  hit = f.match(p)
1022
- if (options.debug) {
1023
- console.error("pattern match", p, f, hit)
1024
- }
1000
+ this.debug("pattern match", p, f, hit)
1025
1001
  }
1026
1002
 
1027
1003
  if (!hit) return false
package/package.json CHANGED
@@ -2,20 +2,20 @@
2
2
  "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
3
3
  "name": "minimatch",
4
4
  "description": "a glob matcher in javascript",
5
- "version": "0.2.10",
5
+ "version": "0.2.14",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git://github.com/isaacs/minimatch.git"
9
9
  },
10
10
  "main": "minimatch.js",
11
11
  "scripts": {
12
- "test": "tap test"
12
+ "test": "tap test/*.js"
13
13
  },
14
14
  "engines": {
15
15
  "node": "*"
16
16
  },
17
17
  "dependencies": {
18
- "lru-cache": "~2.0.0",
18
+ "lru-cache": "2",
19
19
  "sigmund": "~1.0.0"
20
20
  },
21
21
  "devDependencies": {
package/test/basic.js CHANGED
@@ -13,274 +13,376 @@ var tap = require("tap")
13
13
  , next = files.concat([ "a-b", "aXb"
14
14
  , ".x", ".y" ])
15
15
 
16
+
17
+ var patterns =
18
+ [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
19
+ , ["a*", ["a", "abc", "abd", "abe"]]
20
+ , ["X*", ["X*"], {nonull: true}]
21
+
22
+ // allow null glob expansion
23
+ , ["X*", []]
24
+
25
+ // isaacs: Slightly different than bash/sh/ksh
26
+ // \\* is not un-escaped to literal "*" in a failed match,
27
+ // but it does make it get treated as a literal star
28
+ , ["\\*", ["\\*"], {nonull: true}]
29
+ , ["\\**", ["\\**"], {nonull: true}]
30
+ , ["\\*\\*", ["\\*\\*"], {nonull: true}]
31
+
32
+ , ["b*/", ["bdir/"]]
33
+ , ["c*", ["c", "ca", "cb"]]
34
+ , ["**", files]
35
+
36
+ , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
37
+ , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
38
+
39
+ , "legendary larry crashes bashes"
40
+ , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
41
+ , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
42
+ , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
43
+ , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
44
+
45
+ , "character classes"
46
+ , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
47
+ , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
48
+ "bdir/", "ca", "cb", "dd", "de"]]
49
+ , ["a*[^c]", ["abd", "abe"]]
50
+ , function () { files.push("a-b", "aXb") }
51
+ , ["a[X-]b", ["a-b", "aXb"]]
52
+ , function () { files.push(".x", ".y") }
53
+ , ["[^a-c]*", ["d", "dd", "de"]]
54
+ , function () { files.push("a*b/", "a*b/ooo") }
55
+ , ["a\\*b/*", ["a*b/ooo"]]
56
+ , ["a\\*?/*", ["a*b/ooo"]]
57
+ , ["*\\\\!*", [], {null: true}, ["echo !7"]]
58
+ , ["*\\!*", ["echo !7"], null, ["echo !7"]]
59
+ , ["*.\\*", ["r.*"], null, ["r.*"]]
60
+ , ["a[b]c", ["abc"]]
61
+ , ["a[\\b]c", ["abc"]]
62
+ , ["a?c", ["abc"]]
63
+ , ["a\\*c", [], {null: true}, ["abc"]]
64
+ , ["", [""], { null: true }, [""]]
65
+
66
+ , "http://www.opensource.apple.com/source/bash/bash-23/" +
67
+ "bash/tests/glob-test"
68
+ , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
69
+ , ["*/man*/bash.*", ["man/man1/bash.1"]]
70
+ , ["man/man1/bash.1", ["man/man1/bash.1"]]
71
+ , ["a***c", ["abc"], null, ["abc"]]
72
+ , ["a*****?c", ["abc"], null, ["abc"]]
73
+ , ["?*****??", ["abc"], null, ["abc"]]
74
+ , ["*****??", ["abc"], null, ["abc"]]
75
+ , ["?*****?c", ["abc"], null, ["abc"]]
76
+ , ["?***?****c", ["abc"], null, ["abc"]]
77
+ , ["?***?****?", ["abc"], null, ["abc"]]
78
+ , ["?***?****", ["abc"], null, ["abc"]]
79
+ , ["*******c", ["abc"], null, ["abc"]]
80
+ , ["*******?", ["abc"], null, ["abc"]]
81
+ , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
82
+ , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
83
+ , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
84
+ , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
85
+ , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
86
+ , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
87
+ , ["[-abc]", ["-"], null, ["-"]]
88
+ , ["[abc-]", ["-"], null, ["-"]]
89
+ , ["\\", ["\\"], null, ["\\"]]
90
+ , ["[\\\\]", ["\\"], null, ["\\"]]
91
+ , ["[[]", ["["], null, ["["]]
92
+ , ["[", ["["], null, ["["]]
93
+ , ["[*", ["[abc"], null, ["[abc"]]
94
+ , "a right bracket shall lose its special meaning and\n" +
95
+ "represent itself in a bracket expression if it occurs\n" +
96
+ "first in the list. -- POSIX.2 2.8.3.2"
97
+ , ["[]]", ["]"], null, ["]"]]
98
+ , ["[]-]", ["]"], null, ["]"]]
99
+ , ["[a-\z]", ["p"], null, ["p"]]
100
+ , ["??**********?****?", [], { null: true }, ["abc"]]
101
+ , ["??**********?****c", [], { null: true }, ["abc"]]
102
+ , ["?************c****?****", [], { null: true }, ["abc"]]
103
+ , ["*c*?**", [], { null: true }, ["abc"]]
104
+ , ["a*****c*?**", [], { null: true }, ["abc"]]
105
+ , ["a********???*******", [], { null: true }, ["abc"]]
106
+ , ["[]", [], { null: true }, ["a"]]
107
+ , ["[abc", [], { null: true }, ["["]]
108
+
109
+ , "nocase tests"
110
+ , ["XYZ", ["xYz"], { nocase: true, null: true }
111
+ , ["xYz", "ABC", "IjK"]]
112
+ , ["ab*", ["ABC"], { nocase: true, null: true }
113
+ , ["xYz", "ABC", "IjK"]]
114
+ , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
115
+ , ["xYz", "ABC", "IjK"]]
116
+
117
+ // [ pattern, [matches], MM opts, files, TAP opts]
118
+ , "onestar/twostar"
119
+ , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
120
+ , ["{/?,*}", ["/a", "bb"], {null: true}
121
+ , ["/a", "/b/b", "/a/b/c", "bb"]]
122
+
123
+ , "dots should not match unless requested"
124
+ , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
125
+
126
+ // .. and . can only match patterns starting with .,
127
+ // even when options.dot is set.
128
+ , function () {
129
+ files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
130
+ }
131
+ , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
132
+ , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
133
+ , ["a/*/b", ["a/c/b"], {dot:false}]
134
+ , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
135
+
136
+
137
+ // this also tests that changing the options needs
138
+ // to change the cache key, even if the pattern is
139
+ // the same!
140
+ , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
141
+ , [ ".a/.d", "a/.d", "a/b"]]
142
+
143
+ , "paren sets cannot contain slashes"
144
+ , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
145
+
146
+ // brace sets trump all else.
147
+ //
148
+ // invalid glob pattern. fails on bash4 and bsdglob.
149
+ // however, in this implementation, it's easier just
150
+ // to do the intuitive thing, and let brace-expansion
151
+ // actually come before parsing any extglob patterns,
152
+ // like the documentation seems to say.
153
+ //
154
+ // XXX: if anyone complains about this, either fix it
155
+ // or tell them to grow up and stop complaining.
156
+ //
157
+ // bash/bsdglob says this:
158
+ // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
159
+ // but we do this instead:
160
+ , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
161
+
162
+ // test partial parsing in the presence of comment/negation chars
163
+ , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
164
+ , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
165
+
166
+ // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
167
+ , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
168
+ , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
169
+ , {}
170
+ , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
171
+
172
+
173
+ // crazy nested {,,} and *(||) tests.
174
+ , function () {
175
+ files = [ "a", "b", "c", "d"
176
+ , "ab", "ac", "ad"
177
+ , "bc", "cb"
178
+ , "bc,d", "c,db", "c,d"
179
+ , "d)", "(b|c", "*(b|c"
180
+ , "b|c", "b|cc", "cb|c"
181
+ , "x(a|b|c)", "x(a|c)"
182
+ , "(a|b|c)", "(a|c)"]
183
+ }
184
+ , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
185
+ , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
186
+ // a
187
+ // *(b|c)
188
+ // *(b|d)
189
+ , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
190
+ , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
191
+
192
+
193
+ // test various flag settings.
194
+ , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
195
+ , { noext: true } ]
196
+ , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
197
+ , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
198
+ , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
199
+
200
+
201
+ // begin channelling Boole and deMorgan...
202
+ , "negation tests"
203
+ , function () {
204
+ files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
205
+ }
206
+
207
+ // anything that is NOT a* matches.
208
+ , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
209
+
210
+ // anything that IS !a* matches.
211
+ , ["!a*", ["!ab", "!abc"], {nonegate: true}]
212
+
213
+ // anything that IS a* matches
214
+ , ["!!a*", ["a!b"]]
215
+
216
+ // anything that is NOT !a* matches
217
+ , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
218
+
219
+ // negation nestled within a pattern
220
+ , function () {
221
+ files = [ "foo.js"
222
+ , "foo.bar"
223
+ // can't match this one without negative lookbehind.
224
+ , "foo.js.js"
225
+ , "blar.js"
226
+ , "foo."
227
+ , "boo.js.boo" ]
228
+ }
229
+ , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
230
+
231
+ // https://github.com/isaacs/minimatch/issues/5
232
+ , function () {
233
+ files = [ 'a/b/.x/c'
234
+ , 'a/b/.x/c/d'
235
+ , 'a/b/.x/c/d/e'
236
+ , 'a/b/.x'
237
+ , 'a/b/.x/'
238
+ , 'a/.x/b'
239
+ , '.x'
240
+ , '.x/'
241
+ , '.x/a'
242
+ , '.x/a/b'
243
+ , 'a/.x/b/.x/c'
244
+ , '.x/.x' ]
245
+ }
246
+ , ["**/.x/**", [ '.x/'
247
+ , '.x/a'
248
+ , '.x/a/b'
249
+ , 'a/.x/b'
250
+ , 'a/b/.x/'
251
+ , 'a/b/.x/c'
252
+ , 'a/b/.x/c/d'
253
+ , 'a/b/.x/c/d/e' ] ]
254
+
255
+ ]
256
+
257
+ var regexps =
258
+ [ '/^(?:(?=.)a[^/]*?)$/',
259
+ '/^(?:(?=.)X[^/]*?)$/',
260
+ '/^(?:(?=.)X[^/]*?)$/',
261
+ '/^(?:\\*)$/',
262
+ '/^(?:(?=.)\\*[^/]*?)$/',
263
+ '/^(?:\\*\\*)$/',
264
+ '/^(?:(?=.)b[^/]*?\\/)$/',
265
+ '/^(?:(?=.)c[^/]*?)$/',
266
+ '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
267
+ '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
268
+ '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
269
+ '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
270
+ '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
271
+ '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
272
+ '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
273
+ '/^(?:(?=.)a[^/]*?[^c])$/',
274
+ '/^(?:(?=.)a[X-]b)$/',
275
+ '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
276
+ '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
277
+ '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
278
+ '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
279
+ '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
280
+ '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
281
+ '/^(?:(?=.)a[b]c)$/',
282
+ '/^(?:(?=.)a[b]c)$/',
283
+ '/^(?:(?=.)a[^/]c)$/',
284
+ '/^(?:a\\*c)$/',
285
+ 'false',
286
+ '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
287
+ '/^(?:man\\/man1\\/bash\\.1)$/',
288
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
289
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
290
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
291
+ '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
292
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
293
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
294
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
295
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
296
+ '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
297
+ '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
298
+ '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
299
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
300
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
301
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
302
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
303
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
304
+ '/^(?:(?!\\.)(?=.)[-abc])$/',
305
+ '/^(?:(?!\\.)(?=.)[abc-])$/',
306
+ '/^(?:\\\\)$/',
307
+ '/^(?:(?!\\.)(?=.)[\\\\])$/',
308
+ '/^(?:(?!\\.)(?=.)[\\[])$/',
309
+ '/^(?:\\[)$/',
310
+ '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
311
+ '/^(?:(?!\\.)(?=.)[\\]])$/',
312
+ '/^(?:(?!\\.)(?=.)[\\]-])$/',
313
+ '/^(?:(?!\\.)(?=.)[a-z])$/',
314
+ '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
315
+ '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
316
+ '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
317
+ '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
318
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
319
+ '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
320
+ '/^(?:\\[\\])$/',
321
+ '/^(?:\\[abc)$/',
322
+ '/^(?:(?=.)XYZ)$/i',
323
+ '/^(?:(?=.)ab[^/]*?)$/i',
324
+ '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
325
+ '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
326
+ '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
327
+ '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
328
+ '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
329
+ '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
330
+ '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
331
+ '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
332
+ '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
333
+ '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
334
+ '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
335
+ '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
336
+ '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
337
+ '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
338
+ '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
339
+ '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
340
+ '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
341
+ '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
342
+ '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
343
+ '/^(?:(?=.)a[^/]b)$/',
344
+ '/^(?:(?=.)#[^/]*?)$/',
345
+ '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
346
+ '/^(?:(?=.)\\!a[^/]*?)$/',
347
+ '/^(?:(?=.)a[^/]*?)$/',
348
+ '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
349
+ '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
350
+ '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
351
+ var re = 0;
352
+
16
353
  tap.test("basic tests", function (t) {
17
354
  var start = Date.now()
18
355
 
19
356
  // [ pattern, [matches], MM opts, files, TAP opts]
20
- ; [ "http://www.bashcookbook.com/bashinfo" +
21
- "/source/bash-1.14.7/tests/glob-test"
22
- , ["a*", ["a", "abc", "abd", "abe"]]
23
- , ["X*", ["X*"], {nonull: true}]
24
-
25
- // allow null glob expansion
26
- , ["X*", []]
27
-
28
- // isaacs: Slightly different than bash/sh/ksh
29
- // \\* is not un-escaped to literal "*" in a failed match,
30
- // but it does make it get treated as a literal star
31
- , ["\\*", ["\\*"], {nonull: true}]
32
- , ["\\**", ["\\**"], {nonull: true}]
33
- , ["\\*\\*", ["\\*\\*"], {nonull: true}]
34
-
35
- , ["b*/", ["bdir/"]]
36
- , ["c*", ["c", "ca", "cb"]]
37
- , ["**", files]
38
-
39
- , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
40
- , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
41
-
42
- , "legendary larry crashes bashes"
43
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
44
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
45
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
46
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
47
-
48
- , "character classes"
49
- , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
50
- , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
51
- "bdir/", "ca", "cb", "dd", "de"]]
52
- , ["a*[^c]", ["abd", "abe"]]
53
- , function () { files.push("a-b", "aXb") }
54
- , ["a[X-]b", ["a-b", "aXb"]]
55
- , function () { files.push(".x", ".y") }
56
- , ["[^a-c]*", ["d", "dd", "de"]]
57
- , function () { files.push("a*b/", "a*b/ooo") }
58
- , ["a\\*b/*", ["a*b/ooo"]]
59
- , ["a\\*?/*", ["a*b/ooo"]]
60
- , ["*\\\\!*", [], {null: true}, ["echo !7"]]
61
- , ["*\\!*", ["echo !7"], null, ["echo !7"]]
62
- , ["*.\\*", ["r.*"], null, ["r.*"]]
63
- , ["a[b]c", ["abc"]]
64
- , ["a[\\b]c", ["abc"]]
65
- , ["a?c", ["abc"]]
66
- , ["a\\*c", [], {null: true}, ["abc"]]
67
- , ["", [""], { null: true }, [""]]
68
-
69
- , "http://www.opensource.apple.com/source/bash/bash-23/" +
70
- "bash/tests/glob-test"
71
- , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
72
- , ["*/man*/bash.*", ["man/man1/bash.1"]]
73
- , ["man/man1/bash.1", ["man/man1/bash.1"]]
74
- , ["a***c", ["abc"], null, ["abc"]]
75
- , ["a*****?c", ["abc"], null, ["abc"]]
76
- , ["?*****??", ["abc"], null, ["abc"]]
77
- , ["*****??", ["abc"], null, ["abc"]]
78
- , ["?*****?c", ["abc"], null, ["abc"]]
79
- , ["?***?****c", ["abc"], null, ["abc"]]
80
- , ["?***?****?", ["abc"], null, ["abc"]]
81
- , ["?***?****", ["abc"], null, ["abc"]]
82
- , ["*******c", ["abc"], null, ["abc"]]
83
- , ["*******?", ["abc"], null, ["abc"]]
84
- , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
85
- , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
86
- , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
87
- , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
88
- , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
89
- , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
90
- , ["[-abc]", ["-"], null, ["-"]]
91
- , ["[abc-]", ["-"], null, ["-"]]
92
- , ["\\", ["\\"], null, ["\\"]]
93
- , ["[\\\\]", ["\\"], null, ["\\"]]
94
- , ["[[]", ["["], null, ["["]]
95
- , ["[", ["["], null, ["["]]
96
- , ["[*", ["[abc"], null, ["[abc"]]
97
- , "a right bracket shall lose its special meaning and\n" +
98
- "represent itself in a bracket expression if it occurs\n" +
99
- "first in the list. -- POSIX.2 2.8.3.2"
100
- , ["[]]", ["]"], null, ["]"]]
101
- , ["[]-]", ["]"], null, ["]"]]
102
- , ["[a-\z]", ["p"], null, ["p"]]
103
- , ["??**********?****?", [], { null: true }, ["abc"]]
104
- , ["??**********?****c", [], { null: true }, ["abc"]]
105
- , ["?************c****?****", [], { null: true }, ["abc"]]
106
- , ["*c*?**", [], { null: true }, ["abc"]]
107
- , ["a*****c*?**", [], { null: true }, ["abc"]]
108
- , ["a********???*******", [], { null: true }, ["abc"]]
109
- , ["[]", [], { null: true }, ["a"]]
110
- , ["[abc", [], { null: true }, ["["]]
111
-
112
- , "nocase tests"
113
- , ["XYZ", ["xYz"], { nocase: true, null: true }
114
- , ["xYz", "ABC", "IjK"]]
115
- , ["ab*", ["ABC"], { nocase: true, null: true }
116
- , ["xYz", "ABC", "IjK"]]
117
- , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
118
- , ["xYz", "ABC", "IjK"]]
119
-
120
- // [ pattern, [matches], MM opts, files, TAP opts]
121
- , "onestar/twostar"
122
- , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
123
- , ["{/?,*}", ["/a", "bb"], {null: true}
124
- , ["/a", "/b/b", "/a/b/c", "bb"]]
125
-
126
- , "dots should not match unless requested"
127
- , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
128
-
129
- // .. and . can only match patterns starting with .,
130
- // even when options.dot is set.
131
- , function () {
132
- files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
133
- }
134
- , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
135
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
136
- , ["a/*/b", ["a/c/b"], {dot:false}]
137
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
138
-
139
-
140
- // this also tests that changing the options needs
141
- // to change the cache key, even if the pattern is
142
- // the same!
143
- , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
144
- , [ ".a/.d", "a/.d", "a/b"]]
145
-
146
- , "paren sets cannot contain slashes"
147
- , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
148
-
149
- // brace sets trump all else.
150
- //
151
- // invalid glob pattern. fails on bash4 and bsdglob.
152
- // however, in this implementation, it's easier just
153
- // to do the intuitive thing, and let brace-expansion
154
- // actually come before parsing any extglob patterns,
155
- // like the documentation seems to say.
156
- //
157
- // XXX: if anyone complains about this, either fix it
158
- // or tell them to grow up and stop complaining.
159
- //
160
- // bash/bsdglob says this:
161
- // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
162
- // but we do this instead:
163
- , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
164
-
165
- // test partial parsing in the presence of comment/negation chars
166
- , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
167
- , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
168
-
169
- // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
170
- , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
171
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
172
- , {}
173
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
174
-
175
-
176
- // crazy nested {,,} and *(||) tests.
177
- , function () {
178
- files = [ "a", "b", "c", "d"
179
- , "ab", "ac", "ad"
180
- , "bc", "cb"
181
- , "bc,d", "c,db", "c,d"
182
- , "d)", "(b|c", "*(b|c"
183
- , "b|c", "b|cc", "cb|c"
184
- , "x(a|b|c)", "x(a|c)"
185
- , "(a|b|c)", "(a|c)"]
186
- }
187
- , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
188
- , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
189
- // a
190
- // *(b|c)
191
- // *(b|d)
192
- , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
193
- , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
194
-
195
-
196
- // test various flag settings.
197
- , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
198
- , { noext: true } ]
199
- , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
200
- , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
201
- , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
202
-
203
-
204
- // begin channelling Boole and deMorgan...
205
- , "negation tests"
206
- , function () {
207
- files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
208
- }
209
-
210
- // anything that is NOT a* matches.
211
- , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
212
-
213
- // anything that IS !a* matches.
214
- , ["!a*", ["!ab", "!abc"], {nonegate: true}]
215
-
216
- // anything that IS a* matches
217
- , ["!!a*", ["a!b"]]
218
-
219
- // anything that is NOT !a* matches
220
- , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
221
-
222
- // negation nestled within a pattern
223
- , function () {
224
- files = [ "foo.js"
225
- , "foo.bar"
226
- // can't match this one without negative lookbehind.
227
- , "foo.js.js"
228
- , "blar.js"
229
- , "foo."
230
- , "boo.js.boo" ]
231
- }
232
- , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
233
-
234
- // https://github.com/isaacs/minimatch/issues/5
235
- , function () {
236
- files = [ 'a/b/.x/c'
237
- , 'a/b/.x/c/d'
238
- , 'a/b/.x/c/d/e'
239
- , 'a/b/.x'
240
- , 'a/b/.x/'
241
- , 'a/.x/b'
242
- , '.x'
243
- , '.x/'
244
- , '.x/a'
245
- , '.x/a/b'
246
- , 'a/.x/b/.x/c'
247
- , '.x/.x' ]
248
- }
249
- , ["**/.x/**", [ '.x/'
250
- , '.x/a'
251
- , '.x/a/b'
252
- , 'a/.x/b'
253
- , 'a/b/.x/'
254
- , 'a/b/.x/c'
255
- , 'a/b/.x/c/d'
256
- , 'a/b/.x/c/d/e' ] ]
257
-
258
- ].forEach(function (c) {
259
- if (typeof c === "function") return c()
260
- if (typeof c === "string") return t.comment(c)
261
-
262
- var pattern = c[0]
263
- , expect = c[1].sort(alpha)
264
- , options = c[2] || {}
265
- , f = c[3] || files
266
- , tapOpts = c[4] || {}
267
-
268
- // options.debug = true
269
- var m = new mm.Minimatch(pattern, options)
270
- var r = m.makeRe()
271
- tapOpts.re = String(r) || JSON.stringify(r)
272
- tapOpts.files = JSON.stringify(f)
273
- tapOpts.pattern = pattern
274
- tapOpts.set = m.set
275
- tapOpts.negated = m.negate
276
-
277
- var actual = mm.match(f, pattern, options)
278
- actual.sort(alpha)
279
-
280
- t.equivalent( actual, expect
281
- , JSON.stringify(pattern) + " " + JSON.stringify(expect)
282
- , tapOpts )
283
- })
357
+ patterns.forEach(function (c) {
358
+ if (typeof c === "function") return c()
359
+ if (typeof c === "string") return t.comment(c)
360
+
361
+ var pattern = c[0]
362
+ , expect = c[1].sort(alpha)
363
+ , options = c[2] || {}
364
+ , f = c[3] || files
365
+ , tapOpts = c[4] || {}
366
+
367
+ // options.debug = true
368
+ var m = new mm.Minimatch(pattern, options)
369
+ var r = m.makeRe()
370
+ var expectRe = regexps[re++]
371
+ tapOpts.re = String(r) || JSON.stringify(r)
372
+ tapOpts.files = JSON.stringify(f)
373
+ tapOpts.pattern = pattern
374
+ tapOpts.set = m.set
375
+ tapOpts.negated = m.negate
376
+
377
+ var actual = mm.match(f, pattern, options)
378
+ actual.sort(alpha)
379
+
380
+ t.equivalent( actual, expect
381
+ , JSON.stringify(pattern) + " " + JSON.stringify(expect)
382
+ , tapOpts )
383
+
384
+ t.equal(tapOpts.re, expectRe, tapOpts)
385
+ })
284
386
 
285
387
  t.comment("time=" + (Date.now() - start) + "ms")
286
388
  t.end()
@@ -0,0 +1,8 @@
1
+ var test = require('tap').test
2
+ var minimatch = require('../')
3
+
4
+ test('extglob ending with statechar', function(t) {
5
+ t.notOk(minimatch('ax', 'a?(b*)'))
6
+ t.ok(minimatch('ax', '?(a*|b)'))
7
+ t.end()
8
+ })
package/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - 0.4
4
- - 0.6