lilith-file-watcher-daemon/tests/test_patterns.py
2026-01-21 12:48:42 -08:00

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