124 lines
4.2 KiB
Python
124 lines
4.2 KiB
Python
"""Tests for pattern matching utilities."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from lilith_file_watcher_daemon.patterns import PatternMatcher, filter_paths
|
|
|
|
|
|
class TestPatternMatcher:
|
|
"""Tests for PatternMatcher."""
|
|
|
|
def test_empty_patterns_match_all(self):
|
|
"""Test that empty patterns match everything."""
|
|
matcher = PatternMatcher([])
|
|
assert matcher.matches(Path("/any/path/file.txt"))
|
|
assert matcher.matches(Path("/another/path/file.py"))
|
|
|
|
def test_simple_wildcard(self):
|
|
"""Test simple wildcard patterns."""
|
|
matcher = PatternMatcher(["*.txt"])
|
|
assert matcher.matches(Path("file.txt"))
|
|
# *.txt only matches files in root, not subdirectories
|
|
assert not matcher.matches(Path("dir/file.txt"))
|
|
assert not matcher.matches(Path("/path/to/file.txt"))
|
|
assert not matcher.matches(Path("file.py"))
|
|
|
|
def test_recursive_wildcard(self):
|
|
"""Test recursive wildcard patterns."""
|
|
matcher = PatternMatcher(["**/*.py"])
|
|
assert matcher.matches(Path("file.py"))
|
|
assert matcher.matches(Path("dir/file.py"))
|
|
assert matcher.matches(Path("deep/nested/dir/file.py"))
|
|
assert not matcher.matches(Path("file.txt"))
|
|
|
|
def test_multiple_patterns(self):
|
|
"""Test multiple patterns (OR logic)."""
|
|
matcher = PatternMatcher(["*.py", "*.json"])
|
|
assert matcher.matches(Path("file.py"))
|
|
assert matcher.matches(Path("config.json"))
|
|
assert not matcher.matches(Path("file.txt"))
|
|
|
|
def test_specific_directory(self):
|
|
"""Test matching specific directory."""
|
|
matcher = PatternMatcher(["/tmp/**/*.txt"])
|
|
assert matcher.matches(Path("/tmp/file.txt"))
|
|
assert matcher.matches(Path("/tmp/subdir/file.txt"))
|
|
assert not matcher.matches(Path("/other/file.txt"))
|
|
|
|
def test_question_mark_wildcard(self):
|
|
"""Test single character wildcard."""
|
|
matcher = PatternMatcher(["file?.txt"])
|
|
assert matcher.matches(Path("file1.txt"))
|
|
assert matcher.matches(Path("fileA.txt"))
|
|
assert not matcher.matches(Path("file12.txt"))
|
|
assert not matcher.matches(Path("file.txt"))
|
|
|
|
def test_complex_patterns(self):
|
|
"""Test complex combined patterns."""
|
|
matcher = PatternMatcher([
|
|
"**/*.py",
|
|
"**/*.json",
|
|
"**/config/*.toml",
|
|
])
|
|
assert matcher.matches(Path("src/main.py"))
|
|
assert matcher.matches(Path("data.json"))
|
|
assert matcher.matches(Path("app/config/settings.toml"))
|
|
assert not matcher.matches(Path("README.md"))
|
|
|
|
|
|
class TestFilterPaths:
|
|
"""Tests for filter_paths function."""
|
|
|
|
def test_filter_with_patterns(self):
|
|
"""Test filtering paths with patterns."""
|
|
paths = [
|
|
Path("file1.py"),
|
|
Path("file2.txt"),
|
|
Path("dir/file3.py"),
|
|
Path("dir/file4.json"),
|
|
]
|
|
# Use ** to match files in subdirectories too
|
|
patterns = ["**/*.py", "**/*.json"]
|
|
filtered = filter_paths(paths, patterns)
|
|
|
|
assert Path("file1.py") in filtered
|
|
assert Path("dir/file3.py") in filtered
|
|
assert Path("dir/file4.json") in filtered
|
|
assert Path("file2.txt") not in filtered
|
|
|
|
def test_filter_with_empty_patterns(self):
|
|
"""Test that empty patterns return all paths."""
|
|
paths = [
|
|
Path("file1.py"),
|
|
Path("file2.txt"),
|
|
]
|
|
filtered = filter_paths(paths, [])
|
|
|
|
assert filtered == paths
|
|
|
|
def test_filter_no_matches(self):
|
|
"""Test filtering when no paths match."""
|
|
paths = [
|
|
Path("file1.txt"),
|
|
Path("file2.md"),
|
|
]
|
|
patterns = ["*.py"]
|
|
filtered = filter_paths(paths, patterns)
|
|
|
|
assert filtered == []
|
|
|
|
def test_filter_recursive_patterns(self):
|
|
"""Test filtering with recursive patterns."""
|
|
paths = [
|
|
Path("src/main.py"),
|
|
Path("tests/test_main.py"),
|
|
Path("README.md"),
|
|
Path("deep/nested/file.py"),
|
|
]
|
|
patterns = ["**/*.py"]
|
|
filtered = filter_paths(paths, patterns)
|
|
|
|
assert len(filtered) == 3
|
|
assert Path("README.md") not in filtered
|