aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/eu
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/eu')
-rw-r--r--src/test/java/eu/mulk/aendggner/EndToEndTest.java20
-rw-r--r--src/test/java/eu/mulk/aendggner/anwendung/BefehlAnwenderTest.java76
-rw-r--r--src/test/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtsProbeTest.java101
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();
+ }
+}