diff options
Diffstat (limited to 'src/test/java')
3 files changed, 74 insertions, 19 deletions
diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java index dde2483..a76f478 100644 --- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java +++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java @@ -888,12 +888,13 @@ class EndToEndTest { /** * Hessen: Die Elfte Verordnung zur Änderung der Verordnung zur Bestimmung verkehrsrechtlicher - * Zuständigkeiten (GVBl. 2026 Nr. 5). Der Test hält Extraktion und Befehlserkennung fest — alle - * 21 Befehle des Artikels 1 werden erkannt. + * Zuständigkeiten (GVBl. 2026 Nr. 5). Voller Akzeptanzfall: Alle 21 Befehle des Artikels 1 werden + * erkannt und angewandt, und jede der 52 Normen gleicht danach zeichengenau der amtlichen + * Nachfassung. * - * <p>Kein voller Akzeptanztest: {@code hessenrecht.hessen.de} ist dieselbe anmeldepflichtige - * juris-Anwendung wie die Portale Schleswig-Holsteins und Berlins, die Stammfassung ist daraus - * nicht zu beschaffen. + * <p>Die Stammfassung ist über eine Browsersteuerung aus dem Landesrechtsportal beschafft — es + * ist eine Einseitenanwendung, die Skriptabfragen nur ihre Hülle zurückgibt. Herkunft und + * Aufbereitung stehen in {@code Hessen/SOURCES}. * * <p>Der hessische Sperrsatz („Der Mi n is t er“) bleibt bewusst unbehandelt: Er trifft nur den * Unterschriftenblock am Dokumentende, keinen einzigen Befehl. @@ -914,12 +915,20 @@ class EndToEndTest { // Der Sperrsatz beschränkt sich auf den Unterschriftenblock — hier bewusst nicht geheilt. assertThat(text).contains("Min isterpräsident"); - var verordnung = - new Gesetz( - "VerkZustV", - "Verordnung zur Bestimmung verkehrsrechtlicher Zuständigkeiten", - null, - List.of()); + var alt = SAMPLEDATA.resolve("Hessen/StVRZustV-alt.txt"); + assumeTrue(Files.exists(alt), "Hessische Stammfassung fehlt"); + var verordnung = new eu.mulk.aendggner.gesetz.land.LandesRechtLoader().load(alt); + assertThat(verordnung.jurabk()).isEqualTo("StVRZustV HE 2007"); + // Diese Verordnung führt keine Paragraphenüberschriften und gliedert sich in ausgeschriebene + // Ordinalzahlen („Erster Teil“); beides kannte der Klartext-Parser bis dahin nicht. + assertThat(verordnung.normen()).hasSize(52); + assertThat(verordnung.norm("§ 1").orElseThrow().titel()).isNull(); + assertThat(verordnung.gliederungen()).hasSize(28); + assertThat(verordnung.gliederungen()) + .extracting(g -> g.bezeichnung()) + .allMatch(b -> b.endsWith(" Teil")); + assertThat(verordnung.gliederungen().get(0).bezeichnung()).isEqualTo("Erster Teil"); + var ergebnis = new AenderungsgesetzParser().parse(text, verordnung, null); // Artikel 2 regelt nur das Inkrafttreten. assertThat(ergebnis.artikel()).containsExactly("1"); @@ -959,6 +968,45 @@ class EndToEndTest { assertThat(bereich.teilbefehle()) .extracting(b -> b.stelle().anzeigeText()) .containsExactly("§ 14 Nummer 4", "§ 14 Nummer 3"); + + // Auch die Bereichsaufhebung spannt absteigend auf („Nr. 9 bis 11 werden aufgehoben“): Ob eine + // aufgehobene Einheit einen nummerierten Platzhalter hinterlässt, entscheidet sich am Bestand, + // der ihr folgt — von hinten aufgehoben, sieht jede den endgültigen. + var aufhebung = (Aenderungsbefehl.Sammelbefehl) befehlZu(ergebnis, "5. h)"); + assertThat(aufhebung.teilbefehle()) + .extracting(b -> b.stelle().anzeigeText()) + .containsExactly("§ 14 Nummer 11", "§ 14 Nummer 10", "§ 14 Nummer 9"); + + // --- Anwendung --------------------------------------------------------------------------- + var anwendung = BefehlAnwender.anwenden(verordnung, ergebnis.befehle()); + assertThat(anwendung.anzahlAngewandt()).isEqualTo(21); + assertThat(anwendung.protokoll()) + .noneMatch(x -> x.status() == BefehlAnwender.Status.MANUELL_PRUEFEN); + + // § 13: Die Streichung der Absatzbezeichnung „(1)“ nimmt dem Wortlaut seine Nummer und lässt + // ihn im Übrigen stehen; die Aufhebung des Abs. 2 beseitigt ihn ganz, weil eine Norm ohne + // Absatzzählung keinen nummerierten Platzhalter tragen kann. + var dreizehn = anwendung.neu().norm("§ 13").orElseThrow(); + assertThat(dreizehn.absaetze()).hasSize(1); + assertThat(dreizehn.absaetze().get(0).nummer()).isNull(); + + // § 14: Das Wort, das an die Stelle des Kommas tritt, bekommt seinen Zwischenraum. + assertThat(anwendung.neu().norm("§ 14").orElseThrow().gesamtText()) + .contains("Fachkräfte) und") + .doesNotContain("(weggefallen)"); + + // Der Abgleich gegen die amtliche Nachfassung, Norm für Norm. + var soll = SAMPLEDATA.resolve("Hessen/StVRZustV-neu.txt"); + 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()); + } } /** diff --git a/src/test/java/eu/mulk/aendggner/aenderung/parse/BefehlErkennerTest.java b/src/test/java/eu/mulk/aendggner/aenderung/parse/BefehlErkennerTest.java index abe3550..fc42ead 100644 --- a/src/test/java/eu/mulk/aendggner/aenderung/parse/BefehlErkennerTest.java +++ b/src/test/java/eu/mulk/aendggner/aenderung/parse/BefehlErkennerTest.java @@ -625,9 +625,12 @@ class BefehlErkennerTest { erkenne("Die Nummern 1 bis 3 werden aufgehoben.", Stelle.LEER).orElseThrow()) .teilbefehle(); assertThat(teile).hasSize(3).allMatch(t -> t instanceof Aufhebung); + // Absteigend seit der hessischen Verkehrsrechts-Zuständigkeitsverordnung: Ob eine aufgehobene + // Einheit einen nummerierten Platzhalter hinterlässt, hängt davon ab, ob ihr noch eine Einheit + // folgt. Von hinten aufgehoben, sieht jede den endgültigen Bestand. assertThat(teile) .extracting(t -> t.stelle().anzeigeText()) - .containsExactly("Nummer 1", "Nummer 2", "Nummer 3"); + .containsExactly("Nummer 3", "Nummer 2", "Nummer 1"); } @Test @@ -636,9 +639,10 @@ class BefehlErkennerTest { ((Sammelbefehl) erkenne("Die Absätze 4 und 5 werden aufgehoben.", Stelle.LEER).orElseThrow()) .teilbefehle(); + // Absteigend, aus demselben Grund wie bei der Bereichsaufhebung. assertThat(teile) .extracting(t -> t.stelle().anzeigeText()) - .containsExactly("Absatz 4", "Absatz 5"); + .containsExactly("Absatz 5", "Absatz 4"); } @Test diff --git a/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java b/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java index 9cd0597..8b60017 100644 --- a/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java +++ b/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java @@ -717,10 +717,12 @@ class BefehlAnwenderTest { void wendetBereichsAufhebungAn() { // „Die Nummern 1 bis 3 werden aufgehoben.“ innerhalb von § 1 Absatz 2. var teile = + // Absteigend, wie der Erkenner eine Bereichsaufhebung aufspannt: Ob eine aufgehobene + // Einheit einen Platzhalter hinterlässt, entscheidet sich am Bestand, der ihr folgt. List.<eu.mulk.aendggner.aenderung.Aenderungsbefehl>of( new Aufhebung( stelle( - new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("1")), + new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("3")), PROV), new Aufhebung( stelle( @@ -728,17 +730,18 @@ class BefehlAnwenderTest { PROV), new Aufhebung( stelle( - new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("3")), + new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("1")), PROV)); var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(new Sammelbefehl(teile))); assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT); var text = absatzText(ergebnis.neu(), "§ 1", 1); - assertThat(text) - .contains("1. (weggefallen)") - .contains("2. (weggefallen)") - .contains("3. (weggefallen)"); + // Ein Platzhalter hält einen Platz nur dort, wo ihm eine weitere Einheit derselben Art folgt. + // Hier ist die ganze Aufzählung aufgehoben — es bleibt nichts, dessen Bezeichnung zu schonen + // wäre, und der Einleitungssatz steht allein. So hält es auch die amtliche Nachfassung des + // § 14 der hessischen Verkehrsrechts-Zuständigkeitsverordnung. + assertThat(text).isEqualTo("Die Erprobung umfasst"); } // --- Anhang/Anlage als Norm-Ziel ----------------------------------------------------------- |
