Skip to main content

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