minimatch 0.2.11 → 0.3.0

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.
@@ -194,8 +157,8 @@ Perform a case-insensitive match.
194
157
  ### nonull
195
158
 
196
159
  When a match is not found by `minimatch.match`, return a list containing
197
- the pattern itself. When set, an empty list is returned if there are
198
- no matches.
160
+ the pattern itself if this option is set. When not set, an empty list
161
+ is returned if there are no matches.
199
162
 
200
163
  ### matchBase
201
164
 
@@ -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 + ").*$"
@@ -817,11 +813,12 @@ function makeRe () {
817
813
  }
818
814
 
819
815
  minimatch.match = function (list, pattern, options) {
816
+ options = options || {}
820
817
  var mm = new Minimatch(pattern, options)
821
818
  list = list.filter(function (f) {
822
819
  return mm.match(f)
823
820
  })
824
- if (options.nonull && !list.length) {
821
+ if (mm.options.nonull && !list.length) {
825
822
  list.push(pattern)
826
823
  }
827
824
  return list
@@ -829,7 +826,7 @@ minimatch.match = function (list, pattern, options) {
829
826
 
830
827
  Minimatch.prototype.match = match
831
828
  function match (f, partial) {
832
- // console.error("match", f, this.pattern)
829
+ this.debug("match", f, this.pattern)
833
830
  // short-circuit in the case of busted things.
834
831
  // comments, etc.
835
832
  if (this.comment) return false
@@ -847,9 +844,7 @@ function match (f, partial) {
847
844
 
848
845
  // treat the test path as a set of pathparts.
849
846
  f = f.split(slashSplit)
850
- if (options.debug) {
851
- console.error(this.pattern, "split", f)
852
- }
847
+ this.debug(this.pattern, "split", f)
853
848
 
854
849
  // just ONE of the pattern sets in this.set needs to match
855
850
  // in order for it to be valid. If negating, then just one
@@ -857,11 +852,21 @@ function match (f, partial) {
857
852
  // Either way, return on the first hit.
858
853
 
859
854
  var set = this.set
860
- // console.error(this.pattern, "set", set)
855
+ this.debug(this.pattern, "set", set)
856
+
857
+ // Find the basename of the path by looking for the last non-empty segment
858
+ var filename;
859
+ for (var i = f.length - 1; i >= 0; i--) {
860
+ filename = f[i]
861
+ if (filename) break
862
+ }
861
863
 
862
864
  for (var i = 0, l = set.length; i < l; i ++) {
863
- var pattern = set[i]
864
- var hit = this.matchOne(f, pattern, partial)
865
+ var pattern = set[i], file = f
866
+ if (options.matchBase && pattern.length === 1) {
867
+ file = [filename]
868
+ }
869
+ var hit = this.matchOne(file, pattern, partial)
865
870
  if (hit) {
866
871
  if (options.flipNegate) return true
867
872
  return !this.negate
@@ -882,20 +887,12 @@ function match (f, partial) {
882
887
  Minimatch.prototype.matchOne = function (file, pattern, partial) {
883
888
  var options = this.options
884
889
 
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
- }
890
+ this.debug("matchOne",
891
+ { "this": this
892
+ , file: file
893
+ , pattern: pattern })
895
894
 
896
- if (options.debug) {
897
- console.error("matchOne", file.length, pattern.length)
898
- }
895
+ this.debug("matchOne", file.length, pattern.length)
899
896
 
900
897
  for ( var fi = 0
901
898
  , pi = 0
@@ -904,23 +901,18 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
904
901
  ; (fi < fl) && (pi < pl)
905
902
  ; fi ++, pi ++ ) {
906
903
 
907
- if (options.debug) {
908
- console.error("matchOne loop")
909
- }
904
+ this.debug("matchOne loop")
910
905
  var p = pattern[pi]
911
906
  , f = file[fi]
912
907
 
913
- if (options.debug) {
914
- console.error(pattern, p, f)
915
- }
908
+ this.debug(pattern, p, f)
916
909
 
917
910
  // should be impossible.
918
911
  // some invalid regexp stuff in the set.
919
912
  if (p === false) return false
920
913
 
921
914
  if (p === GLOBSTAR) {
922
- if (options.debug)
923
- console.error('GLOBSTAR', [pattern, p, f])
915
+ this.debug('GLOBSTAR', [pattern, p, f])
924
916
 
925
917
  // "**"
926
918
  // a/**/b/**/c would match the following:
@@ -947,8 +939,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
947
939
  var fr = fi
948
940
  , pr = pi + 1
949
941
  if (pr === pl) {
950
- if (options.debug)
951
- console.error('** at the end')
942
+ this.debug('** at the end')
952
943
  // a ** at the end will just swallow the rest.
953
944
  // We have found a match.
954
945
  // however, it will not swallow /.x, unless
@@ -966,15 +957,12 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
966
957
  WHILE: while (fr < fl) {
967
958
  var swallowee = file[fr]
968
959
 
969
- if (options.debug) {
970
- console.error('\nglobstar while',
971
- file, fr, pattern, pr, swallowee)
972
- }
960
+ this.debug('\nglobstar while',
961
+ file, fr, pattern, pr, swallowee)
973
962
 
974
963
  // XXX remove this slice. Just pass the start index.
975
964
  if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
976
- if (options.debug)
977
- console.error('globstar found match!', fr, fl, swallowee)
965
+ this.debug('globstar found match!', fr, fl, swallowee)
978
966
  // found a match.
979
967
  return true
980
968
  } else {
@@ -982,23 +970,21 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
982
970
  // can only swallow ".foo" when explicitly asked.
983
971
  if (swallowee === "." || swallowee === ".." ||
984
972
  (!options.dot && swallowee.charAt(0) === ".")) {
985
- if (options.debug)
986
- console.error("dot detected!", file, fr, pattern, pr)
973
+ this.debug("dot detected!", file, fr, pattern, pr)
987
974
  break WHILE
988
975
  }
989
976
 
990
977
  // ** swallows a segment, and continue.
991
- if (options.debug)
992
- console.error('globstar swallow a segment, and continue')
978
+ this.debug('globstar swallow a segment, and continue')
993
979
  fr ++
994
980
  }
995
981
  }
996
982
  // no match was found.
997
983
  // However, in partial mode, we can't say this is necessarily over.
998
- // If there's more *pattern* left, then
984
+ // If there's more *pattern* left, then
999
985
  if (partial) {
1000
986
  // ran out of file
1001
- // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
987
+ this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
1002
988
  if (fr === fl) return true
1003
989
  }
1004
990
  return false
@@ -1014,14 +1000,10 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
1014
1000
  } else {
1015
1001
  hit = f === p
1016
1002
  }
1017
- if (options.debug) {
1018
- console.error("string match", p, f, hit)
1019
- }
1003
+ this.debug("string match", p, f, hit)
1020
1004
  } else {
1021
1005
  hit = f.match(p)
1022
- if (options.debug) {
1023
- console.error("pattern match", p, f, hit)
1024
- }
1006
+ this.debug("pattern match", p, f, hit)
1025
1007
  }
1026
1008
 
1027
1009
  if (!hit) return false
package/package.json CHANGED
@@ -2,14 +2,14 @@
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.11",
5
+ "version": "0.3.0",
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": "*"
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()
package/test/defaults.js CHANGED
@@ -237,7 +237,7 @@ tap.test("basic tests", function (t) {
237
237
 
238
238
  var pattern = c[0]
239
239
  , expect = c[1].sort(alpha)
240
- , options = c[2] || {}
240
+ , options = c[2]
241
241
  , f = c[3] || files
242
242
  , tapOpts = c[4] || {}
243
243
 
@@ -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