"""Every user-visible string has German text (AD-15); the informal catalogue only differs.""" import re from pathlib import Path import polib import pytest PORTAL = Path(__file__).resolve().parent.parent LOCALE = PORTAL / "locale" TRANS_TAG = re.compile(r"""\{%\s*trans\s+(?:"([^"]+)"|'([^']+)')""") BLOCKTRANS = re.compile(r"\{%\s*blocktrans[^%]*%\}(.*?)\{%\s*endblocktrans\s*%\}", re.S) VARIABLE = re.compile(r"\{\{\s*(\w+)\s*\}\}") PY_CALL = re.compile(r"""(? set[str]: found = set() for template in (PORTAL / "templates").rglob("*.html"): text = template.read_text(encoding="utf-8") found.update(a or b for a, b in TRANS_TAG.findall(text)) found.update(VARIABLE.sub(r"%(\1)s", body).strip() for body in BLOCKTRANS.findall(text)) for source in PORTAL.rglob("*.py"): if "tests" in source.parts or "migrations" in source.parts: continue found.update(a or b for a, b in PY_CALL.findall(source.read_text(encoding="utf-8"))) return found def catalogue(name: str) -> polib.POFile: return polib.pofile(str(LOCALE / name / "LC_MESSAGES" / "django.po")) def test_the_scan_finds_the_strings(): assert {"Sign out", "Home", "Hello, %(name)s", "Audit log"} <= msgids_in_code() def test_every_string_in_the_code_has_german_text(): german = {e.msgid: e for e in catalogue("de")} missing = sorted(msgids_in_code() - german.keys()) assert not missing, f"no German entry for: {missing}" for entry in german.values(): assert entry.msgstr.strip(), f"empty German text for {entry.msgid!r}" assert "fuzzy" not in entry.flags, f"fuzzy entry {entry.msgid!r}" def test_the_german_catalogue_has_no_stale_entries(): stale = sorted({e.msgid for e in catalogue("de")} - msgids_in_code()) assert not stale, f"entries no longer used: {stale}" def test_the_informal_catalogue_only_holds_differences_to_known_strings(): german = {e.msgid: e.msgstr for e in catalogue("de")} for entry in catalogue("de_DU"): assert entry.msgid in german, f"unknown string {entry.msgid!r}" assert entry.msgstr.strip() and "fuzzy" not in entry.flags assert entry.msgstr != german[entry.msgid], f"{entry.msgid!r} does not differ" @pytest.mark.parametrize("name", ["de", "de_DU"]) def test_placeholders_survive_translation(name): for entry in catalogue(name): assert set(re.findall(r"%\(\w+\)s", entry.msgid)) == set( re.findall(r"%\(\w+\)s", entry.msgstr) ), entry.msgid def test_the_formal_text_does_not_use_du_and_the_informal_does_not_use_sie(): formal = " ".join(e.msgstr for e in catalogue("de")) assert not re.search(r"\b(du|dir|dich|dein|deine)\b", formal, re.I) informal = " ".join(e.msgstr for e in catalogue("de_DU")) assert not re.search(r"\b(Sie|Ihnen|Ihr|Ihre)\b", informal)