mirror of https://github.com/buildinspace/peru.git
101 lines
3.7 KiB
Python
101 lines
3.7 KiB
Python
import collections
|
|
import re
|
|
|
|
import peru.glob as glob
|
|
import shared
|
|
|
|
|
|
class GlobTest(shared.PeruTest):
|
|
def test_split_on_stars_interpreting_backslashes(self):
|
|
cases = [
|
|
('', ['']),
|
|
('*', ['', '']),
|
|
('abc', ['abc']),
|
|
('abc\\', ['abc\\']),
|
|
('abc\\n', ['abc\\n']),
|
|
('abc\\\\', ['abc\\']),
|
|
('ab*c', ['ab', 'c']),
|
|
('*abc*', ['', 'abc', '']),
|
|
(r'a\*bc', ['a*bc']),
|
|
(r'a\\*bc', ['a\\', 'bc']),
|
|
(r'a\\\*bc', ['a\\*bc']),
|
|
(r'a\\\\*bc', ['a\\\\', 'bc']),
|
|
]
|
|
for input, output in cases:
|
|
self.assertEqual(
|
|
output,
|
|
glob.split_on_stars_interpreting_backslashes(input),
|
|
'Failed split for input {}'.format(input))
|
|
|
|
def test_glob_to_path_regex(self):
|
|
Case = collections.namedtuple('Case', ['glob', 'matches', 'excludes'])
|
|
cases = [
|
|
Case(glob='a/b/c',
|
|
matches=['a/b/c'],
|
|
excludes=['a/b', 'a/b/c/', '/a/b/c', 'a/b/c/d']),
|
|
# * should be able to match nothing.
|
|
Case(glob='a/*b/c',
|
|
matches=['a/b/c', 'a/xb/c'],
|
|
excludes=['a/x/c', 'a/c', 'a//c']),
|
|
# But * by itself should never match an empty path component.
|
|
Case(glob='a/*/c',
|
|
matches=['a/b/c', 'a/boooo/c', 'a/*/c'],
|
|
excludes=['a/c', 'a/b/d/c', 'a//c']),
|
|
# Similarly, ** does not match empty path components. It's tempting
|
|
# to allow this, but we never want '**/c' to match '/c'.
|
|
Case(glob='a/**/c',
|
|
matches=['a/b/c', 'a/d/e/f/g/c', 'a/c'],
|
|
excludes=['a/b/c/d', 'x/a/c', 'a//c']),
|
|
Case(glob='a/**/**/c',
|
|
matches=['a/b/c', 'a/d/e/f/g/c', 'a/c'],
|
|
excludes=['a/b/c/d', 'x/a/c', 'a//c']),
|
|
Case(glob='**/c',
|
|
matches=['a/b/c', 'c'],
|
|
excludes=['/c', 'c/d']),
|
|
Case(glob='**/*/c',
|
|
matches=['a/b/c', 'a/c'],
|
|
excludes=['c', '/c']),
|
|
# Leading slashes should be preserved if present.
|
|
Case(glob='/a',
|
|
matches=['/a'],
|
|
excludes=['a']),
|
|
Case(glob='/**/c',
|
|
matches=['/a/b/c', '/c'],
|
|
excludes=['c', 'a/b/c']),
|
|
# Make sure special characters are escaped properly.
|
|
Case(glob='a|b',
|
|
matches=['a|b'],
|
|
excludes=['a', 'b']),
|
|
# Test escaped * characters.
|
|
Case(glob='a\\*',
|
|
matches=['a*'],
|
|
excludes=['a', 'aa']),
|
|
]
|
|
for case in cases:
|
|
regex = glob.glob_to_path_regex(case.glob)
|
|
for m in case.matches:
|
|
assert re.match(regex, m), \
|
|
'Glob {} (regex: {} ) should match path {}'.format(
|
|
case.glob, regex, m)
|
|
for e in case.excludes:
|
|
assert not re.match(regex, e), \
|
|
'Glob {} (regex: {} ) should not match path {}'.format(
|
|
case.glob, regex, e)
|
|
|
|
def test_bad_globs(self):
|
|
bad_globs = [
|
|
'**',
|
|
'a/b/**',
|
|
'a/b/**/',
|
|
'a/b/**c/d',
|
|
]
|
|
for bad_glob in bad_globs:
|
|
with self.assertRaises(glob.GlobError):
|
|
glob.glob_to_path_regex(bad_glob)
|
|
|
|
def test_unglobbed_prefix(self):
|
|
assert glob.unglobbed_prefix('a/b/c*/d') == 'a/b'
|
|
assert glob.unglobbed_prefix('a/b/**/d') == 'a/b'
|
|
assert glob.unglobbed_prefix('/a/b/*/d') == '/a/b'
|
|
assert glob.unglobbed_prefix('*/a/b') == ''
|