示例#1
0
class TestGlobCornerCase(_TestGlob):
    """
    Some tests that need a very specific file set to test against for corner cases.

    See `_TestGlob` class for more information in regards to test case format.
    """

    cases = [
        # Test very specific, special cases.
        [('a[/]b', ), [(
            'a[',
            ']b',
        )]],
        [('@(a/b)', ), []],
        [('@(a[/]b)', ), []],
        [('test[', ), [('test[', )]],
        [(r'a\/b', ), [('a', 'b')] if not util.is_case_sensitive() else []],
        [(r'a[\/]b', ),
         [('a[', ']b')] if not util.is_case_sensitive() else []],
        Options(skip=util.is_case_sensitive()),
        [('a[\\', ), [('a[', '')]],
        [('@(a[\\', ), [('@(a[', '')]],
        Options(skip=False)
    ]

    @classmethod
    def setup_fs(cls):
        """Setup file system."""

        cls.mktemp('test[')
        cls.mktemp('a', 'b')
        cls.mktemp('a[', ']b')
        cls.mktemp('@(a', 'b)')
        cls.mktemp('@(a[', ']b)')
        cls.can_symlink = can_symlink()

    @pytest.mark.parametrize("case", cases)
    def test_glob_cases(self, case):
        """Test glob cases."""

        self.eval_glob_cases(case)
示例#2
0
    def test_windows_drives(self):
        """Test windows drives."""

        if util.is_case_sensitive():
            return

        self.assertTrue(
            glob.globmatch('//?/c:/somepath/to/match/file.txt',
                           '//?/c:/**/*.txt',
                           flags=self.flags))

        self.assertTrue(
            glob.globmatch('c:/somepath/to/match/file.txt',
                           'c:/**/*.txt',
                           flags=self.flags))
示例#3
0
class TestFnMatchFilter:
    """
    Test filter.

    `cases` is used in conjunction with the `filter` command
    which takes a list of file names and returns only those which match.

    * Pattern
    * List of filenames
    * Expected result (list of filenames that matched the pattern)
    * Flags

    The default flags are `DOTMATCH`. Any flags passed through via entry are XORed.
    So if `DOTMATCH` is passed via an entry, it will actually disable the default `DOTMATCH`.
    """

    cases = [['P*', ['Python', 'Ruby', 'Perl', 'Tcl'], ['Python', 'Perl'], 0],
             [
                 b'P*', [b'Python', b'Ruby', b'Perl', b'Tcl'],
                 [b'Python', b'Perl'], 0
             ],
             [
                 '*.p*', ['Test.py', 'Test.rb', 'Test.PL'],
                 (['Test.py', 'Test.PL']
                  if not util.is_case_sensitive() else ['Test.py']), 0
             ],
             [
                 '*.P*', ['Test.py', 'Test.rb', 'Test.PL'],
                 (['Test.py', 'Test.PL']
                  if not util.is_case_sensitive() else ['Test.PL']), 0
             ],
             [
                 'usr/*', ['usr/bin', 'usr', 'usr\\lib'],
                 (['usr\\bin', 'usr\\lib']
                  if not util.is_case_sensitive() else ['usr/bin']), 0
             ],
             [
                 r'usr\\*', ['usr/bin', 'usr', 'usr\\lib'],
                 (['usr\\bin', 'usr\\lib']
                  if not util.is_case_sensitive() else ['usr\\lib']), 0
             ],
             [
                 r'te\st[ma]', ['testm', 'test\\3', 'testa'],
                 ['testm', 'testa'], fnmatch.I
             ],
             [
                 r'te\st[ma]', ['testm', 'test\\3', 'testa'],
                 ['testm', 'testa'], fnmatch.F
             ]]

    @classmethod
    def setup_class(cls):
        """Setup the tests."""

        cls.flags = fnmatch.DOTMATCH

    @staticmethod
    def assert_equal(a, b):
        """Assert equal."""

        assert a == b, "Comparison between objects yielded False."

    @classmethod
    def evaluate(cls, case):
        """Evaluate matches."""

        flags = case[3]
        flags = cls.flags ^ flags
        print("PATTERN: ", case[0])
        print("FILES: ", case[1])
        print("FLAGS: ", bin(flags))
        value = fnmatch.filter(case[1], case[0], flags=flags)
        print("TEST: ", value, '<=>', case[2], '\n')
        cls.assert_equal(value, case[2])

    @pytest.mark.parametrize("case", cases)
    def test_cases(self, case):
        """Test case."""

        self.evaluate(case)
示例#4
0
class TestFnMatch:
    """
    Test `fnmatch`.

    Each entry in `cases` is run through the `fnmatch`.  They are also run through
    `fnsplit` and then `fnmatch` as a separate operation to ensure `fnsplit` adds
    no unintended side effects.

    Each case entry is an array of 4 parameters.

    * Pattern
    * File name
    * Expected result (boolean of whether pattern matched file name)
    * Flags

    The default flags are `DOTMATCH`. Any flags passed through via entry are XORed.
    So if `DOTMATCH` is passed via an entry, it will actually disable the default `DOTMATCH`.
    """

    cases = [
        # Basic test of traditional features
        ['abc', 'abc', True, 0],
        ['?*?', 'abc', True, 0],
        ['???*', 'abc', True, 0],
        ['*???', 'abc', True, 0],
        ['???', 'abc', True, 0],
        ['*', 'abc', True, 0],
        ['ab[cd]', 'abc', True, 0],
        ['ab[!de]', 'abc', True, 0],
        ['ab[de]', 'abc', False, 0],
        ['??', 'a', False, 0],
        ['b', 'a', False, 0],

        # Test that '\' is handled correctly in character sets;
        [r'[\]', '\\', False, 0],
        [r'[!\]', 'a', False, 0],
        [r'[!\]', '\\', False, 0],
        [r'[\\]', '\\', True, 0],
        [r'[!\\]', 'a', True, 0],
        [r'[!\\]', '\\', False, 0],

        # Test that filenames with newlines in them are handled correctly.
        ['foo*', 'foo\nbar', True, 0],
        ['foo*', 'foo\nbar\n', True, 0],
        ['foo*', '\nfoo', False, 0],
        ['*', '\n', True, 0],

        # Force case: General
        ['abc', 'abc', True, fnmatch.F],
        ['abc', 'AbC', False, fnmatch.F],
        ['AbC', 'abc', False, fnmatch.F],
        ['AbC', 'AbC', True, fnmatch.F],

        # Force case: slash conventions
        ['usr/bin', 'usr/bin', True, fnmatch.F],
        ['usr/bin', 'usr\\bin', False, fnmatch.F],
        [r'usr\\bin', 'usr/bin', False, fnmatch.F],
        [r'usr\\bin', 'usr\\bin', True, fnmatch.F],

        # Wildcard tests
        [b'te*', b'test', True, 0],
        [b'te*\xff', b'test\xff', True, 0],
        [b'foo*', b'foo\nbar', True, 0],

        # OS specific case behavior
        ['abc', 'abc', True, 0],
        ['abc', 'AbC', not util.is_case_sensitive(), 0],
        ['AbC', 'abc', not util.is_case_sensitive(), 0],
        ['AbC', 'AbC', True, 0],

        # OS specific slash behavior
        ['usr/bin', 'usr/bin', True, 0],
        ['usr/bin', 'usr\\bin', not util.is_case_sensitive(), 0],
        [r'usr\\bin', 'usr/bin', not util.is_case_sensitive(), 0],
        [r'usr\\bin', 'usr\\bin', True, 0],

        # Ensure that we don't fail on regular expression related symbols
        # such as &&, ||, ~~, --, or [.  Currently re doesn't do anything with
        # && etc., but they are handled special in re as there are plans to utilize them.
        ['[[]', '[', True, 0],
        ['[a&&b]', '&', True, 0],
        ['[a||b]', '|', True, 0],
        ['[a~~b]', '~', True, 0],
        ['[a-z+--A-Z]', ',', True, 0],
        ['[a-z--/A-Z]', '.', True, 0],

        # `Dotmatch` cases
        ['.abc', '.abc', True, 0],
        [r'\.abc', '.abc', True, 0],
        ['?abc', '.abc', True, 0],
        ['*abc', '.abc', True, 0],
        ['[.]abc', '.abc', True, 0],
        ['*(.)abc', '.abc', True, fnmatch.E],
        ['*(?)abc', '.abc', True, fnmatch.E],
        ['*(?|.)abc', '.abc', True, fnmatch.E],
        ['*(?|*)abc', '.abc', True, fnmatch.E],
        ['!(test)', '.abc', True, fnmatch.E],

        # Turn off `dotmatch` cases
        ['.abc', '.abc', True, fnmatch.D],
        [r'\.abc', '.abc', True, fnmatch.D],
        ['?abc', '.abc', False, fnmatch.D],
        ['*abc', '.abc', False, fnmatch.D],
        ['[.]abc', '.abc', False, fnmatch.D],
        ['*(.)abc', '.abc', False, fnmatch.E | fnmatch.D],
        [r'*(\.)abc', '.abc', False, fnmatch.E | fnmatch.D],
        ['*(?)abc', '.abc', False, fnmatch.E | fnmatch.D],
        ['*(?|.)abc', '.abc', False, fnmatch.E | fnmatch.D],
        ['*(?|*)abc', '.abc', False, fnmatch.E | fnmatch.D],
        ['a.bc', 'a.bc', True, fnmatch.D],
        ['a?bc', 'a.bc', True, fnmatch.D],
        ['a*bc', 'a.bc', True, fnmatch.D],
        ['a[.]bc', 'a.bc', True, fnmatch.D],
        ['a*(.)bc', 'a.bc', True, fnmatch.E | fnmatch.D],
        [r'a*(\.)bc', 'a.bc', True, fnmatch.E | fnmatch.D],
        ['a*(?)bc', 'a.bc', True, fnmatch.E | fnmatch.D],
        ['a*(?|.)bc', 'a.bc', True, fnmatch.E | fnmatch.D],
        ['a*(?|*)bc', 'a.bc', True, fnmatch.E | fnmatch.D],
        ['!(test)', '.abc', False, fnmatch.D | fnmatch.E],
        ['!(test)', 'abc', True, fnmatch.D | fnmatch.E],

        # POSIX style character classes
        ['[[:alnum:]]bc', 'zbc', True, 0],
        ['[[:alnum:]]bc', '1bc', True, 0],
        ['[a[:alnum:]]bc', 'zbc', True, 0],
        ['[[:alnum:][:blank:]]bc', ' bc', True, 0],

        # We can't use a character class as a range.
        ['[-[:alnum:]]bc', '-bc', True, 0],
        ['[a-[:alnum:]]bc', '-bc', True, 0],
        ['[[:alnum:]-z]bc', '-bc', True, 0],

        # Negation
        ['[![:alnum:]]bc', '!bc', True, 0],
        ['[^[:alnum:]]bc', '!bc', True, 0],

        # Backwards ranges
        ['[a-z]', 'a', True, 0],
        ['[z-a]', 'a', False, 0],
        ['[!z-a]', 'a', True, 0],
        ['[!a-z]', 'a', False, 0],
        ['[9--]', '9', False, 0],

        # Escaped slashes are just slashes as they aren't treated special beyond normalization.
        [r'a\/b', ('a/b' if util.is_case_sensitive() else 'a\\\\b'), True, 0]
    ]

    @classmethod
    def setup_class(cls):
        """Setup the tests."""

        cls.flags = fnmatch.DOTMATCH

    @staticmethod
    def assert_equal(a, b):
        """Assert equal."""

        assert a == b, "Comparison between objects yielded False."

    @classmethod
    def evaluate(cls, case):
        """Evaluate matches."""

        flags = case[3]
        flags = cls.flags ^ flags
        print("PATTERN: ", case[0])
        print("FILE: ", case[1])
        print("FLAGS: ", bin(flags))
        print("TEST: ", case[2], '\n')
        cls.assert_equal(fnmatch.fnmatch(case[1], case[0], flags=flags),
                         case[2])
        cls.assert_equal(
            fnmatch.fnmatch(case[1],
                            fnmatch.fnsplit(case[0], flags=flags),
                            flags=flags), case[2])

    @pytest.mark.parametrize("case", cases)
    def test_cases(self, case):
        """Test case."""

        self.evaluate(case)
示例#5
0
class Testglob(_TestGlob):
    """
    Test glob.

    See `_TestGlob` class for more information in regards to test case format.
    """

    cases = [
        # Test literal.
        [('a', ), [('a', )]],
        [('a', 'D'), [('a', 'D')]],
        [('aab', ), [('aab', )]],
        [('zymurgy', ), []],
        Options(absolute=True),
        [['*'], None],
        [[os.curdir, '*'], None],
        Options(absolute=False),

        # Glob one directory
        [('a*', ), [('a', ), ('aab', ), ('aaa', )]],
        [('*a', ), [('a', ), ('aaa', )]],
        [('.*', ), [('.', ), ('..', ), ('.aa', ), ('.bb', )]],
        [('?aa', ), [('aaa', )]],
        [('aa?', ), [('aaa', ), ('aab', )]],
        [('aa[ab]', ), [('aaa', ), ('aab', )]],
        [('*q', ), []],
        [('.', ), [('.', )]],
        [('?', ), [('a', )]],
        [('[.a]', ), [('a', )]],
        [('*.', ), []],

        # Glob with braces
        [('{a*,a*}', ), [('a', ), ('aab', ), ('aaa', )]],

        # Glob with braces and "unique" turned off
        [('{a*,a*}', ),
         [('a', ), ('aab', ), ('aaa', ), ('a', ), ('aab', ), ('aaa', )],
         glob.Q],
        Options(default_negate='**'),
        # Glob inverse
        [('a*', '**'),
         [('EF', ), ('ZZZ', ),
          ('', )] if not can_symlink() else [('EF', ), ('ZZZ', ), ('', ),
                                             ('sym1', ), ('sym3', ),
                                             ('sym2', ), ('sym3', 'efg'),
                                             ('sym3', 'efg', 'ha'),
                                             ('sym3', 'EF')], glob.N],
        Options(default_negate='sym3/EF'),
        [('**', 'EF'), [] if not can_symlink() else [], glob.N | glob.L],
        [('**', 'EF'), [] if not can_symlink() else [], glob.N],
        Options(default_negate='**'),

        # Disable symlinks
        [('a*', '**'), [('EF', ), ('ZZZ', ),
                        ('', )] if not can_symlink() else [('EF', ), ('ZZZ', ),
                                                           ('', ), ('sym1', ),
                                                           ('sym2', )],
         glob.N | glob.L],
        Options(cwd_temp=True, absolute=True),
        # Test base matching
        [('*', ),
         [('EF', ), ('ZZZ', ), ('a', ), ('a', 'D'), ('a', 'bcd'),
          ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'),
          ('aaa', ), ('aaa', 'zzzF'), ('aab', ),
          ('aab', 'F')] if not can_symlink() else [('EF', ), ('ZZZ', ),
                                                   ('a', ), ('a', 'D'),
                                                   ('a', 'bcd'),
                                                   ('a', 'bcd', 'EF'),
                                                   ('a', 'bcd', 'efg'),
                                                   ('a', 'bcd', 'efg', 'ha'),
                                                   ('aaa', ), ('aaa', 'zzzF'),
                                                   ('aab', ), ('aab', 'F'),
                                                   ('sym1', ), ('sym2', )],
         glob.L | glob.X],

        # Test that base matching does not occur with a path pattern
        [('aab', '*'), [('aab', 'F')], glob.L | glob.X],
        Options(cwd_temp=False, absolute=False),
        [('**', ),
         [(
             'a',
             'bcd',
             'EF',
         ), (
             'a',
             'bcd',
             'efg',
             'ha',
         ), (
             'a',
             'D',
         ), (
             'aaa',
             'zzzF',
         ), (
             'aab',
             'F',
         ), ('EF', ), ('ZZZ', )] if not can_symlink() else [(
             'a',
             'bcd',
             'EF',
         ), (
             'a',
             'bcd',
             'efg',
             'ha',
         ), (
             'a',
             'D',
         ), (
             'aaa',
             'zzzF',
         ), (
             'aab',
             'F',
         ), ('EF', ), ('sym1', ), ('sym2', ), ('ZZZ', )], glob.L | glob.O],

        # Test nested glob directory
        [('a', 'bcd', 'E*'),
         [('a', 'bcd',
           'EF')] if util.is_case_sensitive() else [('a', 'bcd', 'EF'),
                                                    ('a', 'bcd', 'efg')]],
        [('a', 'bcd', '*g'), [('a', 'bcd', 'efg')]],

        # Test case sensitive and insensitive
        [('a', 'bcd', 'E*'), [('a', 'bcd', 'EF')], glob.C],
        [('a', 'bcd', 'E*'), [('a', 'bcd', 'EF'), ('a', 'bcd', 'efg')],
         glob.I],

        # Test glob directory names.
        [('*', 'D'), [('a', 'D')]],
        [('*', '*a'), []],
        [('a', '*', '*', '*a'), [('a', 'bcd', 'efg', 'ha')]],
        [('?a?', '*F'), [('aaa', 'zzzF'), ('aab', 'F')]],

        # Test glob magic in drive name.
        Options(absolute=True, skip=sys.platform != "win32"),
        [('*:', ), []],
        [('?:', ), []],
        [(r'\\\\?\\c:\\', ), [('\\\\?\\c:\\', )]],
        [(r'\\\\*\\*\\', ), []],
        Options(absolute=False, skip=False),
        Options(skip=not can_symlink()),
        # Test broken symlinks
        [('sym*', ), [('sym1', ), ('sym2', ), ('sym3', )]],
        [('sym1', ), [('sym1', )]],
        [('sym2', ), [('sym2', )]],

        # Test glob symlinks.,
        [('sym3', ), [('sym3', )]],
        [('sym3', '*'), [('sym3', 'EF'), ('sym3', 'efg')]],
        [('sym3', ''), [('sym3', '')]],
        [('*', '*F'), [('aaa', 'zzzF'), ('aab', 'F'), ('sym3', 'EF')]],
        Options(skip=False),

        # Test only directories
        [('*', ''), [('aab', ''), ('aaa', ''),
                     ('a', '')] if not can_symlink() else [('aab', ''),
                                                           ('aaa', ''),
                                                           ('a', ''),
                                                           ('sym3', '')]],
        Options(skip=util.is_case_sensitive()),
        [('*\\', ), [('aab', ''), ('aaa', ''),
                     ('a', '')] if not can_symlink() else [('aab', ''),
                                                           ('aaa', ''),
                                                           ('a', ''),
                                                           ('sym3', '')]],
        Options(skip=False),

        # Test `extglob`.
        [('@(a|aa*(a|b))', ), [('aab', ), ('aaa', ), ('a', )]],

        # Test sequences.
        [('[a]', ), [('a', )]],
        [('[!b]', ), [('a', )]],
        [('[^b]', ), [('a', )]],
        [(r'@([\a]|\aaa)', ), [('a', ), ('aaa', )]],
        Options(absolute=True),
        # Test empty.
        [('', ), []],
        Options(absolute=False),

        # Patterns ending with a slash shouldn't match non-directories.
        [('Z*Z', ''), []],
        [('ZZZ', ''), []],
        [('aa*', ''), [('aaa', ''), ('aab', '')]],

        # Test recursion.
        [('**', ),
         [('', ), ('EF', ), ('ZZZ', ), ('a', ), ('a', 'D'), ('a', 'bcd'),
          ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'),
          ('aaa', ), ('aaa', 'zzzF'), ('aab', ),
          ('aab', 'F')] if not can_symlink() else [('', ), ('EF', ), ('ZZZ', ),
                                                   ('a', ), ('a', 'D'),
                                                   ('a', 'bcd'),
                                                   ('a', 'bcd', 'EF'),
                                                   ('a', 'bcd', 'efg'),
                                                   ('a', 'bcd', 'efg', 'ha'),
                                                   ('aaa', ), ('aaa', 'zzzF'),
                                                   ('aab', ), ('aab', 'F'),
                                                   ('sym1', ), ('sym2', ),
                                                   ('sym3', ), ('sym3', 'EF'),
                                                   ('sym3', 'efg'),
                                                   ('sym3', 'efg', 'ha')]],
        [('**', '**'),
         [
             ('', ),
             ('EF', ),
             ('ZZZ', ),
             ('a', ),
             ('a', 'D'),
             ('a', 'bcd'),
             ('a', 'bcd', 'EF'),
             ('a', 'bcd', 'efg'),
             ('a', 'bcd', 'efg', 'ha'),
             ('aaa', ),
             ('aaa', 'zzzF'),
             ('aab', ),
             ('aab', 'F'),
         ] if not can_symlink() else [('', ), ('EF', ), ('ZZZ', ), ('a', ),
                                      ('a', 'D'), ('a', 'bcd'),
                                      ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'),
                                      ('a', 'bcd', 'efg', 'ha'), ('aaa', ),
                                      ('aaa', 'zzzF'), ('aab', ), ('aab', 'F'),
                                      ('sym1', ), ('sym2', ), ('sym3', ),
                                      ('sym3', 'EF'), ('sym3', 'efg'),
                                      ('sym3', 'efg', 'ha')]],
        [('.', '**'),
         [
             ('.', ''),
             ('.', 'EF'),
             ('.', 'ZZZ'),
             ('.', 'a'),
             ('.', 'a', 'D'),
             ('.', 'a', 'bcd'),
             ('.', 'a', 'bcd', 'EF'),
             ('.', 'a', 'bcd', 'efg'),
             ('.', 'a', 'bcd', 'efg', 'ha'),
             ('.', 'aaa'),
             ('.', 'aaa', 'zzzF'),
             ('.', 'aab'),
             ('.', 'aab', 'F'),
         ] if not can_symlink() else [('.', ''), ('.', 'EF'), ('.', 'ZZZ'),
                                      ('.', 'a'), ('.', 'a', 'D'),
                                      ('.', 'a', 'bcd'),
                                      ('.', 'a', 'bcd', 'EF'),
                                      ('.', 'a', 'bcd', 'efg'),
                                      ('.', 'a', 'bcd', 'efg', 'ha'),
                                      ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                                      ('.', 'aab'), ('.', 'aab', 'F'),
                                      ('.', 'sym1'), ('.', 'sym2'),
                                      ('.', 'sym3'), ('.', 'sym3', 'EF'),
                                      ('.', 'sym3', 'efg'),
                                      ('.', 'sym3', 'efg', 'ha')]],
        [
            ('**', ''),
            # Directories
            [('', ), ('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
             ('aaa', ''),
             ('aab', '')] if not can_symlink() else [('', ), ('a', ''),
                                                     ('a', 'bcd', ''),
                                                     ('a', 'bcd', 'efg', ''),
                                                     ('aaa', ''), ('aab', ''),
                                                     ('sym3', ''),
                                                     ('sym3', 'efg', '')]
        ],
        [('a', '**'),
         [('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'),
          ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha')]],
        [('a**', ), [('a', ), ('aaa', ), ('aab', )]],
        [('**', 'EF'),
         [('a', 'bcd', 'EF'),
          ('EF', )] if not can_symlink() else [('a', 'bcd', 'EF'), ('EF', ),
                                               ('sym3', 'EF')]],
        [('**', '*F'),
         [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'),
          ('EF', )] if not can_symlink() else [('a', 'bcd', 'EF'),
                                               ('aaa', 'zzzF'), ('aab', 'F'),
                                               ('EF', ), ('sym3', 'EF')]],
        [('**', '*F', ''), []],
        [('**', 'bcd', '*'), [('a', 'bcd', 'EF'), ('a', 'bcd', 'efg')]],
        [('a', '**', 'bcd'), [('a', 'bcd')]],
        Options(cwd_temp=True, absolute=True),
        [('**', ),
         [('EF', ), ('ZZZ', ), ('a', ), ('a', 'D'), ('a', 'bcd'),
          ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'),
          ('aaa', ), ('aaa', 'zzzF'), ('aab', ),
          ('aab', 'F')] if not can_symlink() else [('EF', ), ('ZZZ', ),
                                                   ('a', ), ('a', 'D'),
                                                   ('a', 'bcd'),
                                                   ('a', 'bcd', 'EF'),
                                                   ('a', 'bcd', 'efg'),
                                                   ('a', 'bcd', 'efg', 'ha'),
                                                   ('aaa', ), ('aaa', 'zzzF'),
                                                   ('aab', ), ('aab', 'F'),
                                                   ('sym1', ), ('sym2', ),
                                                   ('sym3', ), ('sym3', 'EF'),
                                                   ('sym3', 'efg'),
                                                   ('sym3', 'efg', 'ha')]],
        [('**', '*'),
         [('EF', ), ('ZZZ', ), ('a', ), ('a', 'D'), ('a', 'bcd'),
          ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'),
          ('aaa', ), ('aaa', 'zzzF'), ('aab', ),
          ('aab', 'F')] if not can_symlink() else [('EF', ), ('ZZZ', ),
                                                   ('a', ), ('a', 'D'),
                                                   ('a', 'bcd'),
                                                   ('a', 'bcd', 'EF'),
                                                   ('a', 'bcd', 'efg'),
                                                   ('a', 'bcd', 'efg', 'ha'),
                                                   ('aaa', ), ('aaa', 'zzzF'),
                                                   ('aab', ), ('aab', 'F'),
                                                   ('sym1', ), ('sym2', ),
                                                   ('sym3', ), ('sym3', 'EF'),
                                                   ('sym3', 'efg'),
                                                   ('sym3', 'efg', 'ha')]],
        [(os.curdir, '**'),
         [('.', ''), ('.', 'EF'), ('.', 'ZZZ'), (
             '.',
             'a',
         ), ('.', 'a', 'D'), ('.', 'a', 'bcd'), ('.', 'a', 'bcd', 'EF'),
          ('.', 'a', 'bcd', 'efg'),
          ('.', 'a', 'bcd', 'efg', 'ha'), ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
          ('.', 'aab'), ('.', 'aab', 'F')] if not can_symlink() else [
              ('.', ''), (
                  '.',
                  'EF',
              ), ('.', 'ZZZ'), (
                  '.',
                  'a',
              ), ('.', 'a', 'D'), ('.', 'a', 'bcd'), ('.', 'a', 'bcd', 'EF'),
              ('.', 'a', 'bcd', 'efg'), ('.', 'a', 'bcd', 'efg', 'ha'),
              ('.', 'aaa'), ('.', 'aaa', 'zzzF'), ('.', 'aab'),
              ('.', 'aab', 'F'), ('.', 'sym1'), ('.', 'sym2'), ('.', 'sym3'),
              ('.', 'sym3', 'EF'), ('.', 'sym3', 'efg'),
              ('.', 'sym3', 'efg', 'ha')
          ]],
        [(os.curdir, '**', '*'),
         [('.', 'EF'), ('.', 'ZZZ'), (
             '.',
             'a',
         ), ('.', 'a', 'D'), ('.', 'a', 'bcd'), ('.', 'a', 'bcd', 'EF'),
          ('.', 'a', 'bcd', 'efg'),
          ('.', 'a', 'bcd', 'efg', 'ha'), ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
          ('.', 'aab'), ('.', 'aab', 'F')] if not can_symlink() else [
              (
                  '.',
                  'EF',
              ), ('.', 'ZZZ'), (
                  '.',
                  'a',
              ), ('.', 'a', 'D'), ('.', 'a', 'bcd'), ('.', 'a', 'bcd', 'EF'),
              ('.', 'a', 'bcd', 'efg'), ('.', 'a', 'bcd', 'efg', 'ha'),
              ('.', 'aaa'), ('.', 'aaa', 'zzzF'), ('.', 'aab'),
              ('.', 'aab', 'F'), ('.', 'sym1'), ('.', 'sym2'), ('.', 'sym3'),
              ('.', 'sym3', 'EF'), ('.', 'sym3', 'efg'),
              ('.', 'sym3', 'efg', 'ha')
          ]],
        [('**', ''),
         [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''), ('aaa', ''),
          ('aab', '')] if not can_symlink() else [('a', ''), ('a', 'bcd', ''),
                                                  ('a', 'bcd', 'efg', ''),
                                                  ('aaa', ''), ('aab', ''),
                                                  ('sym3', ''),
                                                  ('sym3', 'efg', '')]],
        [(os.curdir, '**', ''),
         [('.', ''), ('.', 'a', ''), ('.', 'a', 'bcd', ''),
          ('.', 'a', 'bcd', 'efg', ''), ('.', 'aaa', ''),
          ('.', 'aab',
           '')] if not can_symlink() else [('.', ''), ('.', 'a', ''),
                                           ('.', 'a', 'bcd', ''),
                                           ('.', 'a', 'bcd', 'efg', ''),
                                           ('.', 'aaa', ''), ('.', 'aab', ''),
                                           ('.', 'sym3', ''),
                                           ('.', 'sym3', 'efg', '')]],
        [('**', 'zz*F'), [('aaa', 'zzzF')]],
        [('**zz*F', ), []],
        [('**', 'EF'),
         [('a', 'bcd', 'EF'),
          ('EF', )] if not can_symlink() else [('a', 'bcd', 'EF'), ('EF', ),
                                               ('sym3', 'EF')]],
        Options(just_negative=True, default_negate='**'),
        [('a*', '**'), [] if not can_symlink() else [], glob.N],
        Options(just_negative=False, cwd_temp=False, absolute=False),

        # Test the file directly -- without magic.
        [[], [[]]]
    ]

    @classmethod
    def setup_fs(cls):
        """Setup file system."""

        cls.mktemp('a', 'D')
        cls.mktemp('aab', 'F')
        cls.mktemp('.aa', 'G')
        cls.mktemp('.bb', 'H')
        cls.mktemp('aaa', 'zzzF')
        cls.mktemp('ZZZ')
        cls.mktemp('EF')
        cls.mktemp('a', 'bcd', 'EF')
        cls.mktemp('a', 'bcd', 'efg', 'ha')
        cls.can_symlink = can_symlink()
        if cls.can_symlink:
            os.symlink(cls.norm('broken'), cls.norm('sym1'))
            os.symlink('broken', cls.norm('sym2'))
            os.symlink(os.path.join('a', 'bcd'), cls.norm('sym3'))

    @pytest.mark.parametrize("case", cases)
    def test_glob_cases(self, case):
        """Test glob cases."""

        self.eval_glob_cases(case)

    def test_negateall(self):
        """Negate applied to all files."""

        for file in glob.glob('!**/',
                              flags=glob.N | glob.NEGATEALL | glob.G,
                              root_dir=self.tempdir):
            self.assert_equal(os.path.isdir(file), False)

    def test_negateall_bytes(self):
        """Negate applied to all files."""

        for file in glob.glob(b'!**/',
                              flags=glob.N | glob.NEGATEALL | glob.G,
                              root_dir=os.fsencode(self.tempdir)):
            self.assert_equal(os.path.isdir(file), False)
示例#6
0
class TestGlobFilter:
    """Test matchtes against `globfilter`.

    Each list entry in `cases` is run through the `globsplit` and then `globfilter`.
    Entries are run through `globsplit` ensure it does not add any unintended side effects.

    There are a couple special types that can be inserted in the case list that can alter
    the behavior of the cases that follow.

    * Strings: These will be printed and then the next case will be processed.
    * Options: This object takes keyword parameters that are used to alter the next tests options:
        * skip_split: If set to `True`, this will cause the next tests to be skipped when we are processing
            cases with `globsplit`.
    * GlobFiles: This object takes a list of file paths and will set them as the current file list to
        compare against.  If `append` is set to `True`, it will extend the test's filelist instead of
        replacing.

    Each test case entry (list) is an array of up to 4 parameters (2 minimum).

    * Pattern
    * Expected result (filenames matched by the pattern)
    * Flags
    * List of files that will temporarily override the current main filelist just for this specific case.

    The default flags are: NEGATE | GLOBSTAR | EXTGLOB | BRACE. If any of these flags are provided in
    a test case, they will disable the default of the same name. All other flags will enable flags as expected.

    """

    cases = [
        Options(skip_split=False),
        GlobFiles([
            'a', 'b', 'c', 'd', 'abc', 'abd', 'abe', 'bb', 'bcd', 'ca', 'cb',
            'dd', 'de', 'bdir/', 'bdir/cfile'
        ]),

        # http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
        ['a*', ['a', 'abc', 'abd', 'abe']],
        ['X*', []],

        # isaacs: Slightly different than bash/sh/ksh
        # \\* is not un-escaped to literal "*" in a failed match,
        # but it does make it get treated as a literal star
        ['\\*', []],
        ['\\**', []],
        ['\\*\\*', []],
        ['b*/', ['bdir/']],
        ['c*', ['c', 'ca', 'cb']],
        [
            '**',
            [
                'a', 'b', 'c', 'd', 'abc', 'abd', 'abe', 'bb', 'bcd', 'ca',
                'cb', 'dd', 'de', 'bdir/', 'bdir/cfile'
            ]
        ],
        [r'\\.\\./*/', []],
        [r's/\\..*//', []],

        # legendary larry crashes bashes
        ['/^root:/{s/^[^:]*:[^:]*:\\([^:]*\\).*$/\\1/', []],
        ['/^root:/{s/^[^:]*:[^:]*:\\([^:]*\\).*$/\u0001/', []],

        # character classes
        ['[a-c]b*', ['abc', 'abd', 'abe', 'bb', 'cb']],
        [
            '[a-y]*[^c]',
            ['abd', 'abe', 'bb', 'bcd', 'bdir/', 'ca', 'cb', 'dd', 'de']
        ],
        ['a*[^c]', ['abd', 'abe']],
        GlobFiles(['a-b', 'aXb'], append=True),
        ['a[X-]b', ['a-b', 'aXb']],
        GlobFiles(['.x', '.y'], append=True),
        ['[^a-c]*', ['d', 'dd', 'de']],
        GlobFiles(['a*b/', 'a*b/ooo'], append=True),
        ['a\\*b/*', ['a*b/ooo']],
        ['a\\*?/*', ['a*b/ooo']],
        ['*\\\\!*', [], 0, ['echo !7']],
        ['*\\!*', ['echo !7'], 0, ['echo !7']],
        ['*.\\*', ['r.*'], 0, ['r.*']],
        ['a[b]c', ['abc']],
        ['a[\\b]c', ['abc']],
        ['a?c', ['abc']],
        ['a\\*c', [], 0, ['abc']],
        ['', [''], 0, ['']],

        # http://www.opensource.apple.com/source/bash/bash-23/bash/tests/glob-test
        GlobFiles(['man/', 'man/man1/', 'man/man1/bash.1'], append=True),
        ['*/man*/bash.*', ['man/man1/bash.1']],
        ['man/man1/bash.1', ['man/man1/bash.1']],
        ['a***c', ['abc'], 0, ['abc']],
        ['a*****?c', ['abc'], 0, ['abc']],
        ['?*****??', ['abc'], 0, ['abc']],
        ['*****??', ['abc'], 0, ['abc']],
        ['?*****?c', ['abc'], 0, ['abc']],
        ['?***?****c', ['abc'], 0, ['abc']],
        ['?***?****?', ['abc'], 0, ['abc']],
        ['?***?****', ['abc'], 0, ['abc']],
        ['*******c', ['abc'], 0, ['abc']],
        ['*******?', ['abc'], 0, ['abc']],
        ['a*cd**?**??k', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['a**?**cd**?**??k', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['a**?**cd**?**??k***', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['a**?**cd**?**??***k', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['a**?**cd**?**??***k**', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['a****c**?**??*****', ['abcdecdhjk'], 0, ['abcdecdhjk']],
        ['[-abc]', ['-'], 0, ['-']],
        ['[abc-]', ['-'], 0, ['-']],
        ['\\', ['\\'], 0, ['\\']],
        ['[\\\\]', (['\\'] if util.is_case_sensitive() else []), 0, ['\\']],
        ['[[]', ['['], 0, ['[']],
        ['[', ['['], 0, ['[']],
        ['[*', ['[abc'], 0, ['[abc']],

        # a right bracket shall lose its special meaning and\
        # represent itself in a bracket expression if it occurs\
        # first in the list.  -- POSIX.2 2.8.3.2
        ['[]]', [']'], 0, [']']],
        ['[]-]', [']'], 0, [']']],
        ['[a-\\z]', ['p'], 0, ['p']],
        ['??**********?****?', [], 0, ['abc']],
        ['??**********?****c', [], 0, ['abc']],
        ['?************c****?****', [], 0, ['abc']],
        ['*c*?**', [], 0, ['abc']],
        ['a*****c*?**', [], 0, ['abc']],
        ['a********???*******', [], 0, ['abc']],
        ['[]', [], 0, ['a']],
        ['[abc', [], 0, ['[']],

        # nocase tests
        ['XYZ', ['xYz'], glob.I, ['xYz', 'ABC', 'IjK']],
        ['ab*', ['ABC'], glob.I, ['xYz', 'ABC', 'IjK']],
        ['[ia]?[ck]', ['ABC', 'IjK'], glob.I, ['xYz', 'ABC', 'IjK']],

        # [ pattern, [matches], MM opts, files, TAP opts]
        # onestar/twostar
        ['{/*,*}', [], 0, ['/asdf/asdf/asdf']],
        ['{/?,*}', ['/a', 'bb'], 0, ['/a', '/b/b', '/a/b/c', 'bb']],

        # dots should not match unless requested
        ['**', ['a/b'], 0, ['a/b', 'a/.d', '.a/.d']],

        # .. and . can only match patterns starting with .,
        # even when options.dot is set.
        GlobFiles(['a/./b', 'a/../b', 'a/c/b', 'a/.d/b']),
        ['a/*/b', ['a/c/b', 'a/.d/b'], glob.D],
        ['a/.*/b', ['a/./b', 'a/../b', 'a/.d/b'], glob.D],
        ['a/*/b', ['a/c/b'], 0],
        ['a/.*/b', ['a/./b', 'a/../b', 'a/.d/b'], 0],

        # this also tests that changing the options needs
        # to change the cache key, even if the pattern is
        # the same!
        ['**', ['a/b', 'a/.d', '.a/.d'], glob.D, ['.a/.d', 'a/.d', 'a/b']],

        # paren sets cannot contain slashes
        ['*(a/b)', [], 0, ['a/b']],

        # brace sets trump all else.
        #
        # invalid glob pattern.  fails on bash4 and bsdglob.
        # however, in this implementation, it's easier just
        # to do the intuitive thing, and let brace-expansion
        # actually come before parsing any extglob patterns,
        # like the documentation seems to say.
        #
        # XXX: if anyone complains about this, either fix it
        # or tell them to grow up and stop complaining.
        #
        # bash/bsdglob says this:
        # , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
        # but we do this instead:
        ['*(a|{b),c)}', ['a', 'ab', 'ac'], 0, ['a', 'ab', 'ac', 'ad']],

        # test partial parsing in the presence of comment/negation chars
        # NOTE: We don't support these so they should work fine.
        ['[!a*', ['[!ab'], 0, ['[!ab', '[ab']],
        ['[#a*', ['[#ab'], 0, ['[#ab', '[ab']],

        # The following tests have `|` not included in things like +(...) etc.
        # We run these tests through normally and through glob.globsplit which splits
        # patterns on unenclosed `|`, so disable these few tests during split tests.
        Options(skip_split=True),
        # like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
        # NOTE: I don't know what the original test was doing because it was matching
        # something crazy. Multimatch regex expanded to escapes to like a 50.
        # I think ours expands them proper, so the original test has been altered.
        [
            '+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g',
            (['+(a|b\\|c\\|d\\|e\\\\|f\\\\|g']
             if util.is_case_sensitive() else []), 0,
            ['+(a|b\\|c\\|d\\|e\\\\|f\\\\|g', 'a', 'b\\c']
        ],

        # crazy nested {,,} and *(||) tests.
        GlobFiles([
            'a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'bc', 'cb', 'bc,d', 'c,db',
            'c,d', 'd)', '(b|c', '*(b|c', 'b|c', 'b|cc', 'cb|c', 'x(a|b|c)',
            'x(a|c)', '(a|b|c)', '(a|c)'
        ]),
        ['*(a|{b,c})', ['a', 'b', 'c', 'ab', 'ac']],
        ['{a,*(b|c,d)}', ['a', '(b|c', '*(b|c', 'd)']],
        # a
        # *(b|c)
        # *(b|d)
        ['{a,*(b|{c,d})}', ['a', 'b', 'bc', 'cb', 'c', 'd']],
        ['*(a|{b|c,c})', ['a', 'b', 'c', 'ab', 'ac', 'bc', 'cb']],

        # test various flag settings.
        ['*(a|{b|c,c})', ['x(a|b|c)', 'x(a|c)', '(a|b|c)', '(a|c)'], glob.E],
        Options(skip_split=False),
        # test extglob nested in extglob
        ['@(a@(c|d)|c@(b|,d))', ['ac', 'ad', 'cb', 'c,d']],

        # NOTE: We don't currently support the base match option
        # [
        #   'a?b',
        #   ['x/y/acb', 'acb/'],
        #   {matchBase: True},
        #   ['x/y/acb', 'acb/', 'acb/d/e', 'x/y/acb/d']
        # ],
        ['#*', ['#a', '#b'], 0, ['#a', '#b', 'c#d']],

        # begin channelling Boole and deMorgan...
        # NOTE: We changed these to `-` since our negation dosn't use `!`.
        # negation tests
        GlobFiles(['d', 'e', '!ab', '!abc', 'a!b', '\\!a']),

        # anything that is NOT a* matches.
        ['!a*', ['\\!a', 'd', 'e', '!ab', '!abc']],

        # anything that IS !a* matches.
        ['!a*', ['!ab', '!abc'], glob.N],

        # NOTE: We don't allow negating negation.
        # # anything that IS a* matches
        # ['!!a*', ['a!b']],

        # anything that is NOT !a* matches
        ['!\\!a*', ['a!b', 'd', 'e', '\\!a']],

        # negation nestled within a pattern
        GlobFiles([
            'foo.js', 'foo.bar', 'foo.js.js', 'blar.js', 'foo.', 'boo.js.boo'
        ]),
        # last one is tricky! * matches foo, . matches ., and 'js.js' != 'js'
        # copy bash 4.3 behavior on this.
        ['*.!(js)', ['foo.bar', 'foo.', 'boo.js.boo', 'foo.js.js']],

        # https://github.com/isaacs/minimatch/issues/5
        GlobFiles([
            'a/b/.x/c', 'a/b/.x/c/d', 'a/b/.x/c/d/e', 'a/b/.x', 'a/b/.x/',
            'a/.x/b', '.x', '.x/', '.x/a', '.x/a/b', 'a/.x/b/.x/c', '.x/.x'
        ]),
        [
            '**/.x/**',
            [
                '.x/', '.x/a', '.x/a/b', 'a/.x/b', 'a/b/.x/', 'a/b/.x/c',
                'a/b/.x/c/d', 'a/b/.x/c/d/e'
            ]
        ],

        # https://github.com/isaacs/minimatch/issues/59
        ['[z-a]', []],
        ['a/[2015-03-10T00:23:08.647Z]/z', []],
        ['[a-0][a-\u0100]', []],

        # Consecutive slashes.
        GlobFiles(['a/b/c', 'd/e/f', 'a/e/c']),
        ['*//e///*', ['d/e/f', 'a/e/c']],
        [r'*//\e///*', ['d/e/f', 'a/e/c']],

        # Backslash trailing cases
        GlobFiles(['a/b/c/', 'd/e/f/', 'a/e/c/']),
        [
            '**\\',
            [] if util.is_case_sensitive() else ['a/b/c/', 'd/e/f/', 'a/e/c/']
        ],

        # Invalid extglob groups
        GlobFiles(['@([test', '@([test\\', '@(test\\', 'test[']),
        [
            '@([test', ['@([test']
            if util.is_case_sensitive() else ['@([test', '@([test\\']
        ],
        ['@([test\\', ['@([test\\']],
        ['@(test\\', ['@(test\\']],
        ['@(test[)', ['test[']],

        # Inverse dot tests
        GlobFiles(['.', '..', '.abc', 'abc']),
        # We enable glob.N by default, so staring with `!`
        # is a problem without glob.M
        ['!(test)', ['abc'], glob.M],
        ['!(test)', ['.abc', 'abc'], glob.D | glob.M],
        ['.!(test)', ['.', '..', '.abc'], glob.M],
        ['.!(test)', ['.', '..', '.abc'], glob.D | glob.M],

        # Slash exclusion
        GlobFiles(['test/test', 'test\\/test']),
        ['test/test', ['test/test'], glob.F],
        ['test\\/test', ['test\\/test'], glob.F],
        ['@(test/test)', [], glob.F],
        [r'@(test\/test)', [], glob.F],
        ['test[/]test', [], glob.F],
        [r'test[\/]test', [], glob.F]
    ]

    @classmethod
    def setup_class(cls):
        """Setup the tests."""

        cls.files = []
        # The tests we scraped were written with this assumed.
        cls.flags = glob.NEGATE | glob.GLOBSTAR | glob.EXTGLOB | glob.BRACE
        cls.skip_split = False

    @staticmethod
    def norm_files(files, flags):
        """Normalize files."""

        flags = glob._flag_transform(flags)
        unix = _wcparse.is_unix_style(flags)

        return [(util.norm_slash(x) if not unix else x) for x in files]

    @staticmethod
    def assert_equal(a, b):
        """Assert equal."""

        assert a == b, "Comparison between objects yielded False."

    @classmethod
    def _filter(cls, case, split=False):
示例#7
0
class Testglob(_TestGlob):
    """
    Test glob.

    See `_TestGlob` class for more information in regards to test case format.
    """

    cases = [
        # Test literal.
        [('a',), [('a',)]],
        [('a', 'D'), [('a', 'D')]],
        [('aab',), [('aab',)]],
        [('zymurgy',), []],
        Options(absolute=True),
        [['*'], None],
        [[os.curdir, '*'], None],
        Options(absolute=False),

        # Glob one directory
        [('a*',), [('a',), ('aab',), ('aaa',)]],
        [('*a',), [('a',), ('aaa',)]],
        [('.*',), [('.',), ('..',), ('.aa',), ('.bb',)]],
        [('?aa',), [('aaa',)]],
        [('aa?',), [('aaa',), ('aab',)]],
        [('aa[ab]',), [('aaa',), ('aab',)]],
        [('*q',), []],

        # Glob inverse
        [
            ('a*',),
            [
                ('EF',), ('ZZZ',), ('',)
            ] if not can_symlink() else [
                ('EF',), ('ZZZ',), ('',), ('sym1',), ('sym3',), ('sym2',),
                ('sym3', 'efg'), ('sym3', 'efg', 'ha'), ('sym3', 'EF')
            ],
            glob.N
        ],

        # Test nested glob directory
        [
            ('a', 'bcd', 'E*'),
            [('a', 'bcd', 'EF')] if util.is_case_sensitive() else [('a', 'bcd', 'EF'), ('a', 'bcd', 'efg')]
        ],
        [('a', 'bcd', '*g'), [('a', 'bcd', 'efg')]],

        # Test glob directory names.
        [('*', 'D'), [('a', 'D')]],
        [('*', '*a'), []],
        [('a', '*', '*', '*a'), [('a', 'bcd', 'efg', 'ha')]],
        [('?a?', '*F'), [('aaa', 'zzzF'), ('aab', 'F')]],

        # Test glob magic in drive name.
        Options(absolute=True, skip=sys.platform != "win32"),
        [('*:',), []],
        [('?:',), []],
        [(r'\\\\?\\c:\\',), [('\\\\?\\c:\\',)]],
        [(r'\\\\*\\*\\',), []],
        Options(absolute=False, skip=False),

        Options(skip=not can_symlink()),
        # Test broken symlinks
        [('sym*',), [('sym1',), ('sym2',), ('sym3',)]],
        [('sym1',), [('sym1',)]],
        [('sym2',), [('sym2',)]],

        # Test glob symlinks.,
        [('sym3',), [('sym3',)]],
        [('sym3', '*'), [('sym3', 'EF'), ('sym3', 'efg')]],
        [('sym3', ''), [('sym3', '')]],
        [('*', '*F'), [('aaa', 'zzzF'), ('aab', 'F'), ('sym3', 'EF')]],
        Options(skip=False),

        # Test only directories
        [
            ('*', ''),
            [
                ('aab', ''), ('aaa', ''), ('a', '')
            ] if not can_symlink() else [
                ('aab', ''), ('aaa', ''), ('a', ''), ('sym3', '')
            ]
        ],
        Options(skip=util.is_case_sensitive()),
        [
            ('*\\',),
            [
                ('aab', ''), ('aaa', ''), ('a', '')
            ] if not can_symlink() else [
                ('aab', ''), ('aaa', ''), ('a', ''), ('sym3', '')
            ]
        ],
        Options(skip=False),

        # Test `extglob`.
        [('@(a|aa*(a|b))',), [('aab',), ('aaa',), ('a',)]],

        # Test sequences.
        [('[a]',), [('a',)]],
        [('[!b]',), [('a',)]],
        [('[^b]',), [('a',)]],
        [(r'@([\a]|\aaa)',), [('a',), ('aaa',)]],

        Options(absolute=True),
        # Test empty.
        [('',), []],
        Options(absolute=False),

        # Patterns ending with a slash shouldn't match non-directories.
        [('Z*Z', ''), []],
        [('ZZZ', ''), []],
        [('aa*', ''), [('aaa', ''), ('aab', '')]],

        # Test recursion.
        [
            ('**',),
            [
                ('',),
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F')
            ] if not can_symlink() else [
                ('',),
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F'),
                ('sym1',), ('sym2',),
                ('sym3',),
                ('sym3', 'EF'),
                ('sym3', 'efg'),
                ('sym3', 'efg', 'ha')
            ]
        ],
        [
            ('**', '**'),
            [
                ('',),
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F'),
            ] if not can_symlink() else [
                ('',),
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F'),
                ('sym1',), ('sym2',),
                ('sym3',),
                ('sym3', 'EF'),
                ('sym3', 'efg'),
                ('sym3', 'efg', 'ha')
            ]
        ],
        [
            ('.', '**'),
            [
                ('.', ''),
                ('.', 'EF'), ('.', 'ZZZ'),
                ('.', 'a'), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F'),
            ] if not can_symlink() else [
                ('.', ''),
                ('.', 'EF'), ('.', 'ZZZ'),
                ('.', 'a'), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F'),
                ('.', 'sym1'), ('.', 'sym2'),
                ('.', 'sym3'),
                ('.', 'sym3', 'EF'),
                ('.', 'sym3', 'efg'),
                ('.', 'sym3', 'efg', 'ha')
            ]
        ],
        [
            ('**', ''),
            # Directories
            [
                ('',),
                ('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
                ('aaa', ''), ('aab', '')
            ] if not can_symlink() else [
                ('',),
                ('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
                ('aaa', ''), ('aab', ''),
                ('sym3', ''), ('sym3', 'efg', '')
            ]
        ],
        [
            ('a', '**'),
            [('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha')]
        ],
        [('a**',), [('a',), ('aaa',), ('aab',)]],
        [
            ('**', 'EF'),
            [('a', 'bcd', 'EF'), ('EF',)] if not can_symlink() else [('a', 'bcd', 'EF'), ('EF',), ('sym3', 'EF')]
        ],
        [
            ('**', '*F'),
            [
                ('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'), ('EF',)
            ] if not can_symlink() else [
                ('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'), ('EF',), ('sym3', 'EF')
            ]
        ],
        [('**', '*F', ''), []],
        [('**', 'bcd', '*'), [('a', 'bcd', 'EF'), ('a', 'bcd', 'efg')]],
        [('a', '**', 'bcd'), [('a', 'bcd')]],
        Options(cwd_temp=True, absolute=True),
        [
            ('**',),
            [
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F')
            ] if not can_symlink() else [
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F'),
                ('sym1',), ('sym2',),
                ('sym3',),
                ('sym3', 'EF'),
                ('sym3', 'efg'),
                ('sym3', 'efg', 'ha')
            ]
        ],
        [
            ('**', '*'),
            [
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F')
            ] if not can_symlink() else [
                ('EF',), ('ZZZ',),
                ('a',), ('a', 'D'),
                ('a', 'bcd'),
                ('a', 'bcd', 'EF'),
                ('a', 'bcd', 'efg'),
                ('a', 'bcd', 'efg', 'ha'),
                ('aaa',), ('aaa', 'zzzF'),
                ('aab',), ('aab', 'F'),
                ('sym1',), ('sym2',),
                ('sym3',),
                ('sym3', 'EF'),
                ('sym3', 'efg'),
                ('sym3', 'efg', 'ha')
            ]
        ],
        [
            (os.curdir, '**'),
            [
                ('.', ''),
                ('.', 'EF'), ('.', 'ZZZ'),
                ('.', 'a',), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F')
            ] if not can_symlink() else [
                ('.', ''),
                ('.', 'EF',), ('.', 'ZZZ'),
                ('.', 'a',), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F'),
                ('.', 'sym1'), ('.', 'sym2'),
                ('.', 'sym3'),
                ('.', 'sym3', 'EF'),
                ('.', 'sym3', 'efg'),
                ('.', 'sym3', 'efg', 'ha')
            ]
        ],
        [
            (os.curdir, '**', '*'),
            [
                ('.', 'EF'), ('.', 'ZZZ'),
                ('.', 'a',), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F')
            ] if not can_symlink() else [
                ('.', 'EF',), ('.', 'ZZZ'),
                ('.', 'a',), ('.', 'a', 'D'),
                ('.', 'a', 'bcd'),
                ('.', 'a', 'bcd', 'EF'),
                ('.', 'a', 'bcd', 'efg'),
                ('.', 'a', 'bcd', 'efg', 'ha'),
                ('.', 'aaa'), ('.', 'aaa', 'zzzF'),
                ('.', 'aab'), ('.', 'aab', 'F'),
                ('.', 'sym1'), ('.', 'sym2'),
                ('.', 'sym3'),
                ('.', 'sym3', 'EF'),
                ('.', 'sym3', 'efg'),
                ('.', 'sym3', 'efg', 'ha')
            ]
        ],
        [
            ('**', ''),
            [
                ('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
                ('aaa', ''), ('aab', '')
            ] if not can_symlink() else [
                ('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
                ('aaa', ''), ('aab', ''),
                ('sym3', ''), ('sym3', 'efg', '')
            ]
        ],
        [
            (os.curdir, '**', ''),
            [
                ('.', ''),
                ('.', 'a', ''), ('.', 'a', 'bcd', ''), ('.', 'a', 'bcd', 'efg', ''),
                ('.', 'aaa', ''), ('.', 'aab', '')
            ] if not can_symlink() else [
                ('.', ''),
                ('.', 'a', ''), ('.', 'a', 'bcd', ''), ('.', 'a', 'bcd', 'efg', ''),
                ('.', 'aaa', ''), ('.', 'aab', ''),
                ('.', 'sym3', ''), ('.', 'sym3', 'efg', '')
            ]
        ],
        [('**', 'zz*F'), [('aaa', 'zzzF')]],
        [('**zz*F',), []],
        [
            ('**', 'EF'),
            [('a', 'bcd', 'EF'), ('EF',)] if not can_symlink() else [('a', 'bcd', 'EF'), ('EF',), ('sym3', 'EF')]
        ],
        Options(just_negative=True),
        [
            ('a*',),
            [
                ('EF',), ('ZZZ',)
            ] if not can_symlink() else [
                ('EF',), ('ZZZ',),
                ('sym1',), ('sym3',), ('sym2',), ('sym3', 'efg'), ('sym3', 'efg', 'ha'), ('sym3', 'EF')
            ],
            glob.N
        ],
        Options(just_negative=False, cwd_temp=False, absolute=False),

        # Test the file directly -- without magic.
        [[], [[]]]
    ]

    @classmethod
    def setup_fs(cls):
        """Setup file system."""

        cls.mktemp('a', 'D')
        cls.mktemp('aab', 'F')
        cls.mktemp('.aa', 'G')
        cls.mktemp('.bb', 'H')
        cls.mktemp('aaa', 'zzzF')
        cls.mktemp('ZZZ')
        cls.mktemp('EF')
        cls.mktemp('a', 'bcd', 'EF')
        cls.mktemp('a', 'bcd', 'efg', 'ha')
        cls.can_symlink = can_symlink()
        if cls.can_symlink:
            os.symlink(cls.norm('broken'), cls.norm('sym1'))
            os.symlink('broken', cls.norm('sym2'))
            os.symlink(os.path.join('a', 'bcd'), cls.norm('sym3'))

    @pytest.mark.parametrize("case", cases)
    def test_glob_cases(self, case):
        """Test glob cases."""

        self.eval_glob_cases(case)