test(#106 Folge): Safety-Net fuer 16 Stub-Parser
81 Tests pruefen pro Stub: - Modul ist importierbar - Docstring enthaelt Recherche-Findings + Issue-Link - parse_protocol() raised NotImplementedError mit informativer Message - Stub ist NICHT in PROTOKOLL_PARSERS-Registry (sonst wuerde Cron crashen) - Wenn parse_protocol kein NotImplementedError mehr wirft (also echt implementiert), MUSS es in PROTOKOLL_PARSERS sein — sonst Test rot Damit ist sichergestellt: sobald ein Stub durch echten Parser ersetzt wird, kann der Implementer nicht vergessen, gleichzeitig den Eintrag in der Registry zu setzen. 868 Tests gruen, 787 → 868 (+81).
This commit is contained in:
parent
c0692b3078
commit
62fd25fbcb
111
tests/test_protokoll_parsers_stubs.py
Normal file
111
tests/test_protokoll_parsers_stubs.py
Normal file
@ -0,0 +1,111 @@
|
||||
"""Tests fuer die Phase-2-Stub-Parser (#106 Folge / #148-#163).
|
||||
|
||||
Pro BL ein Modul `app/protokoll_parsers/<bl>.py`, das:
|
||||
1. importierbar ist (Recherche-Findings im Docstring)
|
||||
2. ``parse_protocol(...)`` raised ``NotImplementedError`` mit Issue-Verweis
|
||||
3. **NICHT** in ``PROTOKOLL_PARSERS``-Registry registriert ist (sonst wuerde
|
||||
der Auto-Ingest-Cron versuchen, sie zu nutzen und mit NotImplementedError
|
||||
abbrechen)
|
||||
|
||||
Diese Tests sind das Safety-Net: sobald ein Stub durch einen echten Parser
|
||||
ersetzt wird, MUSS gleichzeitig der Eintrag in PROTOKOLL_PARSERS gesetzt
|
||||
werden — sonst greift ``test_implemented_parsers_are_registered``.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
|
||||
from app.protokoll_parsers import PROTOKOLL_PARSERS, supported_bundeslaender
|
||||
|
||||
STUB_BL_CODES = [
|
||||
"BUND", "BB", "BE", "BW", "BY", "HB", "HE", "HH",
|
||||
"LSA", "MV", "NI", "RP", "SH", "SL", "SN", "TH",
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(params=STUB_BL_CODES)
|
||||
def stub_module(request):
|
||||
code = request.param
|
||||
mod_name = f"app.protokoll_parsers.{code.lower()}"
|
||||
return code, importlib.import_module(mod_name)
|
||||
|
||||
|
||||
class TestStubImportability:
|
||||
def test_each_stub_imports(self, stub_module):
|
||||
code, mod = stub_module
|
||||
assert mod is not None
|
||||
assert hasattr(mod, "parse_protocol")
|
||||
|
||||
def test_each_stub_has_recherche_in_docstring(self, stub_module):
|
||||
"""Docstring enthaelt 'Recherche'-Marker und Status-Hinweis."""
|
||||
code, mod = stub_module
|
||||
doc = mod.__doc__ or ""
|
||||
assert "Recherche" in doc or "Status" in doc, \
|
||||
f"Stub {code}: Docstring enthaelt keine Recherche-Findings"
|
||||
|
||||
def test_each_stub_links_to_issue(self, stub_module):
|
||||
"""Docstring verweist auf konkretes Tracking-Issue."""
|
||||
code, mod = stub_module
|
||||
doc = mod.__doc__ or ""
|
||||
assert "issues/" in doc, f"Stub {code}: kein Issue-Link"
|
||||
|
||||
|
||||
class TestStubBehavior:
|
||||
def test_each_stub_raises_not_implemented(self, stub_module):
|
||||
code, mod = stub_module
|
||||
with pytest.raises(NotImplementedError) as exc:
|
||||
mod.parse_protocol("/dev/null")
|
||||
msg = str(exc.value)
|
||||
assert "noch nicht implementiert" in msg, \
|
||||
f"Stub {code}: NotImplementedError-Message ist nicht informativ"
|
||||
|
||||
|
||||
class TestRegistryDiscipline:
|
||||
"""Sicherheitsnetz: Stubs duerfen NICHT in PROTOKOLL_PARSERS sein.
|
||||
|
||||
Sobald ein Stub durch echten Parser ersetzt wird, MUSS der Implementer:
|
||||
1. NotImplementedError aus parse_protocol entfernen
|
||||
2. PROTOKOLL_PARSERS[code] = parse_protocol setzen
|
||||
|
||||
Dieser Test schlaegt fehl, wenn eines der beiden vergessen wird —
|
||||
explizit unten ueber test_implemented_parsers_are_registered.
|
||||
"""
|
||||
|
||||
def test_stubs_not_in_registry(self):
|
||||
registered = set(supported_bundeslaender())
|
||||
# Aktuell muss nur NRW in der Registry sein
|
||||
assert registered == {"NRW"}, (
|
||||
"Unerwartete Registry-Eintraege. Wenn neue BL implementiert sind, "
|
||||
"diesen Test anpassen UND den Stub durch echten Parser ersetzen."
|
||||
)
|
||||
|
||||
def test_implemented_parsers_are_registered(self, stub_module):
|
||||
"""Wenn ein Stub-Modul KEIN NotImplementedError mehr wirft (also
|
||||
implementiert wurde), muss es in PROTOKOLL_PARSERS registriert sein.
|
||||
|
||||
Dieser Test ist der Trigger: sobald der Implementer parse_protocol
|
||||
echt implementiert (kein NotImplementedError mehr), schlaegt der
|
||||
andere Test (test_each_stub_raises_not_implemented) fehl. Das ist
|
||||
das richtige Signal — dann muessen Tests + Registry beide angepasst
|
||||
werden.
|
||||
"""
|
||||
code, mod = stub_module
|
||||
# Probe: wirft das Modul noch NotImplementedError?
|
||||
try:
|
||||
mod.parse_protocol("/dev/null")
|
||||
implemented = True
|
||||
except NotImplementedError:
|
||||
implemented = False
|
||||
except Exception:
|
||||
# Anderer Fehler (z.B. fitz konnte /dev/null nicht oeffnen) →
|
||||
# Modul ist implementiert (wuerde mit echtem PDF arbeiten)
|
||||
implemented = True
|
||||
|
||||
if implemented:
|
||||
assert code in PROTOKOLL_PARSERS, (
|
||||
f"{code}-Parser scheint implementiert (keine NotImplementedError), "
|
||||
f"aber nicht in PROTOKOLL_PARSERS registriert. Beide muessen "
|
||||
f"zusammen aktualisiert werden."
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user