blob: 8a1b1e094a5938be2128b633d2e235b1a34e9351 [file] [log] [blame]
package eu.mulk.aendggner.anwendung;
import static org.assertj.core.api.Assertions.assertThat;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Anfuegung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Aufhebung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ebene;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ersetzung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Neufassung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Sammelbefehl;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Streichung;
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.WoerterEinfuegung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker;
import eu.mulk.aendggner.aenderung.Provenienz;
import eu.mulk.aendggner.aenderung.Stelle;
import eu.mulk.aendggner.anwendung.BefehlAnwender.Status;
import eu.mulk.aendggner.gesetz.Absatz;
import eu.mulk.aendggner.gesetz.Gesetz;
import eu.mulk.aendggner.gesetz.Norm;
import java.util.List;
import org.junit.jupiter.api.Test;
class BefehlAnwenderTest {
private static final Provenienz PROV = new Provenienz("1", "1.", "(Test)");
private static Stelle stelle(Stelle.Komponente... komponenten) {
return new Stelle(List.of(komponenten));
}
@Test
void wendetErsetzungAn() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
"die Erprobung",
"die gründliche Erprobung",
false,
false,
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes ist die gründliche Erprobung.");
}
@Test
void meldetFehlendenAltTextAlsManuellPruefen() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
"gibt es nicht",
"egal",
false,
false,
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
var eintrag = ergebnis.protokoll().get(0);
assertThat(eintrag.status()).isEqualTo(Status.MANUELL_PRUEFEN);
assertThat(eintrag.begruendung()).contains("kommt im Zieltext nicht vor");
// Das Gesetz bleibt unverändert.
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes ist die Erprobung.");
}
@Test
void meldetMehrdeutigeErsetzungOhneJeweils() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("2")), "Prüfung", "Untersuchung", false, false, PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.MANUELL_PRUEFEN);
assertThat(ergebnis.protokoll().get(0).begruendung()).contains("mehrdeutig");
}
@Test
void wendetJeweilsErsetzungAufAlleVorkommenAn() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("2")), "Prüfung", "Untersuchung", true, false, PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 2", 0))
.contains("die Untersuchung der Tauglichkeit")
.contains("Die Untersuchung erfolgt");
}
@Test
void wendetErsetzungInSatzAn() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("2"), new Stelle.SatzNr("2")),
"sorgfältig",
"gewissenhaft",
false,
false,
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 2", 0)).contains("erfolgt gewissenhaft");
}
@Test
void wendetErsetzungInNummerAn() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("2")),
"Befehlen",
"Änderungsbefehlen",
false,
false,
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 1))
.contains("2. die Anwendung von Änderungsbefehlen und");
}
@Test
void wendetPunktZuKommaErsetzungAmEndeAn() {
var befehl =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("3")),
".",
",",
false,
true,
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 1)).contains("3. die Ausgabe von Synopsen,");
}
@Test
void wendetNeufassungEinesAbsatzesAn() {
var befehl =
new Neufassung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
"(1) Zweck dieses Gesetzes ist die umfassende Erprobung.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes ist die umfassende Erprobung.");
}
@Test
void wendetNeufassungEinesParagraphenAn() {
var befehl =
new Neufassung(
stelle(new Stelle.Paragraph("2")),
"§ 2 Begriffsbestimmungen (1) Erprobung ist die Untersuchung. (2) Bericht ist das"
+ " Ergebnis.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 2").orElseThrow();
assertThat(norm.titel()).isEqualTo("Begriffsbestimmungen");
assertThat(norm.absaetze()).hasSize(2);
assertThat(norm.absaetze().get(0).nummer()).isEqualTo("1");
assertThat(norm.absaetze().get(1).text()).isEqualTo("Bericht ist das Ergebnis.");
}
@Test
void fuegtParagraphEin() {
var befehl =
new StrukturEinfuegung(
stelle(new Stelle.Paragraph("2")),
false,
Ebene.PARAGRAPH,
"2a",
"§ 2a Verfahren (1) Das Verfahren ist einfach.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var enbezListe = ergebnis.neu().normen().stream().map(Norm::enbez).toList();
assertThat(enbezListe).containsExactly("§ 1", "§ 2", "§ 2a", "§ 3");
var neueNorm = ergebnis.neu().norm("§ 2a").orElseThrow();
assertThat(neueNorm.titel()).isEqualTo("Verfahren");
assertThat(neueNorm.absaetze().get(0).text()).isEqualTo("Das Verfahren ist einfach.");
}
@Test
void meldetBereitsVorhandenenParagraphen() {
var befehl =
new StrukturEinfuegung(
stelle(new Stelle.Paragraph("1")), false, Ebene.PARAGRAPH, "2", "§ 2 Doppelt", PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.MANUELL_PRUEFEN);
assertThat(ergebnis.protokoll().get(0).begruendung()).contains("existiert bereits");
}
@Test
void fuegtWoerterNachAnkerEin() {
var befehl =
new WoerterEinfuegung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
new WortAnker.NachWoertern("Gesetzes"),
"und dieser Verordnung",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes und dieser Verordnung ist die Erprobung.");
}
@Test
void fuegtAbsatzAn() {
var befehl =
new Anfuegung(
stelle(new Stelle.Paragraph("3")),
Ebene.ABSATZ,
"2",
"(2) Es tritt nie außer Kraft.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 3").orElseThrow();
assertThat(norm.absaetze()).hasSize(2);
assertThat(norm.absaetze().get(1).nummer()).isEqualTo("2");
}
@Test
void hebtParagraphenAuf() {
var befehl = new Aufhebung(stelle(new Stelle.Paragraph("2")), PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 2").orElseThrow();
assertThat(norm.weggefallen()).isTrue();
assertThat(norm.gesamtText()).isEqualTo("(weggefallen)");
}
@Test
void hebtAbsatzAuf() {
var befehl = new Aufhebung(stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2")), PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 1", 1)).isEqualTo("(weggefallen)");
}
@Test
void streichtWoerter() {
var befehl =
new Streichung(
stelle(new Stelle.Paragraph("2"), new Stelle.SatzNr("2")), "sorgfältig", PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 2", 0)).contains("Die Prüfung erfolgt.");
}
@Test
void nummeriertAbsatzUm() {
var befehl =
new Umnummerierung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2")),
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("3")),
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 1").orElseThrow();
assertThat(norm.absaetze().get(1).nummer()).isEqualTo("3");
}
@Test
void meldetUnbekanntenBefehlAlsManuellPruefen() {
var befehl = new UnbekannterBefehl(Stelle.LEER, "Die Nummern 1 bis 3 werden aufgehoben.", PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.MANUELL_PRUEFEN);
assertThat(ergebnis.anzahlManuell()).isEqualTo(1);
assertThat(ergebnis.anzahlAngewandt()).isEqualTo(0);
}
@Test
void ersetztAbsatzDurchMehrereAbsaetze() {
var befehl =
new StrukturErsetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
Ebene.ABSATZ,
"(1) Zweck ist die Erprobung. (1a) Die Erprobung ist wichtig.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 1").orElseThrow();
assertThat(norm.absaetze()).hasSize(3);
assertThat(norm.absaetze().get(0).nummer()).isEqualTo("1");
assertThat(norm.absaetze().get(1).nummer()).isEqualTo("1a");
assertThat(norm.absaetze().get(1).text()).isEqualTo("Die Erprobung ist wichtig.");
assertThat(norm.absaetze().get(2).nummer()).isEqualTo("2");
}
@Test
void ersetztSatzDurchMehrereSaetze() {
var befehl =
new StrukturErsetzung(
stelle(new Stelle.Paragraph("2"), new Stelle.SatzNr("2")),
Ebene.SATZ,
"Die Prüfung erfolgt gewissenhaft. Sie wird dokumentiert.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 2", 0))
.contains(
"Erprobung ist die Prüfung der Tauglichkeit. Die Prüfung erfolgt gewissenhaft."
+ " Sie wird dokumentiert. Sie endet mit einem Bericht.");
}
@Test
void fuegtSatzNachSatzEin() {
var befehl =
new StrukturEinfuegung(
stelle(new Stelle.Paragraph("2"), new Stelle.SatzNr("1")),
false,
Ebene.SATZ,
null,
"Die Tauglichkeit ist zu dokumentieren.",
PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(absatzText(ergebnis.neu(), "§ 2", 0))
.contains(
"Erprobung ist die Prüfung der Tauglichkeit. Die Tauglichkeit ist zu dokumentieren."
+ " Die Prüfung erfolgt sorgfältig.");
}
// --- Helfer --------------------------------------------------------------------------------
@Test
void wendetSammelbefehlAlsEinenEintragAn() {
var teil1 =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
"Erprobung",
"Prüfung",
false,
false,
PROV);
var teil2 =
new Ersetzung(
stelle(new Stelle.Paragraph("2")), "Erprobung", "Prüfung", false, false, PROV);
var sammel = new Sammelbefehl(List.of(teil1, teil2));
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(sammel));
// Ein Befehl → genau ein Protokolleintrag, aber beide Teiledits wirken.
assertThat(ergebnis.protokoll()).hasSize(1);
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
assertThat(ergebnis.protokoll().get(0).betroffeneEnbez()).containsExactlyInAnyOrder("§ 1", "§ 2");
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes ist die Prüfung.");
assertThat(absatzText(ergebnis.neu(), "§ 2", 0)).startsWith("Prüfung ist die Prüfung");
}
@Test
void sammelbefehlMitFehlschlagendemTeilWirdManuell() {
var teil1 =
new Ersetzung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("1")),
"Erprobung",
"Prüfung",
false,
false,
PROV);
var teil2 =
new Ersetzung(
stelle(new Stelle.Paragraph("2")), "gibt es nicht", "egal", false, false, PROV);
var sammel = new Sammelbefehl(List.of(teil1, teil2));
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(sammel));
assertThat(ergebnis.protokoll()).hasSize(1);
var eintrag = ergebnis.protokoll().get(0);
assertThat(eintrag.status()).isEqualTo(Status.MANUELL_PRUEFEN);
assertThat(eintrag.begruendung()).contains("Teil 2");
// Der gelungene Teil bleibt trotzdem wirksam.
assertThat(absatzText(ergebnis.neu(), "§ 1", 0))
.isEqualTo("Zweck dieses Gesetzes ist die Prüfung.");
}
private static Gesetz gesetz() {
return new Gesetz(
"TestG",
"Gesetz zur Erprobung",
"Testgesetz",
List.of(
new Norm(
"§ 1",
"Zweck",
null,
List.of(
new Absatz("1", "Zweck dieses Gesetzes ist die Erprobung."),
new Absatz(
"2",
"Die Erprobung umfasst\n"
+ " 1. das Einlesen von Gesetzen,\n"
+ " 2. die Anwendung von Befehlen und\n"
+ " 3. die Ausgabe von Synopsen.")),
false),
new Norm(
"§ 2",
"Begriffe",
null,
List.of(
new Absatz(
null,
"Erprobung ist die Prüfung der Tauglichkeit. Die Prüfung erfolgt"
+ " sorgfältig. Sie endet mit einem Bericht.")),
false),
new Norm(
"§ 3",
"Schlussvorschriften",
null,
List.of(new Absatz("1", "Dieses Gesetz tritt am 1. Januar 2021 in Kraft.")),
false)));
}
@Test
void wendetWortlautZuAbsatzAn() {
// § 2 hat einen unnummerierten Wortlaut, der zu Absatz 1 wird.
var befehl =
new eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortlautZuAbsatz(
stelle(new Stelle.Paragraph("2")), "1", PROV);
var ergebnis = BefehlAnwender.anwenden(gesetz(), List.of(befehl));
assertThat(ergebnis.protokoll().get(0).status()).isEqualTo(Status.ANGEWANDT);
var norm = ergebnis.neu().norm("§ 2").orElseThrow();
assertThat(norm.absaetze()).hasSize(1);
assertThat(norm.absaetze().get(0).nummer()).isEqualTo("1");
assertThat(norm.absaetze().get(0).anzeigeText()).startsWith("(1) Erprobung ist");
}
@Test
void wendetBereichsAufhebungAn() {
// „Die Nummern 1 bis 3 werden aufgehoben.“ innerhalb von § 1 Absatz 2.
var teile =
List.<eu.mulk.aendggner.aenderung.Aenderungsbefehl>of(
new Aufhebung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("1")),
PROV),
new Aufhebung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("2")),
PROV),
new Aufhebung(
stelle(new Stelle.Paragraph("1"), new Stelle.AbsatzNr("2"), new Stelle.NummerNr("3")),
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)");
}
private static String absatzText(Gesetz gesetz, String enbez, int index) {
return gesetz.norm(enbez).orElseThrow().absaetze().get(index).text();
}
}