"""Anker-Matching (5 Stufen), Akronym-Kanal, Jaccard, Parser.""" from backend import textkit def test_finde_zitat_exakt_und_whitespace(): text = "Der Satz steht\nhier drin. Und mehr." span = textkit.finde_zitat(text, "Der Satz steht hier drin.") assert span and text[span[0]:span[1]].startswith("Der") def test_finde_zitat_casefold_und_umlaute(): text = "Die ÜBERTRAGUNG von Daten ist zentral für jedes Netzwerk im Betrieb." assert textkit.finde_zitat(text, "die übertragung von daten ist zentral") def test_finde_zitat_fuzzy_mit_negations_guard(): basis = ("Eine Sprache ist regulär, wenn ein endlicher Automat sie " "akzeptiert und verarbeitet.") text = f"Einleitung. {basis} Schluss." leicht_anders = basis.replace("verarbeitet", "verarbeiten kann") assert textkit.finde_zitat(text, leicht_anders) # Negation im Zitat, nicht im Text → KEIN Anker (Antonym-Falle) negiert = basis.replace("ist regulär", "ist nicht regulär") assert textkit.finde_zitat(text, negiert) is None def test_akronym_kanal(): assert textkit.ist_akronym_von("DNS", "Domain Name System") assert not textkit.ist_akronym_von("HTTP", "Hypertext Markup Language") assert not textkit.ist_akronym_von("A", "Anfang") def test_jaccard_gestemmt(): a = "Die Führung von Teams erfordert Erfahrung." b = "Teams führen erfordert erfahrene Personen." assert textkit.jaccard(a, b) > textkit.jaccard(a, "Völlig anderes Thema hier.") def test_bloecke_parser(): text = ("Prosa davor\n===ATOM===\nTITEL: A\nDEFINITION: Zeile 1\nZeile 2\n" "===ATOM===\nTITEL: B\nDEFINITION: x\n") bloecke = textkit.bloecke(text, "ATOM") assert len(bloecke) == 2 assert bloecke[0]["titel"] == "A" assert "Zeile 2" in bloecke[0]["definition"] def test_ueberlappung(): assert textkit.ueberlappung((0, 100), (50, 150)) == 0.5 assert textkit.ueberlappung((0, 10), (20, 30)) == 0.0