feat: „Zu prüfen“ zeigt bloße Wortformen getrennt am Ende
Ersetzt das Modell ein gültiges Wort nur durch eine andere Form („Punkten“ → „Punkte“, „das“ → „dass“, „sehe“ → „sähe“), heißt der Grund jetzt „Wortform geändert“. Diese Fälle stehen im Bericht in einer eigenen Tabelle nach den sinnverändernden, im Text gestrichelt umrahmt, und in der Konsole am Ende. „-in“ zählt nicht als Endung: „Professor“ → „Professorin“ bleibt oben. Außerdem: Die Tabellen scrollen auf schmalen Bildschirmen waagrecht, und aenderungen.py meldet Zeit-Überschriften nicht als Einfügung, wenn der Rohtext (z. B. eine .vtt) keine hat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
011d201215
commit
cd62feab69
1 changed files with 163 additions and 32 deletions
|
|
@ -124,10 +124,8 @@ def test_cli_missing_file(tmp_path, monkeypatch, capsys):
|
|||
WORDS = {"professor", "das", "dass", "ist", "haus", "unterschreiben", "bar"}
|
||||
|
||||
|
||||
def suspects(model_input, corrected, wordlist=WORDS, glossary=(), fillers=ae.FILLERS["de"]):
|
||||
found = ae.review_candidates(
|
||||
ae.compare(model_input, corrected), wordlist, glossary, fillers
|
||||
)
|
||||
def suspects(model_input, corrected, wordlist=WORDS, glossary=(), lang="de"):
|
||||
found = ae.review_candidates(ae.compare(model_input, corrected), wordlist, glossary, lang)
|
||||
return [(s.reason, s.old, s.new) for s in found]
|
||||
|
||||
|
||||
|
|
@ -182,7 +180,7 @@ def test_review_candidates_fillers_per_language():
|
|||
assert suspects("dann kam er um zu helfen", "Dann kam, zu helfen.") == [
|
||||
(ae.DELETED, "er um", "")
|
||||
]
|
||||
english = suspects("so er we um go", "So we go.", fillers=ae.FILLERS["en"])
|
||||
english = suspects("so er we um go", "So we go.", lang="en")
|
||||
assert english == []
|
||||
|
||||
|
||||
|
|
@ -224,7 +222,7 @@ def test_report_suspects_only_against_model_input(tmp_path, capsys):
|
|||
assert [s.reason for s in comparison.suspects] == [ae.VALID_WORD, ae.DELETED]
|
||||
assert "Zu prüfen (2)" in page
|
||||
assert "Professorin" in section and "Kremmel" not in section
|
||||
assert "<span class=warn title='gültiges Wort ersetzt: „Professor“ → „Professorin“'>" in page
|
||||
assert "<span class='warn' title='gültiges Wort ersetzt: „Professor“ → „Professorin“'>" in page
|
||||
assert "<span class=warn title='gestrichen: „heute“ → „∅“'>⚠</span>" in page
|
||||
# Framing changes nothing about the text itself
|
||||
assert report_text(page) == "Der Professorin im Kreml ⚠ dort.".split()
|
||||
|
|
@ -242,6 +240,20 @@ def test_report_without_suspects(tmp_path):
|
|||
assert "Keine auffälligen Änderungen" in suspect_section(target.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def test_cli_ignores_time_headers_missing_in_raw(tmp_path, monkeypatch, capsys):
|
||||
raw = tmp_path / "rede.vtt"
|
||||
raw.write_text(
|
||||
"WEBVTT\n\n00:00:01.000 --> 00:00:02.000\ndas Kremmel heute\n", encoding="utf-8"
|
||||
)
|
||||
corrected = tmp_path / "rede.korrigiert.txt"
|
||||
corrected.write_text("[00:00:01 - 00:00:02]\n\nDas Kreml heute.\n", encoding="utf-8")
|
||||
monkeypatch.setattr(sys, "argv", ["aenderungen.py", "-a", str(raw), "-b", str(corrected)])
|
||||
ae.main()
|
||||
out = capsys.readouterr().out
|
||||
assert "Zu prüfen: 0 Stellen" in out
|
||||
assert "00:00:01" not in out
|
||||
|
||||
|
||||
def test_cli_glossary(tmp_path, monkeypatch, capsys):
|
||||
raw = tmp_path / "rede.txt"
|
||||
raw.write_text("das Kremmel und\nBar heute\n", encoding="utf-8")
|
||||
|
|
@ -261,3 +273,51 @@ def test_cli_glossary(tmp_path, monkeypatch, capsys):
|
|||
assert "Zu prüfen: 0 Stellen" in out
|
||||
# The report still compares against the raw transcript
|
||||
assert "1× „Kremmel“ → „Kreml“" in out
|
||||
|
||||
|
||||
@pytest.mark.parametrize("old, new, expected", [
|
||||
("Punkten", "Punkte", True),
|
||||
("das", "dass", True),
|
||||
("sehe", "sähe", True), # umlaut
|
||||
("sein", "seien", True), # both endings change
|
||||
("kommt,", "kommen,", True), # punctuation does not count
|
||||
("Professor", "Professorin", False), # "-in" is no inflection
|
||||
("geworben", "geworden", False),
|
||||
("unterschreiben", "unterscheiden", False),
|
||||
("ich", "sich", False),
|
||||
("den", "der", False), # stem too short
|
||||
("sich dazu", "zu", False), # more than one word
|
||||
])
|
||||
def test_word_form_change(old, new, expected):
|
||||
assert ae.word_form_change(old.split(), new.split()) is expected
|
||||
|
||||
|
||||
def test_word_form_change_english():
|
||||
assert ae.word_form_change(["walk"], ["walked"], "en")
|
||||
assert not ae.word_form_change(["walk"], ["walker"], "en")
|
||||
|
||||
|
||||
def test_review_candidates_word_forms():
|
||||
words = WORDS | {"punkten", "punkte"}
|
||||
assert suspects("die Punkten und das", "die Punkte und dass", wordlist=words) == [
|
||||
(ae.WORD_FORM, "Punkten", "Punkte"), (ae.WORD_FORM, "das", "dass"),
|
||||
]
|
||||
|
||||
|
||||
def test_report_and_summary_put_word_forms_last(tmp_path, capsys):
|
||||
target = tmp_path / "bericht.html"
|
||||
comparison = ae.write_report(
|
||||
"das sagte der Professor", "dass sagte der Professorin", target, "rede"
|
||||
)
|
||||
assert [s.reason for s in comparison.suspects] == [ae.WORD_FORM, ae.VALID_WORD]
|
||||
page = target.read_text(encoding="utf-8")
|
||||
section = suspect_section(page)
|
||||
# Meaning change in the main table, the word form in its own group after it
|
||||
assert section.index("Professorin") < section.index("Wortform geändert (1)")
|
||||
assert section.index("Wortform geändert (1)") < section.index("<ins>dass</ins>")
|
||||
assert "<span class='warn form' title='Wortform geändert: „das“ → „dass“'>" in page
|
||||
|
||||
ae.print_summary(comparison)
|
||||
out = capsys.readouterr().out.split("Zu prüfen: ")[1]
|
||||
assert out.startswith("2 Stellen (davon 1 Wortformen)")
|
||||
assert out.index("Professorin") < out.index("„das“ → „dass“")
|
||||
|
|
|
|||
Loading…
Reference in a new issue