glob_match/
lib.rs

1use std::{ops::Range, path::is_separator};
2
3#[derive(Clone, Copy, Debug, Default)]
4struct State {
5  // These store character indices into the glob and path strings.
6  path_index: usize,
7  glob_index: usize,
8
9  // The current index into the captures list.
10  capture_index: usize,
11
12  // When we hit a * or **, we store the state for backtracking.
13  wildcard: Wildcard,
14  globstar: Wildcard,
15}
16
17#[derive(Clone, Copy, Debug, Default)]
18struct Wildcard {
19  // Using u32 rather than usize for these results in 10% faster performance.
20  glob_index: u32,
21  path_index: u32,
22  capture_index: u32,
23}
24
25type Capture = Range<usize>;
26
27pub fn glob_match(glob: &str, path: &str) -> bool {
28  glob_match_internal(glob, path, None)
29}
30
31pub fn glob_match_with_captures<'a>(glob: &str, path: &'a str) -> Option<Vec<Capture>> {
32  let mut captures = Vec::new();
33  if glob_match_internal(glob, path, Some(&mut captures)) {
34    return Some(captures);
35  }
36  None
37}
38
39fn glob_match_internal<'a>(
40  glob: &str,
41  path: &'a str,
42  mut captures: Option<&mut Vec<Capture>>,
43) -> bool {
44  // This algorithm is based on https://research.swtch.com/glob
45  let glob = glob.as_bytes();
46  let path = path.as_bytes();
47
48  let mut state = State::default();
49
50  // Store the state when we see an opening '{' brace in a stack.
51  // Up to 10 nested braces are supported.
52  let mut brace_stack = BraceStack::default();
53
54  // First, check if the pattern is negated with a leading '!' character.
55  // Multiple negations can occur.
56  let mut negated = false;
57  while state.glob_index < glob.len() && glob[state.glob_index] == b'!' {
58    negated = !negated;
59    state.glob_index += 1;
60  }
61
62  while state.glob_index < glob.len() || state.path_index < path.len() {
63    if state.glob_index < glob.len() {
64      match glob[state.glob_index] {
65        b'*' => {
66          let is_globstar = state.glob_index + 1 < glob.len() && glob[state.glob_index + 1] == b'*';
67          if is_globstar {
68            // Coalesce multiple ** segments into one.
69            state.glob_index = skip_globstars(glob, state.glob_index + 2) - 2;
70          }
71
72          // If we are on a different glob index than before, start a new capture.
73          // Otherwise, extend the active one.
74          if captures.is_some()
75            && (captures.as_ref().unwrap().is_empty()
76              || state.glob_index != state.wildcard.glob_index as usize)
77          {
78            state.wildcard.capture_index = state.capture_index as u32;
79            state.begin_capture(&mut captures, state.path_index..state.path_index);
80          } else {
81            state.extend_capture(&mut captures);
82          }
83
84          state.wildcard.glob_index = state.glob_index as u32;
85          state.wildcard.path_index = state.path_index as u32 + 1;
86
87          // ** allows path separators, whereas * does not.
88          // However, ** must be a full path component, i.e. a/**/b not a**b.
89          if is_globstar {
90            state.glob_index += 2;
91
92            if glob.len() == state.glob_index {
93              // A trailing ** segment without a following separator.
94              state.globstar = state.wildcard;
95            } else if (state.glob_index < 3 || glob[state.glob_index - 3] == b'/')
96              && glob[state.glob_index] == b'/'
97            {
98              // Matched a full /**/ segment. If the last character in the path was a separator,
99              // skip the separator in the glob so we search for the next character.
100              // In effect, this makes the whole segment optional so that a/**/b matches a/b.
101              if state.path_index == 0
102                || (state.path_index < path.len()
103                  && is_separator(path[state.path_index - 1] as char))
104              {
105                state.end_capture(&mut captures);
106                state.glob_index += 1;
107              }
108
109              // The allows_sep flag allows separator characters in ** matches.
110              // one is a '/', which prevents a/**/b from matching a/bb.
111              state.globstar = state.wildcard;
112            }
113          } else {
114            state.glob_index += 1;
115          }
116
117          // If we are in a * segment and hit a separator,
118          // either jump back to a previous ** or end the wildcard.
119          if state.globstar.path_index != state.wildcard.path_index
120            && state.path_index < path.len()
121            && is_separator(path[state.path_index] as char)
122          {
123            // Special case: don't jump back for a / at the end of the glob.
124            if state.globstar.path_index > 0 && state.path_index + 1 < path.len() {
125              state.glob_index = state.globstar.glob_index as usize;
126              state.capture_index = state.globstar.capture_index as usize;
127              state.wildcard.glob_index = state.globstar.glob_index;
128              state.wildcard.capture_index = state.globstar.capture_index;
129            } else {
130              state.wildcard.path_index = 0;
131            }
132          }
133
134          // If the next char is a special brace separator,
135          // skip to the end of the braces so we don't try to match it.
136          if brace_stack.length > 0
137            && state.glob_index < glob.len()
138            && matches!(glob[state.glob_index], b',' | b'}')
139          {
140            if state.skip_braces(glob, &mut captures, false) == BraceState::Invalid {
141              // invalid pattern!
142              return false;
143            }
144          }
145
146          continue;
147        }
148        b'?' if state.path_index < path.len() => {
149          if !is_separator(path[state.path_index] as char) {
150            state.add_char_capture(&mut captures);
151            state.glob_index += 1;
152            state.path_index += 1;
153            continue;
154          }
155        }
156        b'[' if state.path_index < path.len() => {
157          state.glob_index += 1;
158          let c = path[state.path_index];
159
160          // Check if the character class is negated.
161          let mut negated = false;
162          if state.glob_index < glob.len() && matches!(glob[state.glob_index], b'^' | b'!') {
163            negated = true;
164            state.glob_index += 1;
165          }
166
167          // Try each range.
168          let mut first = true;
169          let mut is_match = false;
170          while state.glob_index < glob.len() && (first || glob[state.glob_index] != b']') {
171            let mut low = glob[state.glob_index];
172            if !unescape(&mut low, glob, &mut state.glob_index) {
173              // Invalid pattern!
174              return false;
175            }
176            state.glob_index += 1;
177
178            // If there is a - and the following character is not ], read the range end character.
179            let high = if state.glob_index + 1 < glob.len()
180              && glob[state.glob_index] == b'-'
181              && glob[state.glob_index + 1] != b']'
182            {
183              state.glob_index += 1;
184              let mut high = glob[state.glob_index];
185              if !unescape(&mut high, glob, &mut state.glob_index) {
186                // Invalid pattern!
187                return false;
188              }
189              state.glob_index += 1;
190              high
191            } else {
192              low
193            };
194
195            if low <= c && c <= high {
196              is_match = true;
197            }
198            first = false;
199          }
200          if state.glob_index >= glob.len() {
201            // invalid pattern!
202            return false;
203          }
204          state.glob_index += 1;
205          if is_match != negated {
206            state.add_char_capture(&mut captures);
207            state.path_index += 1;
208            continue;
209          }
210        }
211        b'{' if state.path_index < path.len() => {
212          if brace_stack.length as usize >= brace_stack.stack.len() {
213            // Invalid pattern! Too many nested braces.
214            return false;
215          }
216
217          state.end_capture(&mut captures);
218          state.begin_capture(&mut captures, state.path_index..state.path_index);
219
220          // Push old state to the stack, and reset current state.
221          state = brace_stack.push(&state);
222          continue;
223        }
224        b'}' if brace_stack.length > 0 => {
225          // If we hit the end of the braces, we matched the last option.
226          brace_stack.longest_brace_match =
227            brace_stack.longest_brace_match.max(state.path_index as u32);
228          state.glob_index += 1;
229          state = brace_stack.pop(&state, &mut captures);
230          continue;
231        }
232        b',' if brace_stack.length > 0 => {
233          // If we hit a comma, we matched one of the options!
234          // But we still need to check the others in case there is a longer match.
235          brace_stack.longest_brace_match =
236            brace_stack.longest_brace_match.max(state.path_index as u32);
237          state.path_index = brace_stack.last().path_index;
238          state.glob_index += 1;
239          state.wildcard = Wildcard::default();
240          state.globstar = Wildcard::default();
241          continue;
242        }
243        mut c if state.path_index < path.len() => {
244          // Match escaped characters as literals.
245          if !unescape(&mut c, glob, &mut state.glob_index) {
246            // Invalid pattern!
247            return false;
248          }
249
250          let is_match = if c == b'/' {
251            is_separator(path[state.path_index] as char)
252          } else {
253            path[state.path_index] == c
254          };
255
256          if is_match {
257            state.end_capture(&mut captures);
258
259            if brace_stack.length > 0 && state.glob_index > 0 && glob[state.glob_index - 1] == b'}'
260            {
261              brace_stack.longest_brace_match = state.path_index as u32;
262              state = brace_stack.pop(&state, &mut captures);
263            }
264            state.glob_index += 1;
265            state.path_index += 1;
266
267            // If this is not a separator, lock in the previous globstar.
268            if c != b'/' {
269              state.globstar.path_index = 0;
270            }
271            continue;
272          }
273        }
274        _ => {}
275      }
276    }
277
278    // If we didn't match, restore state to the previous star pattern.
279    if state.wildcard.path_index > 0 && state.wildcard.path_index as usize <= path.len() {
280      state.backtrack();
281      continue;
282    }
283
284    if brace_stack.length > 0 {
285      // If in braces, find next option and reset path to index where we saw the '{'
286      match state.skip_braces(glob, &mut captures, true) {
287        BraceState::Invalid => return false,
288        BraceState::Comma => {
289          state.path_index = brace_stack.last().path_index;
290          continue;
291        }
292        BraceState::EndBrace => {}
293      }
294
295      // Hit the end. Pop the stack.
296      // If we matched a previous option, use that.
297      if brace_stack.longest_brace_match > 0 {
298        state = brace_stack.pop(&state, &mut captures);
299        continue;
300      } else {
301        // Didn't match. Restore state, and check if we need to jump back to a star pattern.
302        state = *brace_stack.last();
303        brace_stack.length -= 1;
304        if let Some(captures) = &mut captures {
305          captures.truncate(state.capture_index);
306        }
307        if state.wildcard.path_index > 0 && state.wildcard.path_index as usize <= path.len() {
308          state.backtrack();
309          continue;
310        }
311      }
312    }
313
314    return negated;
315  }
316
317  if brace_stack.length > 0 && state.glob_index > 0 && glob[state.glob_index - 1] == b'}' {
318    brace_stack.longest_brace_match = state.path_index as u32;
319    brace_stack.pop(&state, &mut captures);
320  }
321
322  !negated
323}
324
325#[inline(always)]
326fn unescape(c: &mut u8, glob: &[u8], glob_index: &mut usize) -> bool {
327  if *c == b'\\' {
328    *glob_index += 1;
329    if *glob_index >= glob.len() {
330      // Invalid pattern!
331      return false;
332    }
333    *c = match glob[*glob_index] {
334      b'a' => b'\x61',
335      b'b' => b'\x08',
336      b'n' => b'\n',
337      b'r' => b'\r',
338      b't' => b'\t',
339      c => c,
340    }
341  }
342  true
343}
344
345#[derive(PartialEq)]
346enum BraceState {
347  Invalid,
348  Comma,
349  EndBrace,
350}
351
352impl State {
353  #[inline(always)]
354  fn backtrack(&mut self) {
355    self.glob_index = self.wildcard.glob_index as usize;
356    self.path_index = self.wildcard.path_index as usize;
357    self.capture_index = self.wildcard.capture_index as usize;
358  }
359
360  #[inline(always)]
361  fn begin_capture(&self, captures: &mut Option<&mut Vec<Capture>>, capture: Capture) {
362    if let Some(captures) = captures {
363      if self.capture_index < captures.len() {
364        captures[self.capture_index] = capture;
365      } else {
366        captures.push(capture);
367      }
368    }
369  }
370
371  #[inline(always)]
372  fn extend_capture(&self, captures: &mut Option<&mut Vec<Capture>>) {
373    if let Some(captures) = captures {
374      if self.capture_index < captures.len() {
375        captures[self.capture_index].end = self.path_index;
376      }
377    }
378  }
379
380  #[inline(always)]
381  fn end_capture(&mut self, captures: &mut Option<&mut Vec<Capture>>) {
382    if let Some(captures) = captures {
383      if self.capture_index < captures.len() {
384        self.capture_index += 1;
385      }
386    }
387  }
388
389  #[inline(always)]
390  fn add_char_capture(&mut self, captures: &mut Option<&mut Vec<Capture>>) {
391    self.end_capture(captures);
392    self.begin_capture(captures, self.path_index..self.path_index + 1);
393    self.capture_index += 1;
394  }
395
396  fn skip_braces(
397    &mut self,
398    glob: &[u8],
399    captures: &mut Option<&mut Vec<Capture>>,
400    stop_on_comma: bool,
401  ) -> BraceState {
402    let mut braces = 1;
403    let mut in_brackets = false;
404    let mut capture_index = self.capture_index + 1;
405    while self.glob_index < glob.len() && braces > 0 {
406      match glob[self.glob_index] {
407        // Skip nested braces.
408        b'{' if !in_brackets => braces += 1,
409        b'}' if !in_brackets => braces -= 1,
410        b',' if stop_on_comma && braces == 1 && !in_brackets => {
411          self.glob_index += 1;
412          return BraceState::Comma;
413        }
414        c @ (b'*' | b'?' | b'[') if !in_brackets => {
415          if c == b'[' {
416            in_brackets = true;
417          }
418          if let Some(captures) = captures {
419            if capture_index < captures.len() {
420              captures[capture_index] = self.path_index..self.path_index;
421            } else {
422              captures.push(self.path_index..self.path_index);
423            }
424            capture_index += 1;
425          }
426          if c == b'*' {
427            if self.glob_index + 1 < glob.len() && glob[self.glob_index + 1] == b'*' {
428              self.glob_index = skip_globstars(glob, self.glob_index + 2) - 2;
429              self.glob_index += 1;
430            }
431          }
432        }
433        b']' => in_brackets = false,
434        b'\\' => {
435          self.glob_index += 1;
436        }
437        _ => {}
438      }
439      self.glob_index += 1;
440    }
441
442    if braces != 0 {
443      return BraceState::Invalid;
444    }
445
446    BraceState::EndBrace
447  }
448}
449
450#[inline(always)]
451fn skip_globstars(glob: &[u8], mut glob_index: usize) -> usize {
452  // Coalesce multiple ** segments into one.
453  while glob_index + 3 <= glob.len()
454    && unsafe { glob.get_unchecked(glob_index..glob_index + 3) } == b"/**"
455  {
456    glob_index += 3;
457  }
458  glob_index
459}
460
461struct BraceStack {
462  stack: [State; 10],
463  length: u32,
464  longest_brace_match: u32,
465}
466
467impl Default for BraceStack {
468  #[inline]
469  fn default() -> Self {
470    // Manual implementation is faster than the automatically derived one.
471    BraceStack {
472      stack: [State::default(); 10],
473      length: 0,
474      longest_brace_match: 0,
475    }
476  }
477}
478
479impl BraceStack {
480  #[inline(always)]
481  fn push(&mut self, state: &State) -> State {
482    // Push old state to the stack, and reset current state.
483    self.stack[self.length as usize] = *state;
484    self.length += 1;
485    State {
486      path_index: state.path_index,
487      glob_index: state.glob_index + 1,
488      capture_index: state.capture_index + 1,
489      ..State::default()
490    }
491  }
492
493  #[inline(always)]
494  fn pop(&mut self, state: &State, captures: &mut Option<&mut Vec<Capture>>) -> State {
495    self.length -= 1;
496    let mut state = State {
497      path_index: self.longest_brace_match as usize,
498      glob_index: state.glob_index,
499      // But restore star state if needed later.
500      wildcard: self.stack[self.length as usize].wildcard,
501      globstar: self.stack[self.length as usize].globstar,
502      capture_index: self.stack[self.length as usize].capture_index,
503    };
504    if self.length == 0 {
505      self.longest_brace_match = 0;
506    }
507    state.extend_capture(captures);
508    if let Some(captures) = captures {
509      state.capture_index = captures.len();
510    }
511
512    state
513  }
514
515  #[inline(always)]
516  fn last(&self) -> &State {
517    &self.stack[self.length as usize - 1]
518  }
519}
520
521#[cfg(test)]
522mod tests {
523  use super::*;
524
525  #[test]
526  fn basic() {
527    assert!(glob_match("abc", "abc"));
528    assert!(glob_match("*", "abc"));
529    assert!(glob_match("*", ""));
530    assert!(glob_match("**", ""));
531    assert!(glob_match("*c", "abc"));
532    assert!(!glob_match("*b", "abc"));
533    assert!(glob_match("a*", "abc"));
534    assert!(!glob_match("b*", "abc"));
535    assert!(glob_match("a*", "a"));
536    assert!(glob_match("*a", "a"));
537    assert!(glob_match("a*b*c*d*e*", "axbxcxdxe"));
538    assert!(glob_match("a*b*c*d*e*", "axbxcxdxexxx"));
539    assert!(glob_match("a*b?c*x", "abxbbxdbxebxczzx"));
540    assert!(!glob_match("a*b?c*x", "abxbbxdbxebxczzy"));
541
542    assert!(glob_match("a/*/test", "a/foo/test"));
543    assert!(!glob_match("a/*/test", "a/foo/bar/test"));
544    assert!(glob_match("a/**/test", "a/foo/test"));
545    assert!(glob_match("a/**/test", "a/foo/bar/test"));
546    assert!(glob_match("a/**/b/c", "a/foo/bar/b/c"));
547    assert!(glob_match("a\\*b", "a*b"));
548    assert!(!glob_match("a\\*b", "axb"));
549
550    assert!(glob_match("[abc]", "a"));
551    assert!(glob_match("[abc]", "b"));
552    assert!(glob_match("[abc]", "c"));
553    assert!(!glob_match("[abc]", "d"));
554    assert!(glob_match("x[abc]x", "xax"));
555    assert!(glob_match("x[abc]x", "xbx"));
556    assert!(glob_match("x[abc]x", "xcx"));
557    assert!(!glob_match("x[abc]x", "xdx"));
558    assert!(!glob_match("x[abc]x", "xay"));
559    assert!(glob_match("[?]", "?"));
560    assert!(!glob_match("[?]", "a"));
561    assert!(glob_match("[*]", "*"));
562    assert!(!glob_match("[*]", "a"));
563
564    assert!(glob_match("[a-cx]", "a"));
565    assert!(glob_match("[a-cx]", "b"));
566    assert!(glob_match("[a-cx]", "c"));
567    assert!(!glob_match("[a-cx]", "d"));
568    assert!(glob_match("[a-cx]", "x"));
569
570    assert!(!glob_match("[^abc]", "a"));
571    assert!(!glob_match("[^abc]", "b"));
572    assert!(!glob_match("[^abc]", "c"));
573    assert!(glob_match("[^abc]", "d"));
574    assert!(!glob_match("[!abc]", "a"));
575    assert!(!glob_match("[!abc]", "b"));
576    assert!(!glob_match("[!abc]", "c"));
577    assert!(glob_match("[!abc]", "d"));
578    assert!(glob_match("[\\!]", "!"));
579
580    assert!(glob_match("a*b*[cy]*d*e*", "axbxcxdxexxx"));
581    assert!(glob_match("a*b*[cy]*d*e*", "axbxyxdxexxx"));
582    assert!(glob_match("a*b*[cy]*d*e*", "axbxxxyxdxexxx"));
583
584    assert!(glob_match("test.{jpg,png}", "test.jpg"));
585    assert!(glob_match("test.{jpg,png}", "test.png"));
586    assert!(glob_match("test.{j*g,p*g}", "test.jpg"));
587    assert!(glob_match("test.{j*g,p*g}", "test.jpxxxg"));
588    assert!(glob_match("test.{j*g,p*g}", "test.jxg"));
589    assert!(!glob_match("test.{j*g,p*g}", "test.jnt"));
590    assert!(glob_match("test.{j*g,j*c}", "test.jnc"));
591    assert!(glob_match("test.{jpg,p*g}", "test.png"));
592    assert!(glob_match("test.{jpg,p*g}", "test.pxg"));
593    assert!(!glob_match("test.{jpg,p*g}", "test.pnt"));
594    assert!(glob_match("test.{jpeg,png}", "test.jpeg"));
595    assert!(!glob_match("test.{jpeg,png}", "test.jpg"));
596    assert!(glob_match("test.{jpeg,png}", "test.png"));
597    assert!(glob_match("test.{jp\\,g,png}", "test.jp,g"));
598    assert!(!glob_match("test.{jp\\,g,png}", "test.jxg"));
599    assert!(glob_match("test/{foo,bar}/baz", "test/foo/baz"));
600    assert!(glob_match("test/{foo,bar}/baz", "test/bar/baz"));
601    assert!(!glob_match("test/{foo,bar}/baz", "test/baz/baz"));
602    assert!(glob_match("test/{foo*,bar*}/baz", "test/foooooo/baz"));
603    assert!(glob_match("test/{foo*,bar*}/baz", "test/barrrrr/baz"));
604    assert!(glob_match("test/{*foo,*bar}/baz", "test/xxxxfoo/baz"));
605    assert!(glob_match("test/{*foo,*bar}/baz", "test/xxxxbar/baz"));
606    assert!(glob_match("test/{foo/**,bar}/baz", "test/bar/baz"));
607    assert!(!glob_match("test/{foo/**,bar}/baz", "test/bar/test/baz"));
608
609    assert!(!glob_match("*.txt", "some/big/path/to/the/needle.txt"));
610    assert!(glob_match(
611      "some/**/needle.{js,tsx,mdx,ts,jsx,txt}",
612      "some/a/bigger/path/to/the/crazy/needle.txt"
613    ));
614    assert!(glob_match(
615      "some/**/{a,b,c}/**/needle.txt",
616      "some/foo/a/bigger/path/to/the/crazy/needle.txt"
617    ));
618    assert!(!glob_match(
619      "some/**/{a,b,c}/**/needle.txt",
620      "some/foo/d/bigger/path/to/the/crazy/needle.txt"
621    ));
622    assert!(glob_match("a/{a{a,b},b}", "a/aa"));
623    assert!(glob_match("a/{a{a,b},b}", "a/ab"));
624    assert!(!glob_match("a/{a{a,b},b}", "a/ac"));
625    assert!(glob_match("a/{a{a,b},b}", "a/b"));
626    assert!(!glob_match("a/{a{a,b},b}", "a/c"));
627    assert!(glob_match("a/{b,c[}]*}", "a/b"));
628    assert!(glob_match("a/{b,c[}]*}", "a/c}xx"));
629  }
630
631  // The below tests are based on Bash and micromatch.
632  // https://github.com/micromatch/picomatch/blob/master/test/bash.js
633  // Converted using the following find and replace regex:
634  // find: assert\(([!])?isMatch\('(.*?)', ['"](.*?)['"]\)\);
635  // replace: assert!($1glob_match("$3", "$2"));
636
637  #[test]
638  fn bash() {
639    assert!(!glob_match("a*", "*"));
640    assert!(!glob_match("a*", "**"));
641    assert!(!glob_match("a*", "\\*"));
642    assert!(!glob_match("a*", "a/*"));
643    assert!(!glob_match("a*", "b"));
644    assert!(!glob_match("a*", "bc"));
645    assert!(!glob_match("a*", "bcd"));
646    assert!(!glob_match("a*", "bdir/"));
647    assert!(!glob_match("a*", "Beware"));
648    assert!(glob_match("a*", "a"));
649    assert!(glob_match("a*", "ab"));
650    assert!(glob_match("a*", "abc"));
651
652    assert!(!glob_match("\\a*", "*"));
653    assert!(!glob_match("\\a*", "**"));
654    assert!(!glob_match("\\a*", "\\*"));
655
656    assert!(glob_match("\\a*", "a"));
657    assert!(!glob_match("\\a*", "a/*"));
658    assert!(glob_match("\\a*", "abc"));
659    assert!(glob_match("\\a*", "abd"));
660    assert!(glob_match("\\a*", "abe"));
661    assert!(!glob_match("\\a*", "b"));
662    assert!(!glob_match("\\a*", "bb"));
663    assert!(!glob_match("\\a*", "bcd"));
664    assert!(!glob_match("\\a*", "bdir/"));
665    assert!(!glob_match("\\a*", "Beware"));
666    assert!(!glob_match("\\a*", "c"));
667    assert!(!glob_match("\\a*", "ca"));
668    assert!(!glob_match("\\a*", "cb"));
669    assert!(!glob_match("\\a*", "d"));
670    assert!(!glob_match("\\a*", "dd"));
671    assert!(!glob_match("\\a*", "de"));
672  }
673
674  #[test]
675  fn bash_directories() {
676    assert!(!glob_match("b*/", "*"));
677    assert!(!glob_match("b*/", "**"));
678    assert!(!glob_match("b*/", "\\*"));
679    assert!(!glob_match("b*/", "a"));
680    assert!(!glob_match("b*/", "a/*"));
681    assert!(!glob_match("b*/", "abc"));
682    assert!(!glob_match("b*/", "abd"));
683    assert!(!glob_match("b*/", "abe"));
684    assert!(!glob_match("b*/", "b"));
685    assert!(!glob_match("b*/", "bb"));
686    assert!(!glob_match("b*/", "bcd"));
687    assert!(glob_match("b*/", "bdir/"));
688    assert!(!glob_match("b*/", "Beware"));
689    assert!(!glob_match("b*/", "c"));
690    assert!(!glob_match("b*/", "ca"));
691    assert!(!glob_match("b*/", "cb"));
692    assert!(!glob_match("b*/", "d"));
693    assert!(!glob_match("b*/", "dd"));
694    assert!(!glob_match("b*/", "de"));
695  }
696
697  #[test]
698  fn bash_escaping() {
699    assert!(!glob_match("\\^", "*"));
700    assert!(!glob_match("\\^", "**"));
701    assert!(!glob_match("\\^", "\\*"));
702    assert!(!glob_match("\\^", "a"));
703    assert!(!glob_match("\\^", "a/*"));
704    assert!(!glob_match("\\^", "abc"));
705    assert!(!glob_match("\\^", "abd"));
706    assert!(!glob_match("\\^", "abe"));
707    assert!(!glob_match("\\^", "b"));
708    assert!(!glob_match("\\^", "bb"));
709    assert!(!glob_match("\\^", "bcd"));
710    assert!(!glob_match("\\^", "bdir/"));
711    assert!(!glob_match("\\^", "Beware"));
712    assert!(!glob_match("\\^", "c"));
713    assert!(!glob_match("\\^", "ca"));
714    assert!(!glob_match("\\^", "cb"));
715    assert!(!glob_match("\\^", "d"));
716    assert!(!glob_match("\\^", "dd"));
717    assert!(!glob_match("\\^", "de"));
718
719    assert!(glob_match("\\*", "*"));
720    // assert!(glob_match("\\*", "\\*"));
721    assert!(!glob_match("\\*", "**"));
722    assert!(!glob_match("\\*", "a"));
723    assert!(!glob_match("\\*", "a/*"));
724    assert!(!glob_match("\\*", "abc"));
725    assert!(!glob_match("\\*", "abd"));
726    assert!(!glob_match("\\*", "abe"));
727    assert!(!glob_match("\\*", "b"));
728    assert!(!glob_match("\\*", "bb"));
729    assert!(!glob_match("\\*", "bcd"));
730    assert!(!glob_match("\\*", "bdir/"));
731    assert!(!glob_match("\\*", "Beware"));
732    assert!(!glob_match("\\*", "c"));
733    assert!(!glob_match("\\*", "ca"));
734    assert!(!glob_match("\\*", "cb"));
735    assert!(!glob_match("\\*", "d"));
736    assert!(!glob_match("\\*", "dd"));
737    assert!(!glob_match("\\*", "de"));
738
739    assert!(!glob_match("a\\*", "*"));
740    assert!(!glob_match("a\\*", "**"));
741    assert!(!glob_match("a\\*", "\\*"));
742    assert!(!glob_match("a\\*", "a"));
743    assert!(!glob_match("a\\*", "a/*"));
744    assert!(!glob_match("a\\*", "abc"));
745    assert!(!glob_match("a\\*", "abd"));
746    assert!(!glob_match("a\\*", "abe"));
747    assert!(!glob_match("a\\*", "b"));
748    assert!(!glob_match("a\\*", "bb"));
749    assert!(!glob_match("a\\*", "bcd"));
750    assert!(!glob_match("a\\*", "bdir/"));
751    assert!(!glob_match("a\\*", "Beware"));
752    assert!(!glob_match("a\\*", "c"));
753    assert!(!glob_match("a\\*", "ca"));
754    assert!(!glob_match("a\\*", "cb"));
755    assert!(!glob_match("a\\*", "d"));
756    assert!(!glob_match("a\\*", "dd"));
757    assert!(!glob_match("a\\*", "de"));
758
759    assert!(glob_match("*q*", "aqa"));
760    assert!(glob_match("*q*", "aaqaa"));
761    assert!(!glob_match("*q*", "*"));
762    assert!(!glob_match("*q*", "**"));
763    assert!(!glob_match("*q*", "\\*"));
764    assert!(!glob_match("*q*", "a"));
765    assert!(!glob_match("*q*", "a/*"));
766    assert!(!glob_match("*q*", "abc"));
767    assert!(!glob_match("*q*", "abd"));
768    assert!(!glob_match("*q*", "abe"));
769    assert!(!glob_match("*q*", "b"));
770    assert!(!glob_match("*q*", "bb"));
771    assert!(!glob_match("*q*", "bcd"));
772    assert!(!glob_match("*q*", "bdir/"));
773    assert!(!glob_match("*q*", "Beware"));
774    assert!(!glob_match("*q*", "c"));
775    assert!(!glob_match("*q*", "ca"));
776    assert!(!glob_match("*q*", "cb"));
777    assert!(!glob_match("*q*", "d"));
778    assert!(!glob_match("*q*", "dd"));
779    assert!(!glob_match("*q*", "de"));
780
781    assert!(glob_match("\\**", "*"));
782    assert!(glob_match("\\**", "**"));
783    assert!(!glob_match("\\**", "\\*"));
784    assert!(!glob_match("\\**", "a"));
785    assert!(!glob_match("\\**", "a/*"));
786    assert!(!glob_match("\\**", "abc"));
787    assert!(!glob_match("\\**", "abd"));
788    assert!(!glob_match("\\**", "abe"));
789    assert!(!glob_match("\\**", "b"));
790    assert!(!glob_match("\\**", "bb"));
791    assert!(!glob_match("\\**", "bcd"));
792    assert!(!glob_match("\\**", "bdir/"));
793    assert!(!glob_match("\\**", "Beware"));
794    assert!(!glob_match("\\**", "c"));
795    assert!(!glob_match("\\**", "ca"));
796    assert!(!glob_match("\\**", "cb"));
797    assert!(!glob_match("\\**", "d"));
798    assert!(!glob_match("\\**", "dd"));
799    assert!(!glob_match("\\**", "de"));
800  }
801
802  #[test]
803  fn bash_classes() {
804    assert!(!glob_match("a*[^c]", "*"));
805    assert!(!glob_match("a*[^c]", "**"));
806    assert!(!glob_match("a*[^c]", "\\*"));
807    assert!(!glob_match("a*[^c]", "a"));
808    assert!(!glob_match("a*[^c]", "a/*"));
809    assert!(!glob_match("a*[^c]", "abc"));
810    assert!(glob_match("a*[^c]", "abd"));
811    assert!(glob_match("a*[^c]", "abe"));
812    assert!(!glob_match("a*[^c]", "b"));
813    assert!(!glob_match("a*[^c]", "bb"));
814    assert!(!glob_match("a*[^c]", "bcd"));
815    assert!(!glob_match("a*[^c]", "bdir/"));
816    assert!(!glob_match("a*[^c]", "Beware"));
817    assert!(!glob_match("a*[^c]", "c"));
818    assert!(!glob_match("a*[^c]", "ca"));
819    assert!(!glob_match("a*[^c]", "cb"));
820    assert!(!glob_match("a*[^c]", "d"));
821    assert!(!glob_match("a*[^c]", "dd"));
822    assert!(!glob_match("a*[^c]", "de"));
823    assert!(!glob_match("a*[^c]", "baz"));
824    assert!(!glob_match("a*[^c]", "bzz"));
825    assert!(!glob_match("a*[^c]", "BZZ"));
826    assert!(!glob_match("a*[^c]", "beware"));
827    assert!(!glob_match("a*[^c]", "BewAre"));
828
829    assert!(glob_match("a[X-]b", "a-b"));
830    assert!(glob_match("a[X-]b", "aXb"));
831
832    assert!(!glob_match("[a-y]*[^c]", "*"));
833    assert!(glob_match("[a-y]*[^c]", "a*"));
834    assert!(!glob_match("[a-y]*[^c]", "**"));
835    assert!(!glob_match("[a-y]*[^c]", "\\*"));
836    assert!(!glob_match("[a-y]*[^c]", "a"));
837    assert!(glob_match("[a-y]*[^c]", "a123b"));
838    assert!(!glob_match("[a-y]*[^c]", "a123c"));
839    assert!(glob_match("[a-y]*[^c]", "ab"));
840    assert!(!glob_match("[a-y]*[^c]", "a/*"));
841    assert!(!glob_match("[a-y]*[^c]", "abc"));
842    assert!(glob_match("[a-y]*[^c]", "abd"));
843    assert!(glob_match("[a-y]*[^c]", "abe"));
844    assert!(!glob_match("[a-y]*[^c]", "b"));
845    assert!(glob_match("[a-y]*[^c]", "bd"));
846    assert!(glob_match("[a-y]*[^c]", "bb"));
847    assert!(glob_match("[a-y]*[^c]", "bcd"));
848    assert!(glob_match("[a-y]*[^c]", "bdir/"));
849    assert!(!glob_match("[a-y]*[^c]", "Beware"));
850    assert!(!glob_match("[a-y]*[^c]", "c"));
851    assert!(glob_match("[a-y]*[^c]", "ca"));
852    assert!(glob_match("[a-y]*[^c]", "cb"));
853    assert!(!glob_match("[a-y]*[^c]", "d"));
854    assert!(glob_match("[a-y]*[^c]", "dd"));
855    assert!(glob_match("[a-y]*[^c]", "dd"));
856    assert!(glob_match("[a-y]*[^c]", "dd"));
857    assert!(glob_match("[a-y]*[^c]", "de"));
858    assert!(glob_match("[a-y]*[^c]", "baz"));
859    assert!(glob_match("[a-y]*[^c]", "bzz"));
860    assert!(glob_match("[a-y]*[^c]", "bzz"));
861    // assert(!isMatch('bzz', '[a-y]*[^c]', { regex: true }));
862    assert!(!glob_match("[a-y]*[^c]", "BZZ"));
863    assert!(glob_match("[a-y]*[^c]", "beware"));
864    assert!(!glob_match("[a-y]*[^c]", "BewAre"));
865
866    assert!(glob_match("a\\*b/*", "a*b/ooo"));
867    assert!(glob_match("a\\*?/*", "a*b/ooo"));
868
869    assert!(!glob_match("a[b]c", "*"));
870    assert!(!glob_match("a[b]c", "**"));
871    assert!(!glob_match("a[b]c", "\\*"));
872    assert!(!glob_match("a[b]c", "a"));
873    assert!(!glob_match("a[b]c", "a/*"));
874    assert!(glob_match("a[b]c", "abc"));
875    assert!(!glob_match("a[b]c", "abd"));
876    assert!(!glob_match("a[b]c", "abe"));
877    assert!(!glob_match("a[b]c", "b"));
878    assert!(!glob_match("a[b]c", "bb"));
879    assert!(!glob_match("a[b]c", "bcd"));
880    assert!(!glob_match("a[b]c", "bdir/"));
881    assert!(!glob_match("a[b]c", "Beware"));
882    assert!(!glob_match("a[b]c", "c"));
883    assert!(!glob_match("a[b]c", "ca"));
884    assert!(!glob_match("a[b]c", "cb"));
885    assert!(!glob_match("a[b]c", "d"));
886    assert!(!glob_match("a[b]c", "dd"));
887    assert!(!glob_match("a[b]c", "de"));
888    assert!(!glob_match("a[b]c", "baz"));
889    assert!(!glob_match("a[b]c", "bzz"));
890    assert!(!glob_match("a[b]c", "BZZ"));
891    assert!(!glob_match("a[b]c", "beware"));
892    assert!(!glob_match("a[b]c", "BewAre"));
893
894    assert!(!glob_match("a[\"b\"]c", "*"));
895    assert!(!glob_match("a[\"b\"]c", "**"));
896    assert!(!glob_match("a[\"b\"]c", "\\*"));
897    assert!(!glob_match("a[\"b\"]c", "a"));
898    assert!(!glob_match("a[\"b\"]c", "a/*"));
899    assert!(glob_match("a[\"b\"]c", "abc"));
900    assert!(!glob_match("a[\"b\"]c", "abd"));
901    assert!(!glob_match("a[\"b\"]c", "abe"));
902    assert!(!glob_match("a[\"b\"]c", "b"));
903    assert!(!glob_match("a[\"b\"]c", "bb"));
904    assert!(!glob_match("a[\"b\"]c", "bcd"));
905    assert!(!glob_match("a[\"b\"]c", "bdir/"));
906    assert!(!glob_match("a[\"b\"]c", "Beware"));
907    assert!(!glob_match("a[\"b\"]c", "c"));
908    assert!(!glob_match("a[\"b\"]c", "ca"));
909    assert!(!glob_match("a[\"b\"]c", "cb"));
910    assert!(!glob_match("a[\"b\"]c", "d"));
911    assert!(!glob_match("a[\"b\"]c", "dd"));
912    assert!(!glob_match("a[\"b\"]c", "de"));
913    assert!(!glob_match("a[\"b\"]c", "baz"));
914    assert!(!glob_match("a[\"b\"]c", "bzz"));
915    assert!(!glob_match("a[\"b\"]c", "BZZ"));
916    assert!(!glob_match("a[\"b\"]c", "beware"));
917    assert!(!glob_match("a[\"b\"]c", "BewAre"));
918
919    assert!(!glob_match("a[\\\\b]c", "*"));
920    assert!(!glob_match("a[\\\\b]c", "**"));
921    assert!(!glob_match("a[\\\\b]c", "\\*"));
922    assert!(!glob_match("a[\\\\b]c", "a"));
923    assert!(!glob_match("a[\\\\b]c", "a/*"));
924    assert!(glob_match("a[\\\\b]c", "abc"));
925    assert!(!glob_match("a[\\\\b]c", "abd"));
926    assert!(!glob_match("a[\\\\b]c", "abe"));
927    assert!(!glob_match("a[\\\\b]c", "b"));
928    assert!(!glob_match("a[\\\\b]c", "bb"));
929    assert!(!glob_match("a[\\\\b]c", "bcd"));
930    assert!(!glob_match("a[\\\\b]c", "bdir/"));
931    assert!(!glob_match("a[\\\\b]c", "Beware"));
932    assert!(!glob_match("a[\\\\b]c", "c"));
933    assert!(!glob_match("a[\\\\b]c", "ca"));
934    assert!(!glob_match("a[\\\\b]c", "cb"));
935    assert!(!glob_match("a[\\\\b]c", "d"));
936    assert!(!glob_match("a[\\\\b]c", "dd"));
937    assert!(!glob_match("a[\\\\b]c", "de"));
938    assert!(!glob_match("a[\\\\b]c", "baz"));
939    assert!(!glob_match("a[\\\\b]c", "bzz"));
940    assert!(!glob_match("a[\\\\b]c", "BZZ"));
941    assert!(!glob_match("a[\\\\b]c", "beware"));
942    assert!(!glob_match("a[\\\\b]c", "BewAre"));
943
944    assert!(!glob_match("a[\\b]c", "*"));
945    assert!(!glob_match("a[\\b]c", "**"));
946    assert!(!glob_match("a[\\b]c", "\\*"));
947    assert!(!glob_match("a[\\b]c", "a"));
948    assert!(!glob_match("a[\\b]c", "a/*"));
949    assert!(!glob_match("a[\\b]c", "abc"));
950    assert!(!glob_match("a[\\b]c", "abd"));
951    assert!(!glob_match("a[\\b]c", "abe"));
952    assert!(!glob_match("a[\\b]c", "b"));
953    assert!(!glob_match("a[\\b]c", "bb"));
954    assert!(!glob_match("a[\\b]c", "bcd"));
955    assert!(!glob_match("a[\\b]c", "bdir/"));
956    assert!(!glob_match("a[\\b]c", "Beware"));
957    assert!(!glob_match("a[\\b]c", "c"));
958    assert!(!glob_match("a[\\b]c", "ca"));
959    assert!(!glob_match("a[\\b]c", "cb"));
960    assert!(!glob_match("a[\\b]c", "d"));
961    assert!(!glob_match("a[\\b]c", "dd"));
962    assert!(!glob_match("a[\\b]c", "de"));
963    assert!(!glob_match("a[\\b]c", "baz"));
964    assert!(!glob_match("a[\\b]c", "bzz"));
965    assert!(!glob_match("a[\\b]c", "BZZ"));
966    assert!(!glob_match("a[\\b]c", "beware"));
967    assert!(!glob_match("a[\\b]c", "BewAre"));
968
969    assert!(!glob_match("a[b-d]c", "*"));
970    assert!(!glob_match("a[b-d]c", "**"));
971    assert!(!glob_match("a[b-d]c", "\\*"));
972    assert!(!glob_match("a[b-d]c", "a"));
973    assert!(!glob_match("a[b-d]c", "a/*"));
974    assert!(glob_match("a[b-d]c", "abc"));
975    assert!(!glob_match("a[b-d]c", "abd"));
976    assert!(!glob_match("a[b-d]c", "abe"));
977    assert!(!glob_match("a[b-d]c", "b"));
978    assert!(!glob_match("a[b-d]c", "bb"));
979    assert!(!glob_match("a[b-d]c", "bcd"));
980    assert!(!glob_match("a[b-d]c", "bdir/"));
981    assert!(!glob_match("a[b-d]c", "Beware"));
982    assert!(!glob_match("a[b-d]c", "c"));
983    assert!(!glob_match("a[b-d]c", "ca"));
984    assert!(!glob_match("a[b-d]c", "cb"));
985    assert!(!glob_match("a[b-d]c", "d"));
986    assert!(!glob_match("a[b-d]c", "dd"));
987    assert!(!glob_match("a[b-d]c", "de"));
988    assert!(!glob_match("a[b-d]c", "baz"));
989    assert!(!glob_match("a[b-d]c", "bzz"));
990    assert!(!glob_match("a[b-d]c", "BZZ"));
991    assert!(!glob_match("a[b-d]c", "beware"));
992    assert!(!glob_match("a[b-d]c", "BewAre"));
993
994    assert!(!glob_match("a?c", "*"));
995    assert!(!glob_match("a?c", "**"));
996    assert!(!glob_match("a?c", "\\*"));
997    assert!(!glob_match("a?c", "a"));
998    assert!(!glob_match("a?c", "a/*"));
999    assert!(glob_match("a?c", "abc"));
1000    assert!(!glob_match("a?c", "abd"));
1001    assert!(!glob_match("a?c", "abe"));
1002    assert!(!glob_match("a?c", "b"));
1003    assert!(!glob_match("a?c", "bb"));
1004    assert!(!glob_match("a?c", "bcd"));
1005    assert!(!glob_match("a?c", "bdir/"));
1006    assert!(!glob_match("a?c", "Beware"));
1007    assert!(!glob_match("a?c", "c"));
1008    assert!(!glob_match("a?c", "ca"));
1009    assert!(!glob_match("a?c", "cb"));
1010    assert!(!glob_match("a?c", "d"));
1011    assert!(!glob_match("a?c", "dd"));
1012    assert!(!glob_match("a?c", "de"));
1013    assert!(!glob_match("a?c", "baz"));
1014    assert!(!glob_match("a?c", "bzz"));
1015    assert!(!glob_match("a?c", "BZZ"));
1016    assert!(!glob_match("a?c", "beware"));
1017    assert!(!glob_match("a?c", "BewAre"));
1018
1019    assert!(glob_match("*/man*/bash.*", "man/man1/bash.1"));
1020
1021    assert!(glob_match("[^a-c]*", "*"));
1022    assert!(glob_match("[^a-c]*", "**"));
1023    assert!(!glob_match("[^a-c]*", "a"));
1024    assert!(!glob_match("[^a-c]*", "a/*"));
1025    assert!(!glob_match("[^a-c]*", "abc"));
1026    assert!(!glob_match("[^a-c]*", "abd"));
1027    assert!(!glob_match("[^a-c]*", "abe"));
1028    assert!(!glob_match("[^a-c]*", "b"));
1029    assert!(!glob_match("[^a-c]*", "bb"));
1030    assert!(!glob_match("[^a-c]*", "bcd"));
1031    assert!(!glob_match("[^a-c]*", "bdir/"));
1032    assert!(glob_match("[^a-c]*", "Beware"));
1033    assert!(glob_match("[^a-c]*", "Beware"));
1034    assert!(!glob_match("[^a-c]*", "c"));
1035    assert!(!glob_match("[^a-c]*", "ca"));
1036    assert!(!glob_match("[^a-c]*", "cb"));
1037    assert!(glob_match("[^a-c]*", "d"));
1038    assert!(glob_match("[^a-c]*", "dd"));
1039    assert!(glob_match("[^a-c]*", "de"));
1040    assert!(!glob_match("[^a-c]*", "baz"));
1041    assert!(!glob_match("[^a-c]*", "bzz"));
1042    assert!(glob_match("[^a-c]*", "BZZ"));
1043    assert!(!glob_match("[^a-c]*", "beware"));
1044    assert!(glob_match("[^a-c]*", "BewAre"));
1045  }
1046
1047  #[test]
1048  fn bash_wildmatch() {
1049    assert!(!glob_match("a[]-]b", "aab"));
1050    assert!(!glob_match("[ten]", "ten"));
1051    assert!(glob_match("]", "]"));
1052    assert!(glob_match("a[]-]b", "a-b"));
1053    assert!(glob_match("a[]-]b", "a]b"));
1054    assert!(glob_match("a[]]b", "a]b"));
1055    assert!(glob_match("a[\\]a\\-]b", "aab"));
1056    assert!(glob_match("t[a-g]n", "ten"));
1057    assert!(glob_match("t[^a-g]n", "ton"));
1058  }
1059
1060  #[test]
1061  fn bash_slashmatch() {
1062    // assert!(!glob_match("f[^eiu][^eiu][^eiu][^eiu][^eiu]r", "foo/bar"));
1063    assert!(glob_match("foo[/]bar", "foo/bar"));
1064    assert!(glob_match("f[^eiu][^eiu][^eiu][^eiu][^eiu]r", "foo-bar"));
1065  }
1066
1067  #[test]
1068  fn bash_extra_stars() {
1069    assert!(!glob_match("a**c", "bbc"));
1070    assert!(glob_match("a**c", "abc"));
1071    assert!(!glob_match("a**c", "bbd"));
1072
1073    assert!(!glob_match("a***c", "bbc"));
1074    assert!(glob_match("a***c", "abc"));
1075    assert!(!glob_match("a***c", "bbd"));
1076
1077    assert!(!glob_match("a*****?c", "bbc"));
1078    assert!(glob_match("a*****?c", "abc"));
1079    assert!(!glob_match("a*****?c", "bbc"));
1080
1081    assert!(glob_match("?*****??", "bbc"));
1082    assert!(glob_match("?*****??", "abc"));
1083
1084    assert!(glob_match("*****??", "bbc"));
1085    assert!(glob_match("*****??", "abc"));
1086
1087    assert!(glob_match("?*****?c", "bbc"));
1088    assert!(glob_match("?*****?c", "abc"));
1089
1090    assert!(glob_match("?***?****c", "bbc"));
1091    assert!(glob_match("?***?****c", "abc"));
1092    assert!(!glob_match("?***?****c", "bbd"));
1093
1094    assert!(glob_match("?***?****?", "bbc"));
1095    assert!(glob_match("?***?****?", "abc"));
1096
1097    assert!(glob_match("?***?****", "bbc"));
1098    assert!(glob_match("?***?****", "abc"));
1099
1100    assert!(glob_match("*******c", "bbc"));
1101    assert!(glob_match("*******c", "abc"));
1102
1103    assert!(glob_match("*******?", "bbc"));
1104    assert!(glob_match("*******?", "abc"));
1105
1106    assert!(glob_match("a*cd**?**??k", "abcdecdhjk"));
1107    assert!(glob_match("a**?**cd**?**??k", "abcdecdhjk"));
1108    assert!(glob_match("a**?**cd**?**??k***", "abcdecdhjk"));
1109    assert!(glob_match("a**?**cd**?**??***k", "abcdecdhjk"));
1110    assert!(glob_match("a**?**cd**?**??***k**", "abcdecdhjk"));
1111    assert!(glob_match("a****c**?**??*****", "abcdecdhjk"));
1112  }
1113
1114  #[test]
1115  fn stars() {
1116    assert!(!glob_match("*.js", "a/b/c/z.js"));
1117    assert!(!glob_match("*.js", "a/b/z.js"));
1118    assert!(!glob_match("*.js", "a/z.js"));
1119    assert!(glob_match("*.js", "z.js"));
1120
1121    // assert!(!glob_match("*/*", "a/.ab"));
1122    // assert!(!glob_match("*", ".ab"));
1123
1124    assert!(glob_match("z*.js", "z.js"));
1125    assert!(glob_match("*/*", "a/z"));
1126    assert!(glob_match("*/z*.js", "a/z.js"));
1127    assert!(glob_match("a/z*.js", "a/z.js"));
1128
1129    assert!(glob_match("*", "ab"));
1130    assert!(glob_match("*", "abc"));
1131
1132    assert!(!glob_match("f*", "bar"));
1133    assert!(!glob_match("*r", "foo"));
1134    assert!(!glob_match("b*", "foo"));
1135    assert!(!glob_match("*", "foo/bar"));
1136    assert!(glob_match("*c", "abc"));
1137    assert!(glob_match("a*", "abc"));
1138    assert!(glob_match("a*c", "abc"));
1139    assert!(glob_match("*r", "bar"));
1140    assert!(glob_match("b*", "bar"));
1141    assert!(glob_match("f*", "foo"));
1142
1143    assert!(glob_match("*abc*", "one abc two"));
1144    assert!(glob_match("a*b", "a         b"));
1145
1146    assert!(!glob_match("*a*", "foo"));
1147    assert!(glob_match("*a*", "bar"));
1148    assert!(glob_match("*abc*", "oneabctwo"));
1149    assert!(!glob_match("*-bc-*", "a-b.c-d"));
1150    assert!(glob_match("*-*.*-*", "a-b.c-d"));
1151    assert!(glob_match("*-b*c-*", "a-b.c-d"));
1152    assert!(glob_match("*-b.c-*", "a-b.c-d"));
1153    assert!(glob_match("*.*", "a-b.c-d"));
1154    assert!(glob_match("*.*-*", "a-b.c-d"));
1155    assert!(glob_match("*.*-d", "a-b.c-d"));
1156    assert!(glob_match("*.c-*", "a-b.c-d"));
1157    assert!(glob_match("*b.*d", "a-b.c-d"));
1158    assert!(glob_match("a*.c*", "a-b.c-d"));
1159    assert!(glob_match("a-*.*-d", "a-b.c-d"));
1160    assert!(glob_match("*.*", "a.b"));
1161    assert!(glob_match("*.b", "a.b"));
1162    assert!(glob_match("a.*", "a.b"));
1163    assert!(glob_match("a.b", "a.b"));
1164
1165    assert!(!glob_match("**-bc-**", "a-b.c-d"));
1166    assert!(glob_match("**-**.**-**", "a-b.c-d"));
1167    assert!(glob_match("**-b**c-**", "a-b.c-d"));
1168    assert!(glob_match("**-b.c-**", "a-b.c-d"));
1169    assert!(glob_match("**.**", "a-b.c-d"));
1170    assert!(glob_match("**.**-**", "a-b.c-d"));
1171    assert!(glob_match("**.**-d", "a-b.c-d"));
1172    assert!(glob_match("**.c-**", "a-b.c-d"));
1173    assert!(glob_match("**b.**d", "a-b.c-d"));
1174    assert!(glob_match("a**.c**", "a-b.c-d"));
1175    assert!(glob_match("a-**.**-d", "a-b.c-d"));
1176    assert!(glob_match("**.**", "a.b"));
1177    assert!(glob_match("**.b", "a.b"));
1178    assert!(glob_match("a.**", "a.b"));
1179    assert!(glob_match("a.b", "a.b"));
1180
1181    assert!(glob_match("*/*", "/ab"));
1182    assert!(glob_match(".", "."));
1183    assert!(!glob_match("a/", "a/.b"));
1184    assert!(glob_match("/*", "/ab"));
1185    assert!(glob_match("/??", "/ab"));
1186    assert!(glob_match("/?b", "/ab"));
1187    assert!(glob_match("/*", "/cd"));
1188    assert!(glob_match("a", "a"));
1189    assert!(glob_match("a/.*", "a/.b"));
1190    assert!(glob_match("?/?", "a/b"));
1191    assert!(glob_match("a/**/j/**/z/*.md", "a/b/c/d/e/j/n/p/o/z/c.md"));
1192    assert!(glob_match("a/**/z/*.md", "a/b/c/d/e/z/c.md"));
1193    assert!(glob_match("a/b/c/*.md", "a/b/c/xyz.md"));
1194    assert!(glob_match("a/b/c/*.md", "a/b/c/xyz.md"));
1195    assert!(glob_match("a/*/z/.a", "a/b/z/.a"));
1196    assert!(!glob_match("bz", "a/b/z/.a"));
1197    assert!(glob_match("a/**/c/*.md", "a/bb.bb/aa/b.b/aa/c/xyz.md"));
1198    assert!(glob_match("a/**/c/*.md", "a/bb.bb/aa/bb/aa/c/xyz.md"));
1199    assert!(glob_match("a/*/c/*.md", "a/bb.bb/c/xyz.md"));
1200    assert!(glob_match("a/*/c/*.md", "a/bb/c/xyz.md"));
1201    assert!(glob_match("a/*/c/*.md", "a/bbbb/c/xyz.md"));
1202    assert!(glob_match("*", "aaa"));
1203    assert!(glob_match("*", "ab"));
1204    assert!(glob_match("ab", "ab"));
1205
1206    assert!(!glob_match("*/*/*", "aaa"));
1207    assert!(!glob_match("*/*/*", "aaa/bb/aa/rr"));
1208    assert!(!glob_match("aaa*", "aaa/bba/ccc"));
1209    // assert!(!glob_match("aaa**", "aaa/bba/ccc"));
1210    assert!(!glob_match("aaa/*", "aaa/bba/ccc"));
1211    assert!(!glob_match("aaa/*ccc", "aaa/bba/ccc"));
1212    assert!(!glob_match("aaa/*z", "aaa/bba/ccc"));
1213    assert!(!glob_match("*/*/*", "aaa/bbb"));
1214    assert!(!glob_match("*/*jk*/*i", "ab/zzz/ejkl/hi"));
1215    assert!(glob_match("*/*/*", "aaa/bba/ccc"));
1216    assert!(glob_match("aaa/**", "aaa/bba/ccc"));
1217    assert!(glob_match("aaa/*", "aaa/bbb"));
1218    assert!(glob_match("*/*z*/*/*i", "ab/zzz/ejkl/hi"));
1219    assert!(glob_match("*j*i", "abzzzejklhi"));
1220
1221    assert!(glob_match("*", "a"));
1222    assert!(glob_match("*", "b"));
1223    assert!(!glob_match("*", "a/a"));
1224    assert!(!glob_match("*", "a/a/a"));
1225    assert!(!glob_match("*", "a/a/b"));
1226    assert!(!glob_match("*", "a/a/a/a"));
1227    assert!(!glob_match("*", "a/a/a/a/a"));
1228
1229    assert!(!glob_match("*/*", "a"));
1230    assert!(glob_match("*/*", "a/a"));
1231    assert!(!glob_match("*/*", "a/a/a"));
1232
1233    assert!(!glob_match("*/*/*", "a"));
1234    assert!(!glob_match("*/*/*", "a/a"));
1235    assert!(glob_match("*/*/*", "a/a/a"));
1236    assert!(!glob_match("*/*/*", "a/a/a/a"));
1237
1238    assert!(!glob_match("*/*/*/*", "a"));
1239    assert!(!glob_match("*/*/*/*", "a/a"));
1240    assert!(!glob_match("*/*/*/*", "a/a/a"));
1241    assert!(glob_match("*/*/*/*", "a/a/a/a"));
1242    assert!(!glob_match("*/*/*/*", "a/a/a/a/a"));
1243
1244    assert!(!glob_match("*/*/*/*/*", "a"));
1245    assert!(!glob_match("*/*/*/*/*", "a/a"));
1246    assert!(!glob_match("*/*/*/*/*", "a/a/a"));
1247    assert!(!glob_match("*/*/*/*/*", "a/a/b"));
1248    assert!(!glob_match("*/*/*/*/*", "a/a/a/a"));
1249    assert!(glob_match("*/*/*/*/*", "a/a/a/a/a"));
1250    assert!(!glob_match("*/*/*/*/*", "a/a/a/a/a/a"));
1251
1252    assert!(!glob_match("a/*", "a"));
1253    assert!(glob_match("a/*", "a/a"));
1254    assert!(!glob_match("a/*", "a/a/a"));
1255    assert!(!glob_match("a/*", "a/a/a/a"));
1256    assert!(!glob_match("a/*", "a/a/a/a/a"));
1257
1258    assert!(!glob_match("a/*/*", "a"));
1259    assert!(!glob_match("a/*/*", "a/a"));
1260    assert!(glob_match("a/*/*", "a/a/a"));
1261    assert!(!glob_match("a/*/*", "b/a/a"));
1262    assert!(!glob_match("a/*/*", "a/a/a/a"));
1263    assert!(!glob_match("a/*/*", "a/a/a/a/a"));
1264
1265    assert!(!glob_match("a/*/*/*", "a"));
1266    assert!(!glob_match("a/*/*/*", "a/a"));
1267    assert!(!glob_match("a/*/*/*", "a/a/a"));
1268    assert!(glob_match("a/*/*/*", "a/a/a/a"));
1269    assert!(!glob_match("a/*/*/*", "a/a/a/a/a"));
1270
1271    assert!(!glob_match("a/*/*/*/*", "a"));
1272    assert!(!glob_match("a/*/*/*/*", "a/a"));
1273    assert!(!glob_match("a/*/*/*/*", "a/a/a"));
1274    assert!(!glob_match("a/*/*/*/*", "a/a/b"));
1275    assert!(!glob_match("a/*/*/*/*", "a/a/a/a"));
1276    assert!(glob_match("a/*/*/*/*", "a/a/a/a/a"));
1277
1278    assert!(!glob_match("a/*/a", "a"));
1279    assert!(!glob_match("a/*/a", "a/a"));
1280    assert!(glob_match("a/*/a", "a/a/a"));
1281    assert!(!glob_match("a/*/a", "a/a/b"));
1282    assert!(!glob_match("a/*/a", "a/a/a/a"));
1283    assert!(!glob_match("a/*/a", "a/a/a/a/a"));
1284
1285    assert!(!glob_match("a/*/b", "a"));
1286    assert!(!glob_match("a/*/b", "a/a"));
1287    assert!(!glob_match("a/*/b", "a/a/a"));
1288    assert!(glob_match("a/*/b", "a/a/b"));
1289    assert!(!glob_match("a/*/b", "a/a/a/a"));
1290    assert!(!glob_match("a/*/b", "a/a/a/a/a"));
1291
1292    assert!(!glob_match("*/**/a", "a"));
1293    assert!(!glob_match("*/**/a", "a/a/b"));
1294    assert!(glob_match("*/**/a", "a/a"));
1295    assert!(glob_match("*/**/a", "a/a/a"));
1296    assert!(glob_match("*/**/a", "a/a/a/a"));
1297    assert!(glob_match("*/**/a", "a/a/a/a/a"));
1298
1299    assert!(!glob_match("*/", "a"));
1300    assert!(!glob_match("*/*", "a"));
1301    assert!(!glob_match("a/*", "a"));
1302    // assert!(!glob_match("*/*", "a/"));
1303    // assert!(!glob_match("a/*", "a/"));
1304    assert!(!glob_match("*", "a/a"));
1305    assert!(!glob_match("*/", "a/a"));
1306    assert!(!glob_match("*/", "a/x/y"));
1307    assert!(!glob_match("*/*", "a/x/y"));
1308    assert!(!glob_match("a/*", "a/x/y"));
1309    // assert!(glob_match("*", "a/"));
1310    assert!(glob_match("*", "a"));
1311    assert!(glob_match("*/", "a/"));
1312    assert!(glob_match("*{,/}", "a/"));
1313    assert!(glob_match("*/*", "a/a"));
1314    assert!(glob_match("a/*", "a/a"));
1315
1316    assert!(!glob_match("a/**/*.txt", "a.txt"));
1317    assert!(glob_match("a/**/*.txt", "a/x/y.txt"));
1318    assert!(!glob_match("a/**/*.txt", "a/x/y/z"));
1319
1320    assert!(!glob_match("a/*.txt", "a.txt"));
1321    assert!(glob_match("a/*.txt", "a/b.txt"));
1322    assert!(!glob_match("a/*.txt", "a/x/y.txt"));
1323    assert!(!glob_match("a/*.txt", "a/x/y/z"));
1324
1325    assert!(glob_match("a*.txt", "a.txt"));
1326    assert!(!glob_match("a*.txt", "a/b.txt"));
1327    assert!(!glob_match("a*.txt", "a/x/y.txt"));
1328    assert!(!glob_match("a*.txt", "a/x/y/z"));
1329
1330    assert!(glob_match("*.txt", "a.txt"));
1331    assert!(!glob_match("*.txt", "a/b.txt"));
1332    assert!(!glob_match("*.txt", "a/x/y.txt"));
1333    assert!(!glob_match("*.txt", "a/x/y/z"));
1334
1335    assert!(!glob_match("a*", "a/b"));
1336    assert!(!glob_match("a/**/b", "a/a/bb"));
1337    assert!(!glob_match("a/**/b", "a/bb"));
1338
1339    assert!(!glob_match("*/**", "foo"));
1340    assert!(!glob_match("**/", "foo/bar"));
1341    assert!(!glob_match("**/*/", "foo/bar"));
1342    assert!(!glob_match("*/*/", "foo/bar"));
1343
1344    assert!(glob_match("**/..", "/home/foo/.."));
1345    assert!(glob_match("**/a", "a"));
1346    assert!(glob_match("**", "a/a"));
1347    assert!(glob_match("a/**", "a/a"));
1348    assert!(glob_match("a/**", "a/"));
1349    // assert!(glob_match("a/**", "a"));
1350    assert!(!glob_match("**/", "a/a"));
1351    // assert!(glob_match("**/a/**", "a"));
1352    // assert!(glob_match("a/**", "a"));
1353    assert!(!glob_match("**/", "a/a"));
1354    assert!(glob_match("*/**/a", "a/a"));
1355    // assert!(glob_match("a/**", "a"));
1356    assert!(glob_match("*/**", "foo/"));
1357    assert!(glob_match("**/*", "foo/bar"));
1358    assert!(glob_match("*/*", "foo/bar"));
1359    assert!(glob_match("*/**", "foo/bar"));
1360    assert!(glob_match("**/", "foo/bar/"));
1361    // assert!(glob_match("**/*", "foo/bar/"));
1362    assert!(glob_match("**/*/", "foo/bar/"));
1363    assert!(glob_match("*/**", "foo/bar/"));
1364    assert!(glob_match("*/*/", "foo/bar/"));
1365
1366    assert!(!glob_match("*/foo", "bar/baz/foo"));
1367    assert!(!glob_match("**/bar/*", "deep/foo/bar"));
1368    assert!(!glob_match("*/bar/**", "deep/foo/bar/baz/x"));
1369    assert!(!glob_match("/*", "ef"));
1370    assert!(!glob_match("foo?bar", "foo/bar"));
1371    assert!(!glob_match("**/bar*", "foo/bar/baz"));
1372    // assert!(!glob_match("**/bar**", "foo/bar/baz"));
1373    assert!(!glob_match("foo**bar", "foo/baz/bar"));
1374    assert!(!glob_match("foo*bar", "foo/baz/bar"));
1375    // assert!(glob_match("foo/**", "foo"));
1376    assert!(glob_match("/*", "/ab"));
1377    assert!(glob_match("/*", "/cd"));
1378    assert!(glob_match("/*", "/ef"));
1379    assert!(glob_match("a/**/j/**/z/*.md", "a/b/j/c/z/x.md"));
1380    assert!(glob_match("a/**/j/**/z/*.md", "a/j/z/x.md"));
1381
1382    assert!(glob_match("**/foo", "bar/baz/foo"));
1383    assert!(glob_match("**/bar/*", "deep/foo/bar/baz"));
1384    assert!(glob_match("**/bar/**", "deep/foo/bar/baz/"));
1385    assert!(glob_match("**/bar/*/*", "deep/foo/bar/baz/x"));
1386    assert!(glob_match("foo/**/**/bar", "foo/b/a/z/bar"));
1387    assert!(glob_match("foo/**/bar", "foo/b/a/z/bar"));
1388    assert!(glob_match("foo/**/**/bar", "foo/bar"));
1389    assert!(glob_match("foo/**/bar", "foo/bar"));
1390    assert!(glob_match("*/bar/**", "foo/bar/baz/x"));
1391    assert!(glob_match("foo/**/**/bar", "foo/baz/bar"));
1392    assert!(glob_match("foo/**/bar", "foo/baz/bar"));
1393    assert!(glob_match("**/foo", "XXX/foo"));
1394  }
1395
1396  #[test]
1397  fn globstars() {
1398    assert!(glob_match("**/*.js", "a/b/c/d.js"));
1399    assert!(glob_match("**/*.js", "a/b/c.js"));
1400    assert!(glob_match("**/*.js", "a/b.js"));
1401    assert!(glob_match("a/b/**/*.js", "a/b/c/d/e/f.js"));
1402    assert!(glob_match("a/b/**/*.js", "a/b/c/d/e.js"));
1403    assert!(glob_match("a/b/c/**/*.js", "a/b/c/d.js"));
1404    assert!(glob_match("a/b/**/*.js", "a/b/c/d.js"));
1405    assert!(glob_match("a/b/**/*.js", "a/b/d.js"));
1406    assert!(!glob_match("a/b/**/*.js", "a/d.js"));
1407    assert!(!glob_match("a/b/**/*.js", "d.js"));
1408
1409    assert!(!glob_match("**c", "a/b/c"));
1410    assert!(!glob_match("a/**c", "a/b/c"));
1411    assert!(!glob_match("a/**z", "a/b/c"));
1412    assert!(!glob_match("a/**b**/c", "a/b/c/b/c"));
1413    assert!(!glob_match("a/b/c**/*.js", "a/b/c/d/e.js"));
1414    assert!(glob_match("a/**/b/**/c", "a/b/c/b/c"));
1415    assert!(glob_match("a/**b**/c", "a/aba/c"));
1416    assert!(glob_match("a/**b**/c", "a/b/c"));
1417    assert!(glob_match("a/b/c**/*.js", "a/b/c/d.js"));
1418
1419    assert!(!glob_match("a/**/*", "a"));
1420    assert!(!glob_match("a/**/**/*", "a"));
1421    assert!(!glob_match("a/**/**/**/*", "a"));
1422    assert!(!glob_match("**/a", "a/"));
1423    assert!(!glob_match("a/**/*", "a/"));
1424    assert!(!glob_match("a/**/**/*", "a/"));
1425    assert!(!glob_match("a/**/**/**/*", "a/"));
1426    assert!(!glob_match("**/a", "a/b"));
1427    assert!(!glob_match("a/**/j/**/z/*.md", "a/b/c/j/e/z/c.txt"));
1428    assert!(!glob_match("a/**/b", "a/bb"));
1429    assert!(!glob_match("**/a", "a/c"));
1430    assert!(!glob_match("**/a", "a/b"));
1431    assert!(!glob_match("**/a", "a/x/y"));
1432    assert!(!glob_match("**/a", "a/b/c/d"));
1433    assert!(glob_match("**", "a"));
1434    assert!(glob_match("**/a", "a"));
1435    // assert!(glob_match("a/**", "a"));
1436    assert!(glob_match("**", "a/"));
1437    assert!(glob_match("**/a/**", "a/"));
1438    assert!(glob_match("a/**", "a/"));
1439    assert!(glob_match("a/**/**", "a/"));
1440    assert!(glob_match("**/a", "a/a"));
1441    assert!(glob_match("**", "a/b"));
1442    assert!(glob_match("*/*", "a/b"));
1443    assert!(glob_match("a/**", "a/b"));
1444    assert!(glob_match("a/**/*", "a/b"));
1445    assert!(glob_match("a/**/**/*", "a/b"));
1446    assert!(glob_match("a/**/**/**/*", "a/b"));
1447    assert!(glob_match("a/**/b", "a/b"));
1448    assert!(glob_match("**", "a/b/c"));
1449    assert!(glob_match("**/*", "a/b/c"));
1450    assert!(glob_match("**/**", "a/b/c"));
1451    assert!(glob_match("*/**", "a/b/c"));
1452    assert!(glob_match("a/**", "a/b/c"));
1453    assert!(glob_match("a/**/*", "a/b/c"));
1454    assert!(glob_match("a/**/**/*", "a/b/c"));
1455    assert!(glob_match("a/**/**/**/*", "a/b/c"));
1456    assert!(glob_match("**", "a/b/c/d"));
1457    assert!(glob_match("a/**", "a/b/c/d"));
1458    assert!(glob_match("a/**/*", "a/b/c/d"));
1459    assert!(glob_match("a/**/**/*", "a/b/c/d"));
1460    assert!(glob_match("a/**/**/**/*", "a/b/c/d"));
1461    assert!(glob_match("a/b/**/c/**/*.*", "a/b/c/d.e"));
1462    assert!(glob_match("a/**/f/*.md", "a/b/c/d/e/f/g.md"));
1463    assert!(glob_match("a/**/f/**/k/*.md", "a/b/c/d/e/f/g/h/i/j/k/l.md"));
1464    assert!(glob_match("a/b/c/*.md", "a/b/c/def.md"));
1465    assert!(glob_match("a/*/c/*.md", "a/bb.bb/c/ddd.md"));
1466    assert!(glob_match("a/**/f/*.md", "a/bb.bb/cc/d.d/ee/f/ggg.md"));
1467    assert!(glob_match("a/**/f/*.md", "a/bb.bb/cc/dd/ee/f/ggg.md"));
1468    assert!(glob_match("a/*/c/*.md", "a/bb/c/ddd.md"));
1469    assert!(glob_match("a/*/c/*.md", "a/bbbb/c/ddd.md"));
1470
1471    assert!(glob_match(
1472      "foo/bar/**/one/**/*.*",
1473      "foo/bar/baz/one/image.png"
1474    ));
1475    assert!(glob_match(
1476      "foo/bar/**/one/**/*.*",
1477      "foo/bar/baz/one/two/image.png"
1478    ));
1479    assert!(glob_match(
1480      "foo/bar/**/one/**/*.*",
1481      "foo/bar/baz/one/two/three/image.png"
1482    ));
1483    assert!(!glob_match("a/b/**/f", "a/b/c/d/"));
1484    // assert!(glob_match("a/**", "a"));
1485    assert!(glob_match("**", "a"));
1486    // assert!(glob_match("a{,/**}", "a"));
1487    assert!(glob_match("**", "a/"));
1488    assert!(glob_match("a/**", "a/"));
1489    assert!(glob_match("**", "a/b/c/d"));
1490    assert!(glob_match("**", "a/b/c/d/"));
1491    assert!(glob_match("**/**", "a/b/c/d/"));
1492    assert!(glob_match("**/b/**", "a/b/c/d/"));
1493    assert!(glob_match("a/b/**", "a/b/c/d/"));
1494    assert!(glob_match("a/b/**/", "a/b/c/d/"));
1495    assert!(glob_match("a/b/**/c/**/", "a/b/c/d/"));
1496    assert!(glob_match("a/b/**/c/**/d/", "a/b/c/d/"));
1497    assert!(glob_match("a/b/**/**/*.*", "a/b/c/d/e.f"));
1498    assert!(glob_match("a/b/**/*.*", "a/b/c/d/e.f"));
1499    assert!(glob_match("a/b/**/c/**/d/*.*", "a/b/c/d/e.f"));
1500    assert!(glob_match("a/b/**/d/**/*.*", "a/b/c/d/e.f"));
1501    assert!(glob_match("a/b/**/d/**/*.*", "a/b/c/d/g/e.f"));
1502    assert!(glob_match("a/b/**/d/**/*.*", "a/b/c/d/g/g/e.f"));
1503    assert!(glob_match("a/b-*/**/z.js", "a/b-c/z.js"));
1504    assert!(glob_match("a/b-*/**/z.js", "a/b-c/d/e/z.js"));
1505
1506    assert!(glob_match("*/*", "a/b"));
1507    assert!(glob_match("a/b/c/*.md", "a/b/c/xyz.md"));
1508    assert!(glob_match("a/*/c/*.md", "a/bb.bb/c/xyz.md"));
1509    assert!(glob_match("a/*/c/*.md", "a/bb/c/xyz.md"));
1510    assert!(glob_match("a/*/c/*.md", "a/bbbb/c/xyz.md"));
1511
1512    assert!(glob_match("**/*", "a/b/c"));
1513    assert!(glob_match("**/**", "a/b/c"));
1514    assert!(glob_match("*/**", "a/b/c"));
1515    assert!(glob_match("a/**/j/**/z/*.md", "a/b/c/d/e/j/n/p/o/z/c.md"));
1516    assert!(glob_match("a/**/z/*.md", "a/b/c/d/e/z/c.md"));
1517    assert!(glob_match("a/**/c/*.md", "a/bb.bb/aa/b.b/aa/c/xyz.md"));
1518    assert!(glob_match("a/**/c/*.md", "a/bb.bb/aa/bb/aa/c/xyz.md"));
1519    assert!(!glob_match("a/**/j/**/z/*.md", "a/b/c/j/e/z/c.txt"));
1520    assert!(!glob_match("a/b/**/c{d,e}/**/xyz.md", "a/b/c/xyz.md"));
1521    assert!(!glob_match("a/b/**/c{d,e}/**/xyz.md", "a/b/d/xyz.md"));
1522    assert!(!glob_match("a/**/", "a/b"));
1523    // assert!(!glob_match("**/*", "a/b/.js/c.txt"));
1524    assert!(!glob_match("a/**/", "a/b/c/d"));
1525    assert!(!glob_match("a/**/", "a/bb"));
1526    assert!(!glob_match("a/**/", "a/cb"));
1527    assert!(glob_match("/**", "/a/b"));
1528    assert!(glob_match("**/*", "a.b"));
1529    assert!(glob_match("**/*", "a.js"));
1530    assert!(glob_match("**/*.js", "a.js"));
1531    // assert!(glob_match("a/**/", "a/"));
1532    assert!(glob_match("**/*.js", "a/a.js"));
1533    assert!(glob_match("**/*.js", "a/a/b.js"));
1534    assert!(glob_match("a/**/b", "a/b"));
1535    assert!(glob_match("a/**b", "a/b"));
1536    assert!(glob_match("**/*.md", "a/b.md"));
1537    assert!(glob_match("**/*", "a/b/c.js"));
1538    assert!(glob_match("**/*", "a/b/c.txt"));
1539    assert!(glob_match("a/**/", "a/b/c/d/"));
1540    assert!(glob_match("**/*", "a/b/c/d/a.js"));
1541    assert!(glob_match("a/b/**/*.js", "a/b/c/z.js"));
1542    assert!(glob_match("a/b/**/*.js", "a/b/z.js"));
1543    assert!(glob_match("**/*", "ab"));
1544    assert!(glob_match("**/*", "ab/c"));
1545    assert!(glob_match("**/*", "ab/c/d"));
1546    assert!(glob_match("**/*", "abc.js"));
1547
1548    assert!(!glob_match("**/", "a"));
1549    assert!(!glob_match("**/a/*", "a"));
1550    assert!(!glob_match("**/a/*/*", "a"));
1551    assert!(!glob_match("*/a/**", "a"));
1552    assert!(!glob_match("a/**/*", "a"));
1553    assert!(!glob_match("a/**/**/*", "a"));
1554    assert!(!glob_match("**/", "a/b"));
1555    assert!(!glob_match("**/b/*", "a/b"));
1556    assert!(!glob_match("**/b/*/*", "a/b"));
1557    assert!(!glob_match("b/**", "a/b"));
1558    assert!(!glob_match("**/", "a/b/c"));
1559    assert!(!glob_match("**/**/b", "a/b/c"));
1560    assert!(!glob_match("**/b", "a/b/c"));
1561    assert!(!glob_match("**/b/*/*", "a/b/c"));
1562    assert!(!glob_match("b/**", "a/b/c"));
1563    assert!(!glob_match("**/", "a/b/c/d"));
1564    assert!(!glob_match("**/d/*", "a/b/c/d"));
1565    assert!(!glob_match("b/**", "a/b/c/d"));
1566    assert!(glob_match("**", "a"));
1567    assert!(glob_match("**/**", "a"));
1568    assert!(glob_match("**/**/*", "a"));
1569    assert!(glob_match("**/**/a", "a"));
1570    assert!(glob_match("**/a", "a"));
1571    // assert!(glob_match("**/a/**", "a"));
1572    // assert!(glob_match("a/**", "a"));
1573    assert!(glob_match("**", "a/b"));
1574    assert!(glob_match("**/**", "a/b"));
1575    assert!(glob_match("**/**/*", "a/b"));
1576    assert!(glob_match("**/**/b", "a/b"));
1577    assert!(glob_match("**/b", "a/b"));
1578    // assert!(glob_match("**/b/**", "a/b"));
1579    // assert!(glob_match("*/b/**", "a/b"));
1580    assert!(glob_match("a/**", "a/b"));
1581    assert!(glob_match("a/**/*", "a/b"));
1582    assert!(glob_match("a/**/**/*", "a/b"));
1583    assert!(glob_match("**", "a/b/c"));
1584    assert!(glob_match("**/**", "a/b/c"));
1585    assert!(glob_match("**/**/*", "a/b/c"));
1586    assert!(glob_match("**/b/*", "a/b/c"));
1587    assert!(glob_match("**/b/**", "a/b/c"));
1588    assert!(glob_match("*/b/**", "a/b/c"));
1589    assert!(glob_match("a/**", "a/b/c"));
1590    assert!(glob_match("a/**/*", "a/b/c"));
1591    assert!(glob_match("a/**/**/*", "a/b/c"));
1592    assert!(glob_match("**", "a/b/c/d"));
1593    assert!(glob_match("**/**", "a/b/c/d"));
1594    assert!(glob_match("**/**/*", "a/b/c/d"));
1595    assert!(glob_match("**/**/d", "a/b/c/d"));
1596    assert!(glob_match("**/b/**", "a/b/c/d"));
1597    assert!(glob_match("**/b/*/*", "a/b/c/d"));
1598    assert!(glob_match("**/d", "a/b/c/d"));
1599    assert!(glob_match("*/b/**", "a/b/c/d"));
1600    assert!(glob_match("a/**", "a/b/c/d"));
1601    assert!(glob_match("a/**/*", "a/b/c/d"));
1602    assert!(glob_match("a/**/**/*", "a/b/c/d"));
1603  }
1604
1605  #[test]
1606  fn utf8() {
1607    assert!(glob_match("フ*/**/*", "フォルダ/aaa.js"));
1608    assert!(glob_match("フォ*/**/*", "フォルダ/aaa.js"));
1609    assert!(glob_match("フォル*/**/*", "フォルダ/aaa.js"));
1610    assert!(glob_match("フ*ル*/**/*", "フォルダ/aaa.js"));
1611    assert!(glob_match("フォルダ/**/*", "フォルダ/aaa.js"));
1612  }
1613
1614  #[test]
1615  fn negation() {
1616    assert!(!glob_match("!*", "abc"));
1617    assert!(!glob_match("!abc", "abc"));
1618    assert!(!glob_match("*!.md", "bar.md"));
1619    assert!(!glob_match("foo!.md", "bar.md"));
1620    assert!(!glob_match("\\!*!*.md", "foo!.md"));
1621    assert!(!glob_match("\\!*!*.md", "foo!bar.md"));
1622    assert!(glob_match("*!*.md", "!foo!.md"));
1623    assert!(glob_match("\\!*!*.md", "!foo!.md"));
1624    assert!(glob_match("!*foo", "abc"));
1625    assert!(glob_match("!foo*", "abc"));
1626    assert!(glob_match("!xyz", "abc"));
1627    assert!(glob_match("*!*.*", "ba!r.js"));
1628    assert!(glob_match("*.md", "bar.md"));
1629    assert!(glob_match("*!*.*", "foo!.md"));
1630    assert!(glob_match("*!*.md", "foo!.md"));
1631    assert!(glob_match("*!.md", "foo!.md"));
1632    assert!(glob_match("*.md", "foo!.md"));
1633    assert!(glob_match("foo!.md", "foo!.md"));
1634    assert!(glob_match("*!*.md", "foo!bar.md"));
1635    assert!(glob_match("*b*.md", "foobar.md"));
1636
1637    assert!(!glob_match("a!!b", "a"));
1638    assert!(!glob_match("a!!b", "aa"));
1639    assert!(!glob_match("a!!b", "a/b"));
1640    assert!(!glob_match("a!!b", "a!b"));
1641    assert!(glob_match("a!!b", "a!!b"));
1642    assert!(!glob_match("a!!b", "a/!!/b"));
1643
1644    assert!(!glob_match("!a/b", "a/b"));
1645    assert!(glob_match("!a/b", "a"));
1646    assert!(glob_match("!a/b", "a.b"));
1647    assert!(glob_match("!a/b", "a/a"));
1648    assert!(glob_match("!a/b", "a/c"));
1649    assert!(glob_match("!a/b", "b/a"));
1650    assert!(glob_match("!a/b", "b/b"));
1651    assert!(glob_match("!a/b", "b/c"));
1652
1653    assert!(!glob_match("!abc", "abc"));
1654    assert!(glob_match("!!abc", "abc"));
1655    assert!(!glob_match("!!!abc", "abc"));
1656    assert!(glob_match("!!!!abc", "abc"));
1657    assert!(!glob_match("!!!!!abc", "abc"));
1658    assert!(glob_match("!!!!!!abc", "abc"));
1659    assert!(!glob_match("!!!!!!!abc", "abc"));
1660    assert!(glob_match("!!!!!!!!abc", "abc"));
1661
1662    // assert!(!glob_match("!(*/*)", "a/a"));
1663    // assert!(!glob_match("!(*/*)", "a/b"));
1664    // assert!(!glob_match("!(*/*)", "a/c"));
1665    // assert!(!glob_match("!(*/*)", "b/a"));
1666    // assert!(!glob_match("!(*/*)", "b/b"));
1667    // assert!(!glob_match("!(*/*)", "b/c"));
1668    // assert!(!glob_match("!(*/b)", "a/b"));
1669    // assert!(!glob_match("!(*/b)", "b/b"));
1670    // assert!(!glob_match("!(a/b)", "a/b"));
1671    assert!(!glob_match("!*", "a"));
1672    assert!(!glob_match("!*", "a.b"));
1673    assert!(!glob_match("!*/*", "a/a"));
1674    assert!(!glob_match("!*/*", "a/b"));
1675    assert!(!glob_match("!*/*", "a/c"));
1676    assert!(!glob_match("!*/*", "b/a"));
1677    assert!(!glob_match("!*/*", "b/b"));
1678    assert!(!glob_match("!*/*", "b/c"));
1679    assert!(!glob_match("!*/b", "a/b"));
1680    assert!(!glob_match("!*/b", "b/b"));
1681    assert!(!glob_match("!*/c", "a/c"));
1682    assert!(!glob_match("!*/c", "a/c"));
1683    assert!(!glob_match("!*/c", "b/c"));
1684    assert!(!glob_match("!*/c", "b/c"));
1685    assert!(!glob_match("!*a*", "bar"));
1686    assert!(!glob_match("!*a*", "fab"));
1687    // assert!(!glob_match("!a/(*)", "a/a"));
1688    // assert!(!glob_match("!a/(*)", "a/b"));
1689    // assert!(!glob_match("!a/(*)", "a/c"));
1690    // assert!(!glob_match("!a/(b)", "a/b"));
1691    assert!(!glob_match("!a/*", "a/a"));
1692    assert!(!glob_match("!a/*", "a/b"));
1693    assert!(!glob_match("!a/*", "a/c"));
1694    assert!(!glob_match("!f*b", "fab"));
1695    // assert!(glob_match("!(*/*)", "a"));
1696    // assert!(glob_match("!(*/*)", "a.b"));
1697    // assert!(glob_match("!(*/b)", "a"));
1698    // assert!(glob_match("!(*/b)", "a.b"));
1699    // assert!(glob_match("!(*/b)", "a/a"));
1700    // assert!(glob_match("!(*/b)", "a/c"));
1701    // assert!(glob_match("!(*/b)", "b/a"));
1702    // assert!(glob_match("!(*/b)", "b/c"));
1703    // assert!(glob_match("!(a/b)", "a"));
1704    // assert!(glob_match("!(a/b)", "a.b"));
1705    // assert!(glob_match("!(a/b)", "a/a"));
1706    // assert!(glob_match("!(a/b)", "a/c"));
1707    // assert!(glob_match("!(a/b)", "b/a"));
1708    // assert!(glob_match("!(a/b)", "b/b"));
1709    // assert!(glob_match("!(a/b)", "b/c"));
1710    assert!(glob_match("!*", "a/a"));
1711    assert!(glob_match("!*", "a/b"));
1712    assert!(glob_match("!*", "a/c"));
1713    assert!(glob_match("!*", "b/a"));
1714    assert!(glob_match("!*", "b/b"));
1715    assert!(glob_match("!*", "b/c"));
1716    assert!(glob_match("!*/*", "a"));
1717    assert!(glob_match("!*/*", "a.b"));
1718    assert!(glob_match("!*/b", "a"));
1719    assert!(glob_match("!*/b", "a.b"));
1720    assert!(glob_match("!*/b", "a/a"));
1721    assert!(glob_match("!*/b", "a/c"));
1722    assert!(glob_match("!*/b", "b/a"));
1723    assert!(glob_match("!*/b", "b/c"));
1724    assert!(glob_match("!*/c", "a"));
1725    assert!(glob_match("!*/c", "a.b"));
1726    assert!(glob_match("!*/c", "a/a"));
1727    assert!(glob_match("!*/c", "a/b"));
1728    assert!(glob_match("!*/c", "b/a"));
1729    assert!(glob_match("!*/c", "b/b"));
1730    assert!(glob_match("!*a*", "foo"));
1731    // assert!(glob_match("!a/(*)", "a"));
1732    // assert!(glob_match("!a/(*)", "a.b"));
1733    // assert!(glob_match("!a/(*)", "b/a"));
1734    // assert!(glob_match("!a/(*)", "b/b"));
1735    // assert!(glob_match("!a/(*)", "b/c"));
1736    // assert!(glob_match("!a/(b)", "a"));
1737    // assert!(glob_match("!a/(b)", "a.b"));
1738    // assert!(glob_match("!a/(b)", "a/a"));
1739    // assert!(glob_match("!a/(b)", "a/c"));
1740    // assert!(glob_match("!a/(b)", "b/a"));
1741    // assert!(glob_match("!a/(b)", "b/b"));
1742    // assert!(glob_match("!a/(b)", "b/c"));
1743    assert!(glob_match("!a/*", "a"));
1744    assert!(glob_match("!a/*", "a.b"));
1745    assert!(glob_match("!a/*", "b/a"));
1746    assert!(glob_match("!a/*", "b/b"));
1747    assert!(glob_match("!a/*", "b/c"));
1748    assert!(glob_match("!f*b", "bar"));
1749    assert!(glob_match("!f*b", "foo"));
1750
1751    assert!(!glob_match("!.md", ".md"));
1752    assert!(glob_match("!**/*.md", "a.js"));
1753    // assert!(!glob_match("!**/*.md", "b.md"));
1754    assert!(glob_match("!**/*.md", "c.txt"));
1755    assert!(glob_match("!*.md", "a.js"));
1756    assert!(!glob_match("!*.md", "b.md"));
1757    assert!(glob_match("!*.md", "c.txt"));
1758    assert!(!glob_match("!*.md", "abc.md"));
1759    assert!(glob_match("!*.md", "abc.txt"));
1760    assert!(!glob_match("!*.md", "foo.md"));
1761    assert!(glob_match("!.md", "foo.md"));
1762
1763    assert!(glob_match("!*.md", "a.js"));
1764    assert!(glob_match("!*.md", "b.txt"));
1765    assert!(!glob_match("!*.md", "c.md"));
1766    assert!(!glob_match("!a/*/a.js", "a/a/a.js"));
1767    assert!(!glob_match("!a/*/a.js", "a/b/a.js"));
1768    assert!(!glob_match("!a/*/a.js", "a/c/a.js"));
1769    assert!(!glob_match("!a/*/*/a.js", "a/a/a/a.js"));
1770    assert!(glob_match("!a/*/*/a.js", "b/a/b/a.js"));
1771    assert!(glob_match("!a/*/*/a.js", "c/a/c/a.js"));
1772    assert!(!glob_match("!a/a*.txt", "a/a.txt"));
1773    assert!(glob_match("!a/a*.txt", "a/b.txt"));
1774    assert!(glob_match("!a/a*.txt", "a/c.txt"));
1775    assert!(!glob_match("!a.a*.txt", "a.a.txt"));
1776    assert!(glob_match("!a.a*.txt", "a.b.txt"));
1777    assert!(glob_match("!a.a*.txt", "a.c.txt"));
1778    assert!(!glob_match("!a/*.txt", "a/a.txt"));
1779    assert!(!glob_match("!a/*.txt", "a/b.txt"));
1780    assert!(!glob_match("!a/*.txt", "a/c.txt"));
1781
1782    assert!(glob_match("!*.md", "a.js"));
1783    assert!(glob_match("!*.md", "b.txt"));
1784    assert!(!glob_match("!*.md", "c.md"));
1785    // assert!(!glob_match("!**/a.js", "a/a/a.js"));
1786    // assert!(!glob_match("!**/a.js", "a/b/a.js"));
1787    // assert!(!glob_match("!**/a.js", "a/c/a.js"));
1788    assert!(glob_match("!**/a.js", "a/a/b.js"));
1789    assert!(!glob_match("!a/**/a.js", "a/a/a/a.js"));
1790    assert!(glob_match("!a/**/a.js", "b/a/b/a.js"));
1791    assert!(glob_match("!a/**/a.js", "c/a/c/a.js"));
1792    assert!(glob_match("!**/*.md", "a/b.js"));
1793    assert!(glob_match("!**/*.md", "a.js"));
1794    assert!(!glob_match("!**/*.md", "a/b.md"));
1795    // assert!(!glob_match("!**/*.md", "a.md"));
1796    assert!(!glob_match("**/*.md", "a/b.js"));
1797    assert!(!glob_match("**/*.md", "a.js"));
1798    assert!(glob_match("**/*.md", "a/b.md"));
1799    assert!(glob_match("**/*.md", "a.md"));
1800    assert!(glob_match("!**/*.md", "a/b.js"));
1801    assert!(glob_match("!**/*.md", "a.js"));
1802    assert!(!glob_match("!**/*.md", "a/b.md"));
1803    // assert!(!glob_match("!**/*.md", "a.md"));
1804    assert!(glob_match("!*.md", "a/b.js"));
1805    assert!(glob_match("!*.md", "a.js"));
1806    assert!(glob_match("!*.md", "a/b.md"));
1807    assert!(!glob_match("!*.md", "a.md"));
1808    assert!(glob_match("!**/*.md", "a.js"));
1809    // assert!(!glob_match("!**/*.md", "b.md"));
1810    assert!(glob_match("!**/*.md", "c.txt"));
1811  }
1812
1813  #[test]
1814  fn question_mark() {
1815    assert!(glob_match("?", "a"));
1816    assert!(!glob_match("?", "aa"));
1817    assert!(!glob_match("?", "ab"));
1818    assert!(!glob_match("?", "aaa"));
1819    assert!(!glob_match("?", "abcdefg"));
1820
1821    assert!(!glob_match("??", "a"));
1822    assert!(glob_match("??", "aa"));
1823    assert!(glob_match("??", "ab"));
1824    assert!(!glob_match("??", "aaa"));
1825    assert!(!glob_match("??", "abcdefg"));
1826
1827    assert!(!glob_match("???", "a"));
1828    assert!(!glob_match("???", "aa"));
1829    assert!(!glob_match("???", "ab"));
1830    assert!(glob_match("???", "aaa"));
1831    assert!(!glob_match("???", "abcdefg"));
1832
1833    assert!(!glob_match("a?c", "aaa"));
1834    assert!(glob_match("a?c", "aac"));
1835    assert!(glob_match("a?c", "abc"));
1836    assert!(!glob_match("ab?", "a"));
1837    assert!(!glob_match("ab?", "aa"));
1838    assert!(!glob_match("ab?", "ab"));
1839    assert!(!glob_match("ab?", "ac"));
1840    assert!(!glob_match("ab?", "abcd"));
1841    assert!(!glob_match("ab?", "abbb"));
1842    assert!(glob_match("a?b", "acb"));
1843
1844    assert!(!glob_match("a/?/c/?/e.md", "a/bb/c/dd/e.md"));
1845    assert!(glob_match("a/??/c/??/e.md", "a/bb/c/dd/e.md"));
1846    assert!(!glob_match("a/??/c.md", "a/bbb/c.md"));
1847    assert!(glob_match("a/?/c.md", "a/b/c.md"));
1848    assert!(glob_match("a/?/c/?/e.md", "a/b/c/d/e.md"));
1849    assert!(!glob_match("a/?/c/???/e.md", "a/b/c/d/e.md"));
1850    assert!(glob_match("a/?/c/???/e.md", "a/b/c/zzz/e.md"));
1851    assert!(!glob_match("a/?/c.md", "a/bb/c.md"));
1852    assert!(glob_match("a/??/c.md", "a/bb/c.md"));
1853    assert!(glob_match("a/???/c.md", "a/bbb/c.md"));
1854    assert!(glob_match("a/????/c.md", "a/bbbb/c.md"));
1855  }
1856
1857  #[test]
1858  fn braces() {
1859    assert!(glob_match("{a,b,c}", "a"));
1860    assert!(glob_match("{a,b,c}", "b"));
1861    assert!(glob_match("{a,b,c}", "c"));
1862    assert!(!glob_match("{a,b,c}", "aa"));
1863    assert!(!glob_match("{a,b,c}", "bb"));
1864    assert!(!glob_match("{a,b,c}", "cc"));
1865
1866    assert!(glob_match("a/{a,b}", "a/a"));
1867    assert!(glob_match("a/{a,b}", "a/b"));
1868    assert!(!glob_match("a/{a,b}", "a/c"));
1869    assert!(!glob_match("a/{a,b}", "b/b"));
1870    assert!(!glob_match("a/{a,b,c}", "b/b"));
1871    assert!(glob_match("a/{a,b,c}", "a/c"));
1872    assert!(glob_match("a{b,bc}.txt", "abc.txt"));
1873
1874    assert!(glob_match("foo[{a,b}]baz", "foo{baz"));
1875
1876    assert!(!glob_match("a{,b}.txt", "abc.txt"));
1877    assert!(!glob_match("a{a,b,}.txt", "abc.txt"));
1878    assert!(!glob_match("a{b,}.txt", "abc.txt"));
1879    assert!(glob_match("a{,b}.txt", "a.txt"));
1880    assert!(glob_match("a{b,}.txt", "a.txt"));
1881    assert!(glob_match("a{a,b,}.txt", "aa.txt"));
1882    assert!(glob_match("a{a,b,}.txt", "aa.txt"));
1883    assert!(glob_match("a{,b}.txt", "ab.txt"));
1884    assert!(glob_match("a{b,}.txt", "ab.txt"));
1885
1886    // assert!(glob_match("{a/,}a/**", "a"));
1887    assert!(glob_match("a{a,b/}*.txt", "aa.txt"));
1888    assert!(glob_match("a{a,b/}*.txt", "ab/.txt"));
1889    assert!(glob_match("a{a,b/}*.txt", "ab/a.txt"));
1890    // assert!(glob_match("{a/,}a/**", "a/"));
1891    assert!(glob_match("{a/,}a/**", "a/a/"));
1892    // assert!(glob_match("{a/,}a/**", "a/a"));
1893    assert!(glob_match("{a/,}a/**", "a/a/a"));
1894    assert!(glob_match("{a/,}a/**", "a/a/"));
1895    assert!(glob_match("{a/,}a/**", "a/a/a/"));
1896    assert!(glob_match("{a/,}b/**", "a/b/a/"));
1897    assert!(glob_match("{a/,}b/**", "b/a/"));
1898    assert!(glob_match("a{,/}*.txt", "a.txt"));
1899    assert!(glob_match("a{,/}*.txt", "ab.txt"));
1900    assert!(glob_match("a{,/}*.txt", "a/b.txt"));
1901    assert!(glob_match("a{,/}*.txt", "a/ab.txt"));
1902
1903    assert!(glob_match("a{,.*{foo,db},\\(bar\\)}.txt", "a.txt"));
1904    assert!(!glob_match("a{,.*{foo,db},\\(bar\\)}.txt", "adb.txt"));
1905    assert!(glob_match("a{,.*{foo,db},\\(bar\\)}.txt", "a.db.txt"));
1906
1907    assert!(glob_match("a{,*.{foo,db},\\(bar\\)}.txt", "a.txt"));
1908    assert!(!glob_match("a{,*.{foo,db},\\(bar\\)}.txt", "adb.txt"));
1909    assert!(glob_match("a{,*.{foo,db},\\(bar\\)}.txt", "a.db.txt"));
1910
1911    // assert!(glob_match("a{,.*{foo,db},\\(bar\\)}", "a"));
1912    assert!(!glob_match("a{,.*{foo,db},\\(bar\\)}", "adb"));
1913    assert!(glob_match("a{,.*{foo,db},\\(bar\\)}", "a.db"));
1914
1915    // assert!(glob_match("a{,*.{foo,db},\\(bar\\)}", "a"));
1916    assert!(!glob_match("a{,*.{foo,db},\\(bar\\)}", "adb"));
1917    assert!(glob_match("a{,*.{foo,db},\\(bar\\)}", "a.db"));
1918
1919    assert!(!glob_match("{,.*{foo,db},\\(bar\\)}", "a"));
1920    assert!(!glob_match("{,.*{foo,db},\\(bar\\)}", "adb"));
1921    assert!(!glob_match("{,.*{foo,db},\\(bar\\)}", "a.db"));
1922    assert!(glob_match("{,.*{foo,db},\\(bar\\)}", ".db"));
1923
1924    assert!(!glob_match("{,*.{foo,db},\\(bar\\)}", "a"));
1925    assert!(glob_match("{*,*.{foo,db},\\(bar\\)}", "a"));
1926    assert!(!glob_match("{,*.{foo,db},\\(bar\\)}", "adb"));
1927    assert!(glob_match("{,*.{foo,db},\\(bar\\)}", "a.db"));
1928
1929    assert!(!glob_match("a/b/**/c{d,e}/**/xyz.md", "a/b/c/xyz.md"));
1930    assert!(!glob_match("a/b/**/c{d,e}/**/xyz.md", "a/b/d/xyz.md"));
1931    assert!(glob_match("a/b/**/c{d,e}/**/xyz.md", "a/b/cd/xyz.md"));
1932    assert!(glob_match("a/b/**/{c,d,e}/**/xyz.md", "a/b/c/xyz.md"));
1933    assert!(glob_match("a/b/**/{c,d,e}/**/xyz.md", "a/b/d/xyz.md"));
1934    assert!(glob_match("a/b/**/{c,d,e}/**/xyz.md", "a/b/e/xyz.md"));
1935
1936    assert!(glob_match("*{a,b}*", "xax"));
1937    assert!(glob_match("*{a,b}*", "xxax"));
1938    assert!(glob_match("*{a,b}*", "xbx"));
1939
1940    assert!(glob_match("*{*a,b}", "xba"));
1941    assert!(glob_match("*{*a,b}", "xb"));
1942
1943    assert!(!glob_match("*??", "a"));
1944    assert!(!glob_match("*???", "aa"));
1945    assert!(glob_match("*???", "aaa"));
1946    assert!(!glob_match("*****??", "a"));
1947    assert!(!glob_match("*****???", "aa"));
1948    assert!(glob_match("*****???", "aaa"));
1949
1950    assert!(!glob_match("a*?c", "aaa"));
1951    assert!(glob_match("a*?c", "aac"));
1952    assert!(glob_match("a*?c", "abc"));
1953
1954    assert!(glob_match("a**?c", "abc"));
1955    assert!(!glob_match("a**?c", "abb"));
1956    assert!(glob_match("a**?c", "acc"));
1957    assert!(glob_match("a*****?c", "abc"));
1958
1959    assert!(glob_match("*****?", "a"));
1960    assert!(glob_match("*****?", "aa"));
1961    assert!(glob_match("*****?", "abc"));
1962    assert!(glob_match("*****?", "zzz"));
1963    assert!(glob_match("*****?", "bbb"));
1964    assert!(glob_match("*****?", "aaaa"));
1965
1966    assert!(!glob_match("*****??", "a"));
1967    assert!(glob_match("*****??", "aa"));
1968    assert!(glob_match("*****??", "abc"));
1969    assert!(glob_match("*****??", "zzz"));
1970    assert!(glob_match("*****??", "bbb"));
1971    assert!(glob_match("*****??", "aaaa"));
1972
1973    assert!(!glob_match("?*****??", "a"));
1974    assert!(!glob_match("?*****??", "aa"));
1975    assert!(glob_match("?*****??", "abc"));
1976    assert!(glob_match("?*****??", "zzz"));
1977    assert!(glob_match("?*****??", "bbb"));
1978    assert!(glob_match("?*****??", "aaaa"));
1979
1980    assert!(glob_match("?*****?c", "abc"));
1981    assert!(!glob_match("?*****?c", "abb"));
1982    assert!(!glob_match("?*****?c", "zzz"));
1983
1984    assert!(glob_match("?***?****c", "abc"));
1985    assert!(!glob_match("?***?****c", "bbb"));
1986    assert!(!glob_match("?***?****c", "zzz"));
1987
1988    assert!(glob_match("?***?****?", "abc"));
1989    assert!(glob_match("?***?****?", "bbb"));
1990    assert!(glob_match("?***?****?", "zzz"));
1991
1992    assert!(glob_match("?***?****", "abc"));
1993    assert!(glob_match("*******c", "abc"));
1994    assert!(glob_match("*******?", "abc"));
1995    assert!(glob_match("a*cd**?**??k", "abcdecdhjk"));
1996    assert!(glob_match("a**?**cd**?**??k", "abcdecdhjk"));
1997    assert!(glob_match("a**?**cd**?**??k***", "abcdecdhjk"));
1998    assert!(glob_match("a**?**cd**?**??***k", "abcdecdhjk"));
1999    assert!(glob_match("a**?**cd**?**??***k**", "abcdecdhjk"));
2000    assert!(glob_match("a****c**?**??*****", "abcdecdhjk"));
2001
2002    assert!(!glob_match("a/?/c/?/*/e.md", "a/b/c/d/e.md"));
2003    assert!(glob_match("a/?/c/?/*/e.md", "a/b/c/d/e/e.md"));
2004    assert!(glob_match("a/?/c/?/*/e.md", "a/b/c/d/efghijk/e.md"));
2005    assert!(glob_match("a/?/**/e.md", "a/b/c/d/efghijk/e.md"));
2006    assert!(!glob_match("a/?/e.md", "a/bb/e.md"));
2007    assert!(glob_match("a/??/e.md", "a/bb/e.md"));
2008    assert!(!glob_match("a/?/**/e.md", "a/bb/e.md"));
2009    assert!(glob_match("a/?/**/e.md", "a/b/ccc/e.md"));
2010    assert!(glob_match("a/*/?/**/e.md", "a/b/c/d/efghijk/e.md"));
2011    assert!(glob_match("a/*/?/**/e.md", "a/b/c/d/efgh.ijk/e.md"));
2012    assert!(glob_match("a/*/?/**/e.md", "a/b.bb/c/d/efgh.ijk/e.md"));
2013    assert!(glob_match("a/*/?/**/e.md", "a/bbb/c/d/efgh.ijk/e.md"));
2014
2015    assert!(glob_match("a/*/ab??.md", "a/bbb/abcd.md"));
2016    assert!(glob_match("a/bbb/ab??.md", "a/bbb/abcd.md"));
2017    assert!(glob_match("a/bbb/ab???md", "a/bbb/abcd.md"));
2018  }
2019
2020  #[test]
2021  fn captures() {
2022    fn test_captures<'a>(glob: &str, path: &'a str) -> Option<Vec<&'a str>> {
2023      glob_match_with_captures(glob, path)
2024        .map(|v| v.into_iter().map(|capture| &path[capture]).collect())
2025    }
2026
2027    assert_eq!(test_captures("a/b", "a/b"), Some(vec![]));
2028    assert_eq!(test_captures("a/*/c", "a/bx/c"), Some(vec!["bx"]));
2029    assert_eq!(test_captures("a/*/c", "a/test/c"), Some(vec!["test"]));
2030    assert_eq!(
2031      test_captures("a/*/c/*/e", "a/b/c/d/e"),
2032      Some(vec!["b", "d"])
2033    );
2034    assert_eq!(
2035      test_captures("a/*/c/*/e", "a/b/c/d/e"),
2036      Some(vec!["b", "d"])
2037    );
2038    assert_eq!(test_captures("a/{b,x}/c", "a/b/c"), Some(vec!["b"]));
2039    assert_eq!(test_captures("a/{b,x}/c", "a/x/c"), Some(vec!["x"]));
2040    assert_eq!(test_captures("a/?/c", "a/b/c"), Some(vec!["b"]));
2041    assert_eq!(test_captures("a/*?x/c", "a/yybx/c"), Some(vec!["yy", "b"]));
2042    assert_eq!(
2043      test_captures("a/*[a-z]x/c", "a/yybx/c"),
2044      Some(vec!["yy", "b"])
2045    );
2046    assert_eq!(
2047      test_captures("a/{b*c,c}y", "a/bdcy"),
2048      Some(vec!["bdc", "d"])
2049    );
2050    assert_eq!(test_captures("a/{b*,c}y", "a/bdy"), Some(vec!["bd", "d"]));
2051    assert_eq!(test_captures("a/{b*c,c}", "a/bdc"), Some(vec!["bdc", "d"]));
2052    assert_eq!(test_captures("a/{b*,c}", "a/bd"), Some(vec!["bd", "d"]));
2053    assert_eq!(test_captures("a/{b*,c}", "a/c"), Some(vec!["c", ""]));
2054    assert_eq!(
2055      test_captures("a/{b{c,d},c}y", "a/bdy"),
2056      Some(vec!["bd", "d"])
2057    );
2058    assert_eq!(
2059      test_captures("a/{b*,c*}y", "a/bdy"),
2060      Some(vec!["bd", "d", ""])
2061    );
2062    assert_eq!(
2063      test_captures("a/{b*,c*}y", "a/cdy"),
2064      Some(vec!["cd", "", "d"])
2065    );
2066    assert_eq!(test_captures("a/{b,c}", "a/b"), Some(vec!["b"]));
2067    assert_eq!(test_captures("a/{b,c}", "a/c"), Some(vec!["c"]));
2068    assert_eq!(test_captures("a/{b,c[}]*}", "a/b"), Some(vec!["b", "", ""]));
2069    assert_eq!(
2070      test_captures("a/{b,c[}]*}", "a/c}xx"),
2071      Some(vec!["c}xx", "}", "xx"])
2072    );
2073
2074    // assert\.deepEqual\(([!])?capture\('(.*?)', ['"](.*?)['"]\), (.*)?\);
2075    // assert_eq!(test_captures("$2", "$3"), Some(vec!$4));
2076
2077    assert_eq!(test_captures("test/*", "test/foo"), Some(vec!["foo"]));
2078    assert_eq!(
2079      test_captures("test/*/bar", "test/foo/bar"),
2080      Some(vec!["foo"])
2081    );
2082    assert_eq!(
2083      test_captures("test/*/bar/*", "test/foo/bar/baz"),
2084      Some(vec!["foo", "baz"])
2085    );
2086    assert_eq!(test_captures("test/*.js", "test/foo.js"), Some(vec!["foo"]));
2087    assert_eq!(
2088      test_captures("test/*-controller.js", "test/foo-controller.js"),
2089      Some(vec!["foo"])
2090    );
2091
2092    assert_eq!(
2093      test_captures("test/**/*.js", "test/a.js"),
2094      Some(vec!["", "a"])
2095    );
2096    assert_eq!(
2097      test_captures("test/**/*.js", "test/dir/a.js"),
2098      Some(vec!["dir", "a"])
2099    );
2100    assert_eq!(
2101      test_captures("test/**/*.js", "test/dir/test/a.js"),
2102      Some(vec!["dir/test", "a"])
2103    );
2104    assert_eq!(
2105      test_captures("**/*.js", "test/dir/a.js"),
2106      Some(vec!["test/dir", "a"])
2107    );
2108    assert_eq!(
2109      test_captures("**/**/**/**/a", "foo/bar/baz/a"),
2110      Some(vec!["foo/bar/baz"])
2111    );
2112    assert_eq!(
2113      test_captures("a/{b/**/y,c/**/d}", "a/b/y"),
2114      Some(vec!["b/y", "", ""])
2115    );
2116    assert_eq!(
2117      test_captures("a/{b/**/y,c/**/d}", "a/b/x/x/y"),
2118      Some(vec!["b/x/x/y", "x/x", ""])
2119    );
2120    assert_eq!(
2121      test_captures("a/{b/**/y,c/**/d}", "a/c/x/x/d"),
2122      Some(vec!["c/x/x/d", "", "x/x"])
2123    );
2124    assert_eq!(
2125      test_captures("a/{b/**/**/y,c/**/**/d}", "a/b/x/x/x/x/x/y"),
2126      Some(vec!["b/x/x/x/x/x/y", "x/x/x/x/x", ""])
2127    );
2128    assert_eq!(
2129      test_captures("a/{b/**/**/y,c/**/**/d}", "a/c/x/x/x/x/x/d"),
2130      Some(vec!["c/x/x/x/x/x/d", "", "x/x/x/x/x"])
2131    );
2132    assert_eq!(
2133      test_captures(
2134        "some/**/{a,b,c}/**/needle.txt",
2135        "some/path/a/to/the/needle.txt"
2136      ),
2137      Some(vec!["path", "a", "to/the"])
2138    );
2139  }
2140
2141  #[test]
2142  fn fuzz_tests() {
2143    // https://github.com/devongovett/glob-match/issues/1
2144    let s = "{*{??*{??**,Uz*zz}w**{*{**a,z***b*[!}w??*azzzzzzzz*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!z[za,z&zz}w**z*z*}";
2145    assert!(!glob_match(s, s));
2146    let s = "**** *{*{??*{??***\u{5} *{*{??*{??***\u{5},\0U\0}]*****\u{1},\0***\0,\0\0}w****,\0U\0}]*****\u{1},\0***\0,\0\0}w*****\u{1}***{}*.*\0\0*\0";
2147    assert!(!glob_match(s, s));
2148  }
2149}