diff --git a/IPython/utils/tests/test_path.py b/IPython/utils/tests/test_path.py index 6f15d57..b281995 100644 --- a/IPython/utils/tests/test_path.py +++ b/IPython/utils/tests/test_path.py @@ -19,6 +19,7 @@ import shutil import sys import tempfile from io import StringIO +from contextlib import contextmanager from os.path import join, abspath, split @@ -447,41 +448,70 @@ def test_unicode_in_filename(): str(ex) -def test_shellglob(): - """Test glob expansion for %run magic.""" - filenames_start_with_a = map('a{0}'.format, range(3)) - filenames_end_with_b = map('{0}b'.format, range(3)) - filenames = filenames_start_with_a + filenames_end_with_b +class TestShellGlob(object): - with TemporaryDirectory() as td: - save = os.getcwdu() - try: - os.chdir(td) + @classmethod + def setUpClass(cls): + cls.filenames_start_with_a = map('a{0}'.format, range(3)) + cls.filenames_end_with_b = map('{0}b'.format, range(3)) + cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b + cls.tempdir = TemporaryDirectory() + td = cls.tempdir.name + with cls.in_tempdir(): # Create empty files - for fname in filenames: + for fname in cls.filenames: open(os.path.join(td, fname), 'w').close() - def assert_match(patterns, matches): - # glob returns unordered list. that's why sorted is required. - nt.assert_equals(sorted(path.shellglob(patterns)), - sorted(matches)) - - assert_match(['*'], filenames) - assert_match(['a*'], filenames_start_with_a) - assert_match(['*c'], ['*c']) - assert_match(['*', 'a*', '*b', '*c'], - filenames - + filenames_start_with_a - + filenames_end_with_b - + ['*c']) - - assert_match([r'\*'], ['*']) - assert_match([r'a\*', 'a*'], ['a*'] + filenames_start_with_a) - assert_match(['a[012]'], filenames_start_with_a) - assert_match([r'a\[012]'], ['a[012]']) - finally: - os.chdir(save) + @classmethod + def tearDownClass(cls): + cls.tempdir.cleanup() + + @classmethod + @contextmanager + def in_tempdir(cls): + save = os.getcwdu() + os.chdir(cls.tempdir.name) + yield + os.chdir(save) + + def check_match(self, patterns, matches): + with self.in_tempdir(): + # glob returns unordered list. that's why sorted is required. + nt.assert_equals(sorted(path.shellglob(patterns)), + sorted(matches)) + + def common_cases(self): + return [ + (['*'], self.filenames), + (['a*'], self.filenames_start_with_a), + (['*c'], ['*c']), + (['*', 'a*', '*b', '*c'], self.filenames + + self.filenames_start_with_a + + self.filenames_end_with_b + + ['*c']), + (['a[012]'], self.filenames_start_with_a), + ] + + @skip_win32 + def test_match_posix(self): + for (patterns, matches) in self.common_cases() + [ + ([r'\*'], ['*']), + ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a), + ([r'a\[012]'], ['a[012]']), + ]: + yield (self.check_match, patterns, matches) + + @skip_if_not_win32 + def test_match_windows(self): + for (patterns, matches) in self.common_cases() + [ + # In windows, backslash is interpreted as path + # separator. Therefore, you can't escape glob + # using it. + ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a), + ([r'a\[012]'], [r'a\[012]']), + ]: + yield (self.check_match, patterns, matches) def test_unescape_glob():