37 lines
1.4 KiB
Python
37 lines
1.4 KiB
Python
from fnmatch import fnmatch
|
|
|
|
from .paths import is_excluded_path, iter_source_files
|
|
|
|
CS_SUFFIXES = frozenset({".cs"})
|
|
|
|
|
|
def is_test_file(path, config):
|
|
return any(path.is_relative_to(root) for root in config.test_roots)
|
|
|
|
|
|
def evaluate_paths(paths, root, config):
|
|
root = root.resolve()
|
|
candidates = None
|
|
for raw in paths:
|
|
path = raw.resolve()
|
|
if not path.is_relative_to(root):
|
|
return f"TDD GUARD: '{path}' is outside the repository"
|
|
if path.suffix.lower() not in CS_SUFFIXES:
|
|
continue
|
|
if is_excluded_path(path, root, config.exclude) or is_test_file(path, config):
|
|
continue
|
|
if candidates is None:
|
|
candidates = tuple(p for p in iter_source_files(root) if p.suffix.lower() == ".cs")
|
|
roots = (*config.test_roots, path.parent / "tests", path.parent / "test")
|
|
names = tuple(pattern.format(stem=path.stem) for pattern in config.test_patterns)
|
|
found = any(
|
|
candidate.is_relative_to(test_root)
|
|
and any(fnmatch(candidate.name if "/" not in pattern else candidate.relative_to(test_root).as_posix(), pattern)
|
|
for pattern in names)
|
|
for test_root in roots for candidate in candidates
|
|
)
|
|
if not found:
|
|
return (f"TDD GUARD: '{path.name}' requires an existing test such as '{names[0]}'. "
|
|
"Add the test in a configured test root first.")
|
|
return None
|