Simplify pattern tests

- Stop using “adjust_pattern” and “exclude_path” as they're utility
  functions not relevant to testing pattern classes
- Cover a few more cases, especially with more than one path separator
  and relative paths
- At least one dedicated test function for each pattern style as opposed
  to a single, big test mixing styles
- Use positive instead of negative matching (i.e. the expected list of
  resulting items is a list of items matching a pattern)
This commit is contained in:
Michael Hanselmann 2016-01-15 22:11:47 +01:00
parent 560a61b634
commit c1feb4b532
1 changed files with 81 additions and 46 deletions

View File

@ -9,7 +9,7 @@ import sys
import msgpack import msgpack
import msgpack.fallback import msgpack.fallback
from ..helpers import adjust_patterns, exclude_path, Location, format_file_size, format_timedelta, PathPrefixPattern, FnmatchPattern, make_path_safe, \ from ..helpers import exclude_path, Location, format_file_size, format_timedelta, PathPrefixPattern, FnmatchPattern, make_path_safe, \
prune_within, prune_split, get_cache_dir, Statistics, is_slow_msgpack, yes, RegexPattern, \ prune_within, prune_split, get_cache_dir, Statistics, is_slow_msgpack, yes, RegexPattern, \
StableDict, int_to_bigint, bigint_to_int, parse_timestamp, CompressionSpec, ChunkerParams, \ StableDict, int_to_bigint, bigint_to_int, parse_timestamp, CompressionSpec, ChunkerParams, \
ProgressIndicatorPercent, ProgressIndicatorEndless, load_excludes, parse_pattern ProgressIndicatorPercent, ProgressIndicatorEndless, load_excludes, parse_pattern
@ -160,70 +160,105 @@ class FormatTimedeltaTestCase(BaseTestCase):
) )
def check_patterns(files, paths, excludes, expected): def check_patterns(files, pattern, expected):
"""Utility for testing exclusion patterns. """Utility for testing patterns.
""" """
patterns = adjust_patterns(paths, excludes) assert all([f == os.path.normpath(f) for f in files]), \
included = [path for path in files if not exclude_path(path, patterns)] "Pattern matchers expect normalized input paths"
assert included == (files if expected is None else expected) matched = [f for f in files if pattern.match(f)]
assert matched == (files if expected is None else expected)
@pytest.mark.parametrize("paths, excludes, expected", [ @pytest.mark.parametrize("pattern, expected", [
# "None" means all files, i.e. none excluded # "None" means all files, i.e. all match the given pattern
([], [], None), ("/", None),
(['/'], [], None), ("/./", None),
(['/'], ['/h'], None), ("", []),
(['/'], ['/home'], ['/etc/passwd', '/etc/hosts', '/var/log/messages', '/var/log/dmesg']), ("/home/u", []),
(['/'], ['/home/'], ['/etc/passwd', '/etc/hosts', '/home', '/var/log/messages', '/var/log/dmesg']), ("/home/user", ["/home/user/.profile", "/home/user/.bashrc"]),
(['/home/u'], [], []), ("/etc", ["/etc/server/config", "/etc/server/hosts"]),
(['/', '/home', '/etc/hosts'], ['/'], []), ("///etc//////", ["/etc/server/config", "/etc/server/hosts"]),
(['/home/'], ['/home/user2'], ['/home', '/home/user/.profile', '/home/user/.bashrc']), ("/./home//..//home/user2", ["/home/user2/.profile", "/home/user2/public_html/index.html"]),
(['/'], ['*.profile', '/var/log'], ("/srv", ["/srv/messages", "/srv/dmesg"]),
['/etc/passwd', '/etc/hosts', '/home', '/home/user/.bashrc', '/home/user2/public_html/index.html']),
(['/'], ['/home/*/public_html', '*.profile', '*/log/*'],
['/etc/passwd', '/etc/hosts', '/home', '/home/user/.bashrc']),
(['/etc/', '/var'], ['dmesg'], ['/etc/passwd', '/etc/hosts', '/var/log/messages', '/var/log/dmesg']),
]) ])
def test_patterns(paths, excludes, expected): def test_patterns_prefix(pattern, expected):
files = [ files = [
'/etc/passwd', '/etc/hosts', '/home', "/etc/server/config", "/etc/server/hosts", "/home", "/home/user/.profile", "/home/user/.bashrc",
'/home/user/.profile', '/home/user/.bashrc', "/home/user2/.profile", "/home/user2/public_html/index.html", "/srv/messages", "/srv/dmesg",
'/home/user2/.profile', '/home/user2/public_html/index.html',
'/var/log/messages', '/var/log/dmesg',
] ]
check_patterns(files, paths, [FnmatchPattern(p) for p in excludes], expected) check_patterns(files, PathPrefixPattern(pattern), expected)
@pytest.mark.parametrize("paths, excludes, expected", [ @pytest.mark.parametrize("pattern, expected", [
# "None" means all files, i.e. none excluded # "None" means all files, i.e. all match the given pattern
([], [], None), ("", []),
(['/'], [], None), ("foo", []),
(['/'], ['.*'], []), ("relative", ["relative/path1", "relative/two"]),
(['/'], ['^/'], []), ("more", ["more/relative"]),
(['/'], ['^abc$'], None),
(['/'], ['^(?!/home/)'],
['/home/user/.profile', '/home/user/.bashrc', '/home/user2/.profile',
'/home/user2/public_html/index.html']),
]) ])
def test_patterns_regex(paths, excludes, expected): def test_patterns_prefix_relative(pattern, expected):
files = ["relative/path1", "relative/two", "more/relative"]
check_patterns(files, PathPrefixPattern(pattern), expected)
@pytest.mark.parametrize("pattern, expected", [
# "None" means all files, i.e. all match the given pattern
("/*", None),
("/./*", None),
("*", None),
("*/*", None),
("*///*", None),
("/home/u", []),
("/home/*",
["/home/user/.profile", "/home/user/.bashrc", "/home/user2/.profile", "/home/user2/public_html/index.html",
"/home/foo/.thumbnails", "/home/foo/bar/.thumbnails"]),
("/home/user/*", ["/home/user/.profile", "/home/user/.bashrc"]),
("/etc/*", ["/etc/server/config", "/etc/server/hosts"]),
("*/.pr????e", ["/home/user/.profile", "/home/user2/.profile"]),
("///etc//////*", ["/etc/server/config", "/etc/server/hosts"]),
("/./home//..//home/user2/*", ["/home/user2/.profile", "/home/user2/public_html/index.html"]),
("/srv*", ["/srv/messages", "/srv/dmesg"]),
("/home/*/.thumbnails", ["/home/foo/.thumbnails", "/home/foo/bar/.thumbnails"]),
])
def test_patterns_fnmatch(pattern, expected):
files = [
"/etc/server/config", "/etc/server/hosts", "/home", "/home/user/.profile", "/home/user/.bashrc",
"/home/user2/.profile", "/home/user2/public_html/index.html", "/srv/messages", "/srv/dmesg",
"/home/foo/.thumbnails", "/home/foo/bar/.thumbnails",
]
check_patterns(files, FnmatchPattern(pattern), expected)
@pytest.mark.parametrize("pattern, expected", [
# "None" means all files, i.e. all match the given pattern
("", None),
(".*", None),
("^/", None),
("^abc$", []),
("^[^/]", []),
("^(?!/srv|/foo|/opt)",
["/home", "/home/user/.profile", "/home/user/.bashrc", "/home/user2/.profile",
"/home/user2/public_html/index.html", "/home/foo/.thumbnails", "/home/foo/bar/.thumbnails",]),
])
def test_patterns_regex(pattern, expected):
files = [ files = [
'/srv/data', '/foo/bar', '/home', '/srv/data', '/foo/bar', '/home',
'/home/user/.profile', '/home/user/.bashrc', '/home/user/.profile', '/home/user/.bashrc',
'/home/user2/.profile', '/home/user2/public_html/index.html', '/home/user2/.profile', '/home/user2/public_html/index.html',
'/opt/log/messages.txt', '/opt/log/dmesg.txt', '/opt/log/messages.txt', '/opt/log/dmesg.txt',
"/home/foo/.thumbnails", "/home/foo/bar/.thumbnails",
] ]
patterns = [] obj = RegexPattern(pattern)
assert str(obj) == pattern
assert obj.pattern == pattern
for i in excludes: check_patterns(files, obj, expected)
pat = RegexPattern(i)
assert str(pat) == i
assert pat.pattern == i
patterns.append(pat)
check_patterns(files, paths, patterns, expected)
def test_regex_pattern(): def test_regex_pattern():