diff options
Diffstat (limited to 'src/test/java')
3 files changed, 190 insertions, 7 deletions
diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java index 109bbf6..8c9743d 100644 --- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java +++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java @@ -1927,17 +1927,23 @@ class EndToEndTest { // Kein Befehl des Heftes bleibt mehr ungelesen. assertThat(parseErgebnis.befehle()).noneMatch(b -> b instanceof UnbekannterBefehl); - // Die Verweisung auf einen anderen Punkt desselben Artikels wird gelesen, aber bewusst nicht - // ausgeführt. Der Unterschied ist kein kosmetischer: Die Synopse sagt fortan, dass das - // Erzeugnis hier die Grenze zieht, und nicht, dass die Vorlage unverständlich sei. + // Die Verweisung auf einen anderen Punkt desselben Artikels wird gelesen und ausgeführt: Der + // verwiesene Punkt ändert die Überschrift des § 13, und die Angabe der Inhaltsübersicht wird + // ihr nachgeführt. Hier scheitert das nicht am Erzeugnis, sondern am Gegenstand — diese + // Verordnung führt gar keine Inhaltsübersicht, und die Rüge sagt genau das. var verweisung = befehlAn(parseErgebnis, "12."); assertThat(verweisung).isInstanceOf(VerweisenderBefehl.class); assertThat(((VerweisenderBefehl) verweisung).verweis()).isEqualTo("Nummer 8 Buchst. a"); + assertThat(gesetz.norm("Inhaltsübersicht")).isEmpty(); - var anwendung = BefehlAnwender.anwenden(gesetz, List.of(verweisung)); - assertThat(anwendung.protokoll().get(0).grund()).isEqualTo(Grund.NICHT_UNTERSTUETZT); - assertThat(anwendung.protokoll().get(0).begruendung()) - .contains("verweist auf „Nummer 8 Buchst. a“"); + var anwendung = BefehlAnwender.anwenden(gesetz, parseErgebnis.befehle()); + var protokoll = + anwendung.protokoll().stream() + .filter(a -> a.befehl() == verweisung) + .findFirst() + .orElseThrow(); + assertThat(protokoll.grund()).isEqualTo(Grund.BESTAND_WIDERSPRICHT); + assertThat(protokoll.begruendung()).contains("keine Inhaltsübersicht"); } private static Aenderungsbefehl befehlAn( diff --git a/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java b/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java index 39c71cc..3ed028b 100644 --- a/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java +++ b/src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java @@ -18,6 +18,7 @@ import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturErsetzung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Umnummerierung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.UnbekannterBefehl; +import eu.mulk.aendggner.aenderung.Aenderungsbefehl.VerweisenderBefehl; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WoerterEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker; import eu.mulk.aendggner.aenderung.Provenienz; @@ -1029,6 +1030,81 @@ class BefehlAnwenderTest { .contains("Teil 2 | Verfahren\n§ 3 | Ablauf"); } + // --- Der verweisende Befehl ------------------------------------------------------------------ + + /** + * „Die Inhaltsübersicht wird entsprechend der vorstehenden Nummer 8 Buchst. a geändert.“ Der + * verwiesene Punkt ändert die Überschrift des § 1; die Angabe wird auf den Titel nachgeführt, den + * der Paragraph danach trägt. Übertragen wird also das Ergebnis jenes Punktes und nicht sein + * Wortlaut — das trifft, was „entsprechend“ meint. + */ + @Test + void fuehrtDieInhaltsuebersichtDemVerwiesenenPunktNach() { + var ueberschrift = + new Ersetzung( + new Stelle(List.of(new Stelle.Paragraph("1"), new Stelle.Ueberschrift())), + "Zweck", + "Zweck und Ziel", + false, + false, + new Provenienz("1", "8. a)", "(Test)")); + var verweisung = + new VerweisenderBefehl( + iuStelle(), "Nummer 8 Buchst. a", new Provenienz("1", "12.", "(Test)")); + + var ergebnis = + BefehlAnwender.anwenden(gesetzMitInhaltsuebersicht(), List.of(ueberschrift, verweisung)); + + assertThat(ergebnis.protokoll()).allMatch(a -> a.status() == Status.ANGEWANDT); + assertThat(ergebnis.neu().norm("§ 1").orElseThrow().titel()).isEqualTo("Zweck und Ziel"); + assertThat(absatzText(ergebnis.neu(), "Inhaltsübersicht", 0)) + .contains("§ 1 | Zweck und Ziel") + .doesNotContain("§ 1 | Zweck\n"); + } + + /** + * Was der Verweis nicht trägt, bleibt liegen und wird benannt. Die Inhaltsübersicht führt allein + * Bezeichnung und Überschrift; was im Absatz eines Paragraphen geschieht, hat in ihr kein + * Gegenstück, und es zu erraten wäre schlimmer, als die Grenze zu benennen. + */ + @Test + void ruegtDenVerweisAufEinenPunktOhneGegenstueckInDerUebersicht() { + var imAbsatz = + new Ersetzung( + new Stelle(List.of(new Stelle.Paragraph("1"))), + "Text", + "Wortlaut", + false, + false, + new Provenienz("1", "8. a)", "(Test)")); + var verweisung = + new VerweisenderBefehl( + iuStelle(), "Nummer 8 Buchst. a", new Provenienz("1", "12.", "(Test)")); + + var ergebnis = + BefehlAnwender.anwenden(gesetzMitInhaltsuebersicht(), List.of(imAbsatz, verweisung)); + + var ruege = ergebnis.protokoll().get(1); + assertThat(ruege.status()).isEqualTo(Status.MANUELL_PRUEFEN); + assertThat(ruege.grund()).isEqualTo(Grund.NICHT_UNTERSTUETZT); + assertThat(ruege.begruendung()).contains("ändert keine Überschrift"); + } + + /** Ein Verweis ins Leere ist keine Grenze des Erzeugnisses, sondern ein Befund am Dokument. */ + @Test + void ruegtDenVerweisAufEinenNichtVorhandenenPunkt() { + var verweisung = + new VerweisenderBefehl( + iuStelle(), "Nummer 8 Buchst. a", new Provenienz("1", "12.", "(Test)")); + + var ergebnis = BefehlAnwender.anwenden(gesetzMitInhaltsuebersicht(), List.of(verweisung)); + + var ruege = ergebnis.protokoll().get(0); + assertThat(ruege.status()).isEqualTo(Status.MANUELL_PRUEFEN); + assertThat(ruege.grund()).isEqualTo(Grund.STELLE_NICHT_AUFLOESBAR); + assertThat(ruege.begruendung()).contains("findet sich nicht im selben Artikel"); + } + // --- Gliederungs-Überschriften --------------------------------------------------------------- private static Gesetz gesetzMitGliederungen() { diff --git a/src/test/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtsProbeTest.java b/src/test/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtsProbeTest.java new file mode 100644 index 0000000..742430b --- /dev/null +++ b/src/test/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtsProbeTest.java @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2026 Matthias Andreas Benkard <code@mail.matthias.benkard.de> +// SPDX-License-Identifier: AGPL-3.0-or-later +package eu.mulk.aendggner.anwendung; + +import static org.assertj.core.api.Assertions.assertThat; + +import eu.mulk.aendggner.gesetz.Absatz; +import eu.mulk.aendggner.gesetz.Gesetz; +import eu.mulk.aendggner.gesetz.Norm; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * Die Probe schlägt an, wo ein Lauf den Bestand angerührt und die Inhaltsübersicht zurückgelassen + * hat — und nur dort. Was die Quelle von sich aus ungenau führt, geht sie nichts an. + */ +class InhaltsuebersichtsProbeTest { + + private static Gesetz gesetz(String uebersicht, Norm... normen) { + var alle = new ArrayList<Norm>(); + alle.add( + new Norm("Inhaltsübersicht", null, null, List.of(new Absatz(null, uebersicht)), false)); + alle.addAll(List.of(normen)); + return new Gesetz("TestG", "Testgesetz", null, alle); + } + + private static Norm norm(String enbez, String titel) { + return new Norm(enbez, titel, null, List.of(new Absatz(null, "Text.")), false); + } + + private static final String UEBERSICHT = "§ 1 | Zweck\n§ 2 | Begriffe"; + + @Test + void ruegtDieNichtNachgefuehrteAngabe() { + var alt = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("§ 2", "Begriffe")); + var neu = gesetz(UEBERSICHT, norm("§ 1", "Zweck und Ziel"), norm("§ 2", "Begriffe")); + + assertThat(InhaltsuebersichtsProbe.pruefe(alt, neu)) + .singleElement() + .asString() + .contains("§ 1") + .contains("gehen auseinander"); + } + + @Test + void schweigtWennDieAngabeMitgefuehrtWurde() { + var alt = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("§ 2", "Begriffe")); + var neu = + gesetz( + "§ 1 | Zweck und Ziel\n§ 2 | Begriffe", + norm("§ 1", "Zweck und Ziel"), + norm("§ 2", "Begriffe")); + + assertThat(InhaltsuebersichtsProbe.pruefe(alt, neu)).isEmpty(); + } + + @Test + void ruegtDenEingefuegtenParagraphenOhneAngabe() { + var alt = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("§ 2", "Begriffe")); + var neu = + gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("§ 1a", "Neues"), norm("§ 2", "Begriffe")); + + assertThat(InhaltsuebersichtsProbe.pruefe(alt, neu)) + .singleElement() + .asString() + .contains("keine Angabe zu § 1a"); + } + + @Test + void ruegtDieAngabeZurBeseitigtenNorm() { + var alt = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("§ 2", "Begriffe")); + var neu = gesetz(UEBERSICHT, norm("§ 1", "Zweck")); + + assertThat(InhaltsuebersichtsProbe.pruefe(alt, neu)) + .singleElement() + .asString() + .contains("weiterhin eine Angabe zu § 2"); + } + + /** + * Eine Anlage steht nicht in der Inhaltsübersicht; sie dort zu vermissen hieße, ihr etwas + * abzuverlangen, was sie nie leistet. + */ + @Test + void schweigtZurGeaendertenAnlage() { + var alt = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("Anlage 8", "Muster")); + var neu = gesetz(UEBERSICHT, norm("§ 1", "Zweck"), norm("Anlage 8", "Anderes Muster")); + + assertThat(InhaltsuebersichtsProbe.pruefe(alt, neu)).isEmpty(); + } + + /** Ohne Inhaltsübersicht gibt es nichts zu prüfen — und nichts zu rügen. */ + @Test + void schweigtOhneInhaltsuebersicht() { + var ohne = new Gesetz("TestG", "Testgesetz", null, List.of(norm("§ 1", "Zweck"))); + var geaendert = new Gesetz("TestG", "Testgesetz", null, List.of(norm("§ 1", "Zweck und Ziel"))); + + assertThat(InhaltsuebersichtsProbe.pruefe(ohne, geaendert)).isEmpty(); + } +} |
