aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/eu/mulk/aendggner/EndToEndTest.java54
-rw-r--r--src/test/java/eu/mulk/aendggner/aenderung/parse/SeitenkonkordanzTest.java84
2 files changed, 138 insertions, 0 deletions
diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java
index eead6a0..34bc8e6 100644
--- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java
+++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java
@@ -172,6 +172,60 @@ class EndToEndTest {
/** Neues digitales BGBl-Format (recht.bund.de, ab 2023): 3. UWGÄndG 2026. */
@Test
+ void fundstelleImHeft() throws Exception {
+ var xml = SAMPLEDATA.resolve("UWG/BJNR141400004.xml");
+ var pdf = SAMPLEDATA.resolve("UWG/bgbl126s0043_regelungstext.pdf");
+ assumeTrue(Files.exists(xml) && Files.exists(pdf), "UWG-Beispieldaten fehlen");
+
+ var gesetz = new GiiXmlLoader().load(xml);
+ var auszug = new PatchTextExtraktor().extrahiereMitSeiten(Quelle.lies(pdf));
+ var befehle =
+ new AenderungsgesetzParser()
+ .parse(TextBereiniger.bereinige(auszug.text()), gesetz, null, false, auszug.seiten())
+ .befehle();
+
+ // Jeder Befehl trägt seine Seite; das Heft hat fünf.
+ assertThat(befehle).allSatisfy(b -> assertThat(b.provenienz().seite()).isNotNull());
+ assertThat(befehle).allSatisfy(b -> assertThat(b.provenienz().seite()).isBetween(1, 5));
+
+ // Die Befehle stehen im Heft, wie sie erschlossen werden: Die Seiten steigen.
+ var seiten = befehle.stream().map(b -> b.provenienz().seite()).toList();
+ assertThat(seiten).isSorted();
+
+ // Gegenprobe am Druckwerk: Der erste Befehl steht auf Seite 1, „Nach § 5b Absatz 3 …“ auf
+ // Seite 3 (dort beginnt die Zeile „3. Nach § 5b Absatz 3 wird der folgende Absatz 3a
+ // eingefügt:“).
+ assertThat(befehle.get(0).provenienz().seite()).isEqualTo(1);
+ assertThat(
+ befehle.stream()
+ .filter(b -> b.provenienz().originalText().startsWith("Nach § 5b Absatz 3"))
+ .findFirst()
+ .orElseThrow()
+ .provenienz()
+ .seite())
+ .isEqualTo(3);
+
+ // Die Seite steht auch in der Anzeige — dort sucht sie, wer einen Rest von Hand prüft.
+ assertThat(befehle.get(0).provenienz().anzeigeText()).endsWith("(S. 1)");
+ }
+
+ @Test
+ void klartextTraegtKeineSeite() throws Exception {
+ // Eine Klartextdatei hat kein Satzbild; eine Seitenangabe wäre erfunden.
+ var xml = SAMPLEDATA.resolve("UWG/BJNR141400004.xml");
+ var pdf = SAMPLEDATA.resolve("UWG/bgbl126s0043_regelungstext.pdf");
+ assumeTrue(Files.exists(xml) && Files.exists(pdf), "UWG-Beispieldaten fehlen");
+
+ var gesetz = new GiiXmlLoader().load(xml);
+ var text = TextBereiniger.bereinige(new PatchTextExtraktor().extrahiere(pdf));
+ var befehle = new AenderungsgesetzParser().parse(text, gesetz, null).befehle();
+
+ assertThat(befehle).isNotEmpty();
+ assertThat(befehle).allSatisfy(b -> assertThat(b.provenienz().seite()).isNull());
+ assertThat(befehle.get(0).provenienz().anzeigeText()).doesNotContain("(S.");
+ }
+
+ @Test
void uwgNeuesBgblFormat() throws Exception {
var xml = SAMPLEDATA.resolve("UWG/BJNR141400004.xml");
var pdf = SAMPLEDATA.resolve("UWG/bgbl126s0043_regelungstext.pdf");
diff --git a/src/test/java/eu/mulk/aendggner/aenderung/parse/SeitenkonkordanzTest.java b/src/test/java/eu/mulk/aendggner/aenderung/parse/SeitenkonkordanzTest.java
new file mode 100644
index 0000000..8e30814
--- /dev/null
+++ b/src/test/java/eu/mulk/aendggner/aenderung/parse/SeitenkonkordanzTest.java
@@ -0,0 +1,84 @@
+// SPDX-FileCopyrightText: 2026 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+// SPDX-License-Identifier: AGPL-3.0-or-later
+package eu.mulk.aendggner.aenderung.parse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class SeitenkonkordanzTest {
+
+ private static FontgroessenFilter.Zeile zeile(int seite, String text) {
+ return new FontgroessenFilter.Zeile(seite, Float.NaN, Float.NaN, Float.NaN, text);
+ }
+
+ private static Seitenkonkordanz konkordanz(FontgroessenFilter.Zeile... zeilen) {
+ return Seitenkonkordanz.aus(List.of(zeilen));
+ }
+
+ @Test
+ void findetDenBefehlAufSeinerSeite() {
+ var leser =
+ konkordanz(
+ zeile(1, "1. § 2 Absatz 2 wird durch die folgenden Absätze 2 und 3 ersetzt:"),
+ zeile(2, "2. In § 5 Absatz 3 Nummer 1 wird die Angabe „a“ durch „b“ ersetzt."))
+ .leser();
+
+ assertThat(leser.seiteVon("§ 2 Absatz 2 wird durch die folgenden Absätze 2 und 3 ersetzt:"))
+ .isEqualTo(1);
+ assertThat(leser.seiteVon("In § 5 Absatz 3 Nummer 1 wird die Angabe „a“ durch „b“ ersetzt."))
+ .isEqualTo(2);
+ }
+
+ @Test
+ void satzzeichenUndSilbentrennungStoerenNicht() {
+ // Der Bereiniger zieht weiche Umbrüche zusammen und heilt Trennstriche; der Wortbestand ist
+ // hernach derselbe, das Satzbild nicht. Genau darauf beruht die Suche.
+ var leser =
+ konkordanz(
+ zeile(4, "3. Nach Absatz 5 wird der folgende Ab-"),
+ zeile(5, "satz 6 eingefügt: „(6) Eine geschäftliche Handlung ist irreführend.“"))
+ .leser();
+
+ assertThat(leser.seiteVon("Nach Absatz 5 wird der folgende Absatz 6 eingefügt:")).isEqualTo(4);
+ }
+
+ @Test
+ void mehrfacherWortlautTrifftDieFortgeschritteneSeite() {
+ // „Absatz 3 wird aufgehoben“ steht in einem Heft dutzendfach. Maßgeblich ist, wie weit die
+ // Erschließung gediehen ist — deshalb der fortschreitende Leser.
+ var konkordanz =
+ konkordanz(
+ zeile(1, "a) Der Absatz 3 wird aufgehoben."),
+ zeile(7, "b) In § 40 wird ein Wort ersetzt."),
+ zeile(9, "c) Der Absatz 3 wird aufgehoben."));
+
+ var leser = konkordanz.leser();
+ assertThat(leser.seiteVon("Der Absatz 3 wird aufgehoben.")).isEqualTo(1);
+ assertThat(leser.seiteVon("In § 40 wird ein Wort ersetzt.")).isEqualTo(7);
+ assertThat(leser.seiteVon("Der Absatz 3 wird aufgehoben.")).isEqualTo(9);
+ }
+
+ @Test
+ void wasSichNichtWiederfindetBleibtOhneSeite() {
+ var leser =
+ konkordanz(zeile(1, "Ein Wortlaut, der nichts mit dem Gesuchten zu tun hat.")).leser();
+
+ assertThat(leser.seiteVon("Dieser Befehl steht in keinem Heft.")).isNull();
+ }
+
+ @Test
+ void zuKurzesIstKeinWortlaut() {
+ // „a)“ steht auf jeder zweiten Seite; daraus eine Fundstelle zu machen wäre geraten.
+ var leser = konkordanz(zeile(3, "a) und b) und c)")).leser();
+
+ assertThat(leser.seiteVon("a)")).isNull();
+ }
+
+ @Test
+ void ohneSatzbildKeineSeite() {
+ assertThat(Seitenkonkordanz.LEER.leser().seiteVon("Ein beliebiger Befehlstext von Länge."))
+ .isNull();
+ }
+}