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)
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))
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)
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)
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)
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):
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)