diff options
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/java/eu/mulk/aendggner/EndToEndTest.java | 161 |
1 files changed, 109 insertions, 52 deletions
diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java index 78a45e9..91a0cca 100644 --- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java +++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java @@ -17,11 +17,13 @@ import eu.mulk.aendggner.aenderung.parse.SuperskriptModus; import eu.mulk.aendggner.aenderung.parse.TextBereiniger; import eu.mulk.aendggner.aenderung.parse.ZitatExtraktor; import eu.mulk.aendggner.anwendung.BefehlAnwender; +import eu.mulk.aendggner.anwendung.Nachfassungsabgleich; import eu.mulk.aendggner.gesetz.Absatz; import eu.mulk.aendggner.gesetz.Gesetz; import eu.mulk.aendggner.gesetz.gii.GiiXmlLoader; import eu.mulk.aendggner.synopse.HtmlRenderer; import eu.mulk.aendggner.synopse.SynopseBuilder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDate; @@ -737,13 +739,13 @@ class EndToEndTest { assumeTrue(Files.exists(pfad), "Nachfassung " + nachfassung + " fehlt"); var soll = new eu.mulk.aendggner.gesetz.land.LandesRechtLoader().load(pfad); assertThat(soll.normen()).hasSameSizeAs(alt.normen()); - for (var normSoll : soll.normen()) { - var normIst = anwendung.neu().norm(normSoll.enbez()); - assertThat(normIst).as("Norm %s fehlt", normSoll.enbez()).isPresent(); - assertThat(normIst.orElseThrow().gesamtText().replaceAll("\\s+", " ").strip()) - .as("Norm %s", normSoll.enbez()) - .isEqualTo(normSoll.gesamtText().replaceAll("\\s+", " ").strip()); - } + + // Geprüft wird mit demselben Abgleich, den auch --nachfassung fährt: Werkzeug und Test messen + // an einem Maßstab, sonst geht der eine durch, wo der andere anschlüge. + var abgleich = Nachfassungsabgleich.vergleiche(soll, anwendung.neu()); + assertThat(abgleich.fehlende()).isEmpty(); + assertThat(abgleich.abweichungen()).as("Abweichungen gegen die amtliche Nachfassung").isEmpty(); + assertThat(abgleich.gehtAuf()).as(abgleich.kurzbericht()).isTrue(); } /** @@ -1055,17 +1057,10 @@ class EndToEndTest { var sollAsog = SAMPLEDATA.resolve("Berlin/ASOG-Bln-neu.txt"); assumeTrue(Files.exists(sollAsog), "ASOG-Nachfassung fehlt"); var soll = new eu.mulk.aendggner.gesetz.land.LandesRechtLoader().load(sollAsog); - var abweichend = new java.util.ArrayList<String>(); - for (var normSoll : soll.normen()) { - var normIst = anwendung.neu().norm(normSoll.enbez()).orElseThrow(); - if (!normIst - .gesamtText() - .replaceAll("\\s+", " ") - .strip() - .equals(normSoll.gesamtText().replaceAll("\\s+", " ").strip())) { - abweichend.add(normSoll.enbez()); - } - } + var abweichend = + Nachfassungsabgleich.vergleiche(soll, anwendung.neu()).abweichungen().stream() + .map(Nachfassungsabgleich.Abweichung::enbez) + .toList(); // Keine Abweichung mehr: Alle 171 Normen gleichen der amtlichen Nachfassung. // // § 67 trug die beiden zuvor benannten Abweichungen: Das Portal setzt in der neuen Fassung @@ -1148,17 +1143,10 @@ class EndToEndTest { var soll = new eu.mulk.aendggner.gesetz.land.LandesRechtLoader() .load(SAMPLEDATA.resolve("BadenWuerttemberg/KomWO-BW-neu.txt")); - var abweichend = new java.util.ArrayList<String>(); - for (var normSoll : soll.normen()) { - var normIst = anwendung.neu().norm(normSoll.enbez()).orElseThrow(); - if (!normIst - .gesamtText() - .replaceAll("\\s+", " ") - .strip() - .equals(normSoll.gesamtText().replaceAll("\\s+", " ").strip())) { - abweichend.add(normSoll.enbez()); - } - } + var abweichend = + Nachfassungsabgleich.vergleiche(soll, anwendung.neu()).abweichungen().stream() + .map(Nachfassungsabgleich.Abweichung::enbez) + .toList(); // § 20: Der Befehl ersetzt das Wort „Name“ durch „der vollständige Familienname“; im Zieltext // steht davor bereits „der“, sodass es doppelt erscheint. Die amtliche Nachfassung räumt das // auf, der Befehlswortlaut tut es nicht — ÄndGgner wendet den Wortlaut an. @@ -1353,13 +1341,10 @@ class EndToEndTest { assumeTrue(Files.exists(soll), "Hessische Nachfassung fehlt"); var amtlich = new eu.mulk.aendggner.gesetz.land.LandesRechtLoader().load(soll); assertThat(amtlich.normen()).hasSize(52); - for (var normSoll : amtlich.normen()) { - var normIst = anwendung.neu().norm(normSoll.enbez()); - assertThat(normIst).as("Norm %s fehlt", normSoll.enbez()).isPresent(); - assertThat(normIst.orElseThrow().gesamtText().replaceAll("\\s+", " ").strip()) - .as("Norm %s", normSoll.enbez()) - .isEqualTo(normSoll.gesamtText().replaceAll("\\s+", " ").strip()); - } + var abgleich = Nachfassungsabgleich.vergleiche(amtlich, anwendung.neu()); + assertThat(abgleich.fehlende()).isEmpty(); + assertThat(abgleich.abweichungen()).isEmpty(); + assertThat(abgleich.gleich()).isEqualTo(52); } /** @@ -1527,8 +1512,8 @@ class EndToEndTest { Files.exists(alt) && Files.exists(entwurfPdf) && Files.exists(antragPdf), "BayJG-Beispieldaten fehlen"); - var ohne = Pipeline.erzeugeSynopse(alt, List.of(entwurfPdf), null, false); - var mit = Pipeline.erzeugeSynopse(alt, List.of(entwurfPdf, antragPdf), null, false); + var ohne = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(alt, List.of(entwurfPdf))); + var mit = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(alt, List.of(entwurfPdf, antragPdf))); assertThat(mit.anzahlAngewandt()).isEqualTo(ohne.anzahlAngewandt()).isEqualTo(154); assertThat(mit.anzahlManuell()).isEqualTo(ohne.anzahlManuell()).isEqualTo(0); @@ -1607,8 +1592,8 @@ class EndToEndTest { Files.exists(xml) && Files.exists(empfehlung) && Files.exists(entwurf), "GEG-Beispieldaten fehlen"); - var ausEmpfehlung = Pipeline.erzeugeSynopse(xml, List.of(empfehlung), null, false); - var ausEntwurf = Pipeline.erzeugeSynopse(xml, List.of(entwurf), null, false); + var ausEmpfehlung = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(empfehlung))); + var ausEntwurf = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(entwurf))); // 69 statt der früheren 68: Nennt der Rahmen dieselbe Gliederungseinheit wie der Befehl („… // Teil 2 wird wie folgt geändert: … die Angabe zur Überschrift von Teil 2 Abschnitt 4 …“), @@ -1635,7 +1620,7 @@ class EndToEndTest { var pdf = SAMPLEDATA.resolve("IfSG/1924334.pdf"); assumeTrue(Files.exists(xml) && Files.exists(pdf), "IfSG-Beispieldaten fehlen"); - var ergebnis = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false); + var ergebnis = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(pdf))); // 51 statt der früheren 47: Die Satzzählung folgt jetzt der amtlichen — eine eingerückte // Aufzählungsmarke beendet keinen Satz, und eine Ordnungszahl vor einem Gliederungswort („nach @@ -1655,7 +1640,7 @@ class EndToEndTest { var pdf = SAMPLEDATA.resolve("GEG/BT-Drs-21-7071_Beschlussempfehlung.pdf"); assumeTrue(Files.exists(xml) && Files.exists(pdf), "GEG-Beispieldaten fehlen"); - var ergebnis = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false); + var ergebnis = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(pdf))); assertThat(ergebnis.anzahlAngewandt()).isZero(); assertThat(ergebnis.html()).contains("keine Änderungsbefehle"); @@ -1682,7 +1667,7 @@ class EndToEndTest { assumeTrue(Files.exists(xml) && Files.exists(pdf), "UWG-Beispieldaten fehlen"); // Ohne Stichtag bleibt es beim vollen Bestand — aber nicht stillschweigend. - var ohne = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false); + var ohne = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(pdf))); assertThat(ohne.anzahlAngewandt()).isEqualTo(19); assertThat(ohne.html()) .contains("Das Änderungsgesetz tritt gestaffelt in Kraft") @@ -1690,7 +1675,9 @@ class EndToEndTest { .contains("<dt>Inkrafttreten</dt><dd>27. September 2026 (gestaffelt, siehe unten)</dd>"); // Am 19. Juni 2026 galt genau ein Befehl: der Buchstabe c der Nummer 2. - var frueh = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2026, 6, 19)); + var frueh = + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2026, 6, 19))); assertThat(frueh.anzahlAngewandt()).isEqualTo(1); assertThat(frueh.anzahlManuell()).isZero(); assertThat(frueh.html()) @@ -1698,12 +1685,16 @@ class EndToEndTest { .contains("Am Stichtag noch nicht in Kraft") .contains("Tritt erst am 27. September 2026 in Kraft"); // Der Tag davor ändert noch gar nichts. - var davor = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2026, 6, 18)); + var davor = + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2026, 6, 18))); assertThat(davor.anzahlAngewandt()).isZero(); // Am 27. September 2026 ist das Gesetz vollständig in Kraft; dann deckt sich die Fassung mit // der ungefilterten, und der Abschnitt „noch nicht in Kraft“ entfällt. - var spaet = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2026, 9, 27)); + var spaet = + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2026, 9, 27))); assertThat(spaet.anzahlAngewandt()).isEqualTo(19); assertThat(spaet.html()).doesNotContain("Am Stichtag noch nicht in Kraft"); } @@ -1720,12 +1711,13 @@ class EndToEndTest { var pdf = SAMPLEDATA.resolve("GEG/bgbl123s0280_regelungstext.pdf"); assumeTrue(Files.exists(xml) && Files.exists(pdf), "GEG-Beispieldaten fehlen"); - var vollstaendig = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false); + var vollstaendig = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(pdf))); assertThat(vollstaendig.anzahlAngewandt()).isEqualTo(117); assertThat(vollstaendig.anzahlManuell()).isEqualTo(2); var anfang2024 = - Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2024, 1, 1)); + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2024, 1, 1))); assertThat(anfang2024.anzahlAngewandt()).isEqualTo(116); assertThat(anfang2024.anzahlManuell()).isEqualTo(2); assertThat(anfang2024.html()) @@ -1733,7 +1725,8 @@ class EndToEndTest { .contains("Tritt erst am 1. Oktober 2024 in Kraft"); var oktober2024 = - Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2024, 10, 1)); + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2024, 10, 1))); assertThat(oktober2024.anzahlAngewandt()).isEqualTo(117); } @@ -1753,7 +1746,8 @@ class EndToEndTest { assumeTrue(Files.exists(xml) && Files.exists(pdf), "IfSG-Beispieldaten fehlen"); var novemberFassung = - Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2020, 11, 19)); + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2020, 11, 19))); assertThat(novemberFassung.anzahlAngewandt()).isEqualTo(65); assertThat(novemberFassung.html()) .contains("Am Stichtag noch nicht in Kraft") @@ -1761,7 +1755,8 @@ class EndToEndTest { // Am 1. April 2021 kommen die zehn Befehle des Artikels 2 und der Doppelbuchstabe hinzu. var aprilFassung = - Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false, LocalDate.of(2021, 4, 1)); + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)).mitStichtag(LocalDate.of(2021, 4, 1))); assertThat(aprilFassung.anzahlAngewandt()).isEqualTo(75); assertThat(aprilFassung.html()).doesNotContain("Am Stichtag noch nicht in Kraft"); } @@ -1812,7 +1807,7 @@ class EndToEndTest { assertThat(grundregel.wortlaut()) .isEqualTo("Dieses Gesetz tritt am Tag nach der Verkündung in Kraft."); - var synopse = Pipeline.erzeugeSynopse(alt, List.of(pdf), null, false); + var synopse = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(alt, List.of(pdf))); assertThat(synopse.anzahlAngewandt()).isEqualTo(4); assertThat(synopse.html()).doesNotContain("tritt gestaffelt in Kraft"); } @@ -1881,4 +1876,66 @@ class EndToEndTest { .toList(); assertThat(unerkannt).containsExactly("5. a) aa)", "7. a) aa)", "12."); } + + /** + * Der Abgleich mit der amtlichen Nachfassung ist fortan eine Leistung des Erzeugnisses und nicht + * bloß eine des Testcodes: {@code --nachfassung} nimmt dieselben Eingaben an wie das Stammgesetz + * und stellt das Ergebnis normweise dagegen. Berlin, Artikel 1: 171 von 171. + */ + @Test + void nachfassungWirdNormweiseAbgeglichen() throws Exception { + var alt = SAMPLEDATA.resolve("Berlin/ASOG-Bln-alt.txt"); + var neu = SAMPLEDATA.resolve("Berlin/ASOG-Bln-neu.txt"); + var pdf = SAMPLEDATA.resolve("Berlin/GVBl-2026-17_ASOG-LAF-AendG.pdf"); + assumeTrue( + Files.exists(alt) && Files.exists(neu) && Files.exists(pdf), "ASOG-Beispieldaten fehlen"); + + var ergebnis = + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(alt, List.of(pdf)) + .mitArtikel("1") + .mitNachfassung(Quelle.lies(neu))); + + var abgleich = ergebnis.abgleich(); + assertThat(abgleich).isNotNull(); + assertThat(abgleich.gehtAuf()).as(abgleich.kurzbericht()).isTrue(); + assertThat(abgleich.gleich()).isEqualTo(171); + assertThat(abgleich.geprueft()).isEqualTo(171); + // Und er steht in der Synopse, wo ihn auch findet, wer keine Befehlszeile liest. + assertThat(ergebnis.html()) + .contains("Abgleich mit der amtlichen Nachfassung") + .contains("171 von 171 Normen gleich"); + } + + /** + * Die Kette steht und fällt damit, dass die ausgegebene Fassung wieder eingelesen dasselbe Gesetz + * ergibt. Geprüft wird das hier am <em>Bundesrecht</em> — der Rundlauf-Test des Textausgebers + * deckt nur die Klartext-Stammfassungen ab, und gerade der Weg vom gii-XML in den kanonischen + * Klartext ist der, den die Kette braucht: Wer ein zweites Heft auf das Ergebnis des ersten + * anwenden will, hat kein XML mehr, sondern nur diesen Text. + */ + @Test + void dieAusgegebeneFassungLaesstSichWiederEinlesen() 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 erst = Pipeline.erzeugeSynopse(Pipeline.Auftrag.von(xml, List.of(pdf))); + assertThat(erst.anzahlAngewandt()).isEqualTo(19); + + // Der zweite Lauf hält dasselbe Ergebnis gegen den Text, den der erste geschrieben hat. Geht + // der Abgleich auf, so trägt der Text die Fassung vollständig — und damit die Kette. + var zweit = + Pipeline.erzeugeSynopse( + Pipeline.Auftrag.von(xml, List.of(pdf)) + .mitNachfassung( + new Quelle("UWG-neu.txt", erst.neufassung().getBytes(StandardCharsets.UTF_8)))); + + var abgleich = zweit.abgleich(); + assertThat(abgleich).isNotNull(); + assertThat(abgleich.fehlende()).isEmpty(); + assertThat(abgleich.ueberzaehlige()).isEmpty(); + assertThat(abgleich.abweichungen()).isEmpty(); + assertThat(abgleich.gehtAuf()).as(abgleich.kurzbericht()).isTrue(); + } } |
