test(classifier): ✅ add tests that assert that fixtures must exist with their associated existing pattern

a log line cannot match multiple patterns. Again a fixture can only exist in codebase if its associated pattern also exists.
This commit is contained in:
2026-08-25 12:39:50 +02:00
parent 476b69d26f
commit 59a04c6761
10 changed files with 278 additions and 36 deletions
+41 -5
View File
@@ -11,19 +11,28 @@ ORIGINAL_LOGS_DIR = FIXTURE_PATH / "original_logs"
def _pattern_name_to_filename(name: str) -> str:
"""STORE_CODE_NOT_FOUND → CR_store_code_not_found.txt"""
"""
Returns the fixture corresponding to the error code name
"""
return f"CR_{name.lower()}.txt"
def _read_fixture(path: Path) -> str:
"""Lit un fichier de fixture avec fallback Windows-1252."""
"""
Read a file with fallback Windows-1252.
"""
try:
return path.read_text(encoding="utf-8")
contenu = path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="windows-1252")
if "\ufffd" not in contenu:
return contenu
return path.read_text(encoding="windows-1252")
@pytest.mark.parametrize("name, pattern", N2_PATTERNS.items())
def test_pattern_matches_fixture(name, pattern):
"""Chaque pattern N2 matche au moins une ligne de son fichier de fixture."""
"""
Assert each N2 pattern must match at least one line in its fixture.
"""
fixture = ORIGINAL_LOGS_DIR / _pattern_name_to_filename(name)
if not fixture.exists():
@@ -49,4 +58,31 @@ def test_pattern_matches_fixture(name, pattern):
f"{name} : no match in file {fixture.name}\n"
f"pattern: {pattern}"
)
def test_patterns_do_not_overlap():
"""
Assert that a log line can match only one N2 pattern.
"""
fixtures_dir = FIXTURE_PATH
for fixture in fixtures_dir.glob("CR_*.txt"):
line_list = [line for line in _read_fixture(fixture).splitlines() if line.strip()]
for line in line_list:
matching = [
name for name, raw in N2_PATTERNS.items()
if re.compile(raw).search(line)
]
assert len(matching) <= 1, (
f"Chevauchement détecté sur {fixture.name} : "
f"{matching} match line : {line[:80]}"
)
def test_no_orphan_fixtures():
"""
Assert that a fixture exist only if its associated pattern exists.
Aucun fichier de fixture ne doit exister sans pattern associé.
"""
expected = {f"CR_{name.lower()}.txt" for name in N2_PATTERNS}
actual = {f.name for f in FIXTURE_PATH.glob("CR_*.txt")}
orphan = actual - expected
assert not orphan, f"Fixtures orphelines (sans pattern) : {sorted(orphan)}"