diff options
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/java/eu/mulk/aendggner/bericht/KorpusberichtTest.java | 134 | ||||
| -rw-r--r-- | src/test/resources/sampledata/korpus-grundlinie.tsv | 44 | ||||
| -rw-r--r-- | src/test/resources/sampledata/korpus.tsv | 46 |
3 files changed, 224 insertions, 0 deletions
diff --git a/src/test/java/eu/mulk/aendggner/bericht/KorpusberichtTest.java b/src/test/java/eu/mulk/aendggner/bericht/KorpusberichtTest.java new file mode 100644 index 0000000..e709337 --- /dev/null +++ b/src/test/java/eu/mulk/aendggner/bericht/KorpusberichtTest.java @@ -0,0 +1,134 @@ +// SPDX-FileCopyrightText: 2026 Matthias Andreas Benkard <code@mail.matthias.benkard.de> +// SPDX-License-Identifier: AGPL-3.0-or-later +package eu.mulk.aendggner.bericht; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +/** + * Der Massenlauf über den Beispielkorpus, gehalten gegen die eingecheckte Grundlinie. + * + * <p>Die Einzelprüfungen sagen, dass ein bestimmtes Heft aufgeht. Diese sagt, dass keines der + * einunddreißig Hefte hinter das zurückfällt, was es einmal hergegeben hat — und zwar in einer + * Zahl, die sich fortschreiben lässt, statt in Dutzenden verstreuter Behauptungen. + */ +class KorpusberichtTest { + + private static final Path SAMPLEDATA = Path.of("src/test/resources/sampledata"); + private static final Path LISTE = SAMPLEDATA.resolve("korpus.tsv"); + private static final Path GRUNDLINIE = SAMPLEDATA.resolve("korpus-grundlinie.tsv"); + + @Test + void derKorpusFaelltNichtHinterDieGrundlinieZurueck() throws Exception { + assumeTrue(Files.exists(LISTE) && Files.exists(GRUNDLINIE), "Korpusliste fehlt"); + var auftraege = Korpusbericht.liesListe(LISTE); + assumeTrue( + auftraege.stream().allMatch(a -> Files.exists(SAMPLEDATA.resolve(a.stamm()))), + "Beispieldaten des Korpus fehlen"); + + var zeilen = Korpusbericht.fuehreAus(auftraege, SAMPLEDATA.toAbsolutePath(), null); + + // Ein gescheiterter Auftrag hält den Lauf nicht an — unbemerkt bleiben darf er aber nicht; + // sonst meldete der Bericht lauter Nullen und niemand sähe den Grund. + assertThat(zeilen).hasSameSizeAs(auftraege); + assertThat(zeilen).allSatisfy(z -> assertThat(z.fehler()).isNull()); + + var ruegen = + Korpusbericht.gegenGrundlinie(zeilen, Files.readString(GRUNDLINIE, StandardCharsets.UTF_8)); + + assertThat(ruegen) + .as( + "Rückschritte gegenüber der Grundlinie; steht dagegen ein Fortschritt darin, so ist" + + " korpus-grundlinie.tsv fortzuschreiben:\n%s\n\nLauf:\n%s", + String.join("\n", ruegen), Korpusbericht.alsTsv(zeilen)) + .isEmpty(); + } + + @Test + void dieListeWirdVollstaendigGelesen() throws Exception { + assumeTrue(Files.exists(LISTE), "Korpusliste fehlt"); + var auftraege = Korpusbericht.liesListe(LISTE); + + assertThat(auftraege).isNotEmpty(); + // Kommentar- und Leerzeilen sind übergangen, „-“ heißt „nicht angegeben“. + assertThat(auftraege).noneMatch(a -> a.bezeichnung().startsWith("#")); + assertThat(auftraege).allSatisfy(a -> assertThat(a.hefte()).isNotEmpty()); + var mitArtikel = + auftraege.stream().filter(a -> "GEG-BGBl-zeitrichtig".equals(a.bezeichnung())).findFirst(); + assertThat(mitArtikel).isPresent(); + assertThat(mitArtikel.orElseThrow().artikel()).isEqualTo("1"); + assertThat(mitArtikel.orElseThrow().nachfassung()).isNull(); + var mehrereHefte = + auftraege.stream() + .filter(a -> "BayJG-mit-Aenderungsantrag".equals(a.bezeichnung())) + .findFirst() + .orElseThrow(); + assertThat(mehrereHefte.hefte()).hasSize(2); + var mitStichtag = + auftraege.stream() + .filter(a -> "IfSG-Stichtag".equals(a.bezeichnung())) + .findFirst() + .orElseThrow(); + assertThat(mitStichtag.stichtag()).isNotNull(); + } + + @Test + void nurDerRueckschrittWirdGeruegt() { + var grundlinie = + """ + # Bezeichnung\tBefehle\tangewandt\tmanuell\tzurückgestellt\tgleich\tgeprüft\tfehlend\tüberzählig\tabweichend\tGründe + Fall\t10\t8\t2\t0\t20\t22\t1\t0\t1\t- + """; + + var besser = + List.of(new Korpusbericht.Zeile("Fall", 10, 9, 1, 0, 21, 22, 0, 0, 1, Map.of(), null)); + assertThat(Korpusbericht.gegenGrundlinie(besser, grundlinie)).isEmpty(); + + var schlechter = + List.of(new Korpusbericht.Zeile("Fall", 10, 7, 3, 0, 19, 22, 1, 0, 2, Map.of(), null)); + assertThat(Korpusbericht.gegenGrundlinie(schlechter, grundlinie)) + .anySatisfy(r -> assertThat(r).contains("angewandte Befehle 7 statt 8")) + .anySatisfy(r -> assertThat(r).contains("liegengebliebene Befehle 3 statt 2")) + .anySatisfy(r -> assertThat(r).contains("gleiche Normen 19 statt 20")) + .anySatisfy(r -> assertThat(r).contains("abweichende Normen 2 statt 1")); + } + + @Test + void einGescheiterterAuftragWirdGeruegtStattUebergangen() { + var grundlinie = + """ + # Bezeichnung\tBefehle\tangewandt\tmanuell\tzurückgestellt\tgleich\tgeprüft\tfehlend\tüberzählig\tabweichend\tGründe + Fall\t10\t8\t2\t0\t-\t-\t-\t-\t-\t- + """; + + var gescheitert = + List.of( + new Korpusbericht.Zeile( + "Fall", 0, 0, 0, 0, null, null, null, null, null, Map.of(), "IOException: weg")); + assertThat(Korpusbericht.gegenGrundlinie(gescheitert, grundlinie)) + .singleElement() + .asString() + .contains("gescheitert"); + } + + @Test + void einVerschwundenerAuftragFaelltAuf() { + var grundlinie = + """ + # Bezeichnung\tBefehle\tangewandt\tmanuell\tzurückgestellt\tgleich\tgeprüft\tfehlend\tüberzählig\tabweichend\tGründe + Fall\t10\t8\t2\t0\t-\t-\t-\t-\t-\t- + """; + + assertThat(Korpusbericht.gegenGrundlinie(List.of(), grundlinie)) + .singleElement() + .asString() + .contains("ist im Lauf aber nicht vorgekommen"); + } +} diff --git a/src/test/resources/sampledata/korpus-grundlinie.tsv b/src/test/resources/sampledata/korpus-grundlinie.tsv new file mode 100644 index 0000000..60da4f6 --- /dev/null +++ b/src/test/resources/sampledata/korpus-grundlinie.tsv @@ -0,0 +1,44 @@ +# Grundlinie des Korpuslaufs (§ 6d des Handbuchs), Stand 28. August 2026. +# +# Jede Zeile hält fest, was ein Auftrag der Liste „korpus.tsv“ zu diesem Zeitpunkt hergegeben hat. +# Der Lauf wird dagegen gehalten (KorpusberichtTest, „--grundlinie“): Gerügt wird allein, was +# FÄLLT — weniger erschlossene oder angewandte Befehle, weniger gleiche Normen, mehr +# liegengebliebene, fehlende, überzählige oder abweichende. Ein Fortschritt ist kein Fehler, +# sondern der Zweck der Arbeit; er verlangt allein, diese Datei fortzuschreiben. +# +# Die hohen Reste bei GEG-Beschlussempfehlung, IfSG-Beschlussempfehlung und RP-UKAPOGS beruhen +# darauf, dass die Vorlage eine ältere Fassung fortschreibt als die eingesetzte Stammfassung +# („Zieltext nicht vorhanden“); sie sind kein Mangel des Erzeugnisses, wohl aber ein Wächter: +# Steigen sie, hat sich etwas verschlechtert. +# Bezeichnung Befehle angewandt manuell zurückgestellt gleich geprüft fehlend überzählig abweichend Gründe +UWG-BGBl 19 19 0 0 - - - - - - +UWG-RegE 20 20 0 0 - - - - - - +AGG-RegE 24 23 1 0 - - - - - Stelle nicht auffindbar:1 +ProdHaftG-RegE 1 1 0 0 - - - - - - +GEG-BGBl-zeitrichtig 119 119 0 0 - - - - - - +IfSG-BGBl-zeitrichtig 75 75 0 0 - - - - - - +BayJG-GVBl 154 154 0 0 - - - - - - +SN-SaechsBeamtVG 5 5 0 0 - - - - - - +NI-NEFG 7 7 0 0 - - - - - - +SH-Gemeindeordnung 1 1 0 0 167 167 0 0 0 - +SH-Kreisordnung 1 1 0 0 86 86 0 0 0 - +NRW-WDR-Gesetz 101 101 0 0 - - - - - - +NRW-LMG 18 18 0 0 - - - - - - +NRW-TMZ-Gesetz 4 4 0 0 - - - - - - +NRW-17-RAEStV-AusfG 1 1 0 0 - - - - - - +BE-ASOG 6 6 0 0 171 171 0 0 0 - +BE-LAF-ErrG 2 2 0 0 5 5 0 0 0 - +BW-KomWO 37 31 6 0 91 93 0 0 2 Befehl nicht erkannt:6 +HE-StVRZustV 21 21 0 0 52 52 0 0 0 - +TH-KiGaFinVO 10 10 0 0 - - - - - - +BB-FraktG 4 4 0 0 24 24 0 0 0 - +HH-GutachterausschussVO 21 17 4 0 10 14 0 0 4 Befehl nicht erkannt:2; Stelle nicht auffindbar:1; Zieltext nicht vorhanden:1 +HB-BerufsfachschulVO 41 37 4 0 26 29 1 0 2 Befehl nicht erkannt:3; Fundstelle mehrdeutig:1 +MV-APOAmtsTA 24 20 4 0 - - - - - Befehl nicht erkannt:4 +RP-UKAPOGS 23 9 14 0 - - - - - Stelle nicht auffindbar:2; Zieltext nicht vorhanden:10; Bestand widerspricht dem Befehl:2 +GEG-GModG-RegE 97 87 10 0 - - - - - Befehl nicht erkannt:6; Stelle nicht auffindbar:2; Zieltext nicht vorhanden:2 +GEG-Beschlussempfehlung 119 70 49 0 - - - - - Befehl nicht erkannt:1; Stelle nicht auffindbar:3; Zieltext nicht vorhanden:40; Fundstelle mehrdeutig:1; Bestand widerspricht dem Befehl:4 +IfSG-Beschlussempfehlung 75 51 24 0 - - - - - Befehl nicht erkannt:1; Stelle nicht auffindbar:1; Zieltext nicht vorhanden:21; Bestand widerspricht dem Befehl:1 +BayJG-Landtagsentwurf 154 154 0 0 - - - - - - +BayJG-mit-Aenderungsantrag 154 154 0 0 - - - - - - +IfSG-Stichtag 75 65 0 10 - - - - - - diff --git a/src/test/resources/sampledata/korpus.tsv b/src/test/resources/sampledata/korpus.tsv new file mode 100644 index 0000000..2832539 --- /dev/null +++ b/src/test/resources/sampledata/korpus.tsv @@ -0,0 +1,46 @@ +# Auftragsliste des Korpuslaufs (§ 6d des Handbuchs). +# +# Spalten, durch Tabulator getrennt: +# Bezeichnung | Stammfassung | Hefte (durch Komma) | Artikel | Nachfassung | Stichtag +# „-“ heißt: nicht angegeben. Die Pfade beziehen sich auf das Verzeichnis dieser Datei. +# +# Aufgenommen ist, was die Akzeptanzprüfungen des EndToEndTest fahren. Deren Zahlen müssen hier +# unverändert herauskommen; weichen sie ab, liegt der Fehler an der Liste und nicht am Erzeugnis. +# +# Bezeichnung Stamm Hefte Artikel Nachfassung Stichtag +UWG-BGBl UWG/BJNR141400004.xml UWG/bgbl126s0043_regelungstext.pdf - - - +UWG-RegE UWG/BJNR141400004.xml UWG/BT-Drs-21-1855_Regierungsentwurf.pdf - - - +AGG-RegE AGG/BJNR189710006.xml AGG/BT-Drs-21-6178_Regierungsentwurf.pdf - - - +ProdHaftG-RegE ProdHaftG/BJNR021980989.xml ProdHaftG/RegE_Produkthaftungsrecht_2025-12-17.pdf - - - +GEG-BGBl-zeitrichtig GEG/BJNR172810020-2023.xml GEG/bgbl123s0280_regelungstext.pdf 1 - - +IfSG-BGBl-zeitrichtig IfSG/BJNR104510000-2020.xml IfSG/bgbl120s2397_78991.pdf - - - +BayJG-GVBl BayJG/BayJG-alt.txt BayJG/gvbl-2026-06.pdf - - - +SN-SaechsBeamtVG Sachsen/SaechsBeamtVG-alt.txt Sachsen/SaechsGVBl-2026-S134_AendG-SaechsBeamtVG_revosax.pdf - - - +NI-NEFG Niedersachsen/NEFG-alt.txt Niedersachsen/Nds-GVBl-2026-10_ELER-Foerdergesetz-AendG.pdf - - - +SH-Gemeindeordnung SchleswigHolstein/GO-SH-alt.txt SchleswigHolstein/GVOBl-2026-27_Kommunalrecht-AendG.pdf 1 SchleswigHolstein/GO-SH-neu.txt - +SH-Kreisordnung SchleswigHolstein/KrO-SH-alt.txt SchleswigHolstein/GVOBl-2026-27_Kommunalrecht-AendG.pdf 2 SchleswigHolstein/KrO-SH-neu.txt - +NRW-WDR-Gesetz NRW/WDR-Gesetz-alt.txt NRW/GV-NRW-2026-S202_22-Rundfunkaenderungsgesetz.pdf - - - +NRW-LMG NRW/LMG-NRW-alt.txt NRW/GV-NRW-2026-S202_22-Rundfunkaenderungsgesetz.pdf - - - +NRW-TMZ-Gesetz NRW/TMZ-Gesetz-alt.txt NRW/GV-NRW-2026-S202_22-Rundfunkaenderungsgesetz.pdf - - - +NRW-17-RAEStV-AusfG NRW/17-RAEStV-AusfG-alt.txt NRW/GV-NRW-2026-S202_22-Rundfunkaenderungsgesetz.pdf - - - +BE-ASOG Berlin/ASOG-Bln-alt.txt Berlin/GVBl-2026-17_ASOG-LAF-AendG.pdf 1 Berlin/ASOG-Bln-neu.txt - +BE-LAF-ErrG Berlin/LAF-ErrG-alt.txt Berlin/GVBl-2026-17_ASOG-LAF-AendG.pdf 2 Berlin/LAF-ErrG-neu.txt - +BW-KomWO BadenWuerttemberg/KomWO-BW-alt.txt BadenWuerttemberg/GBl-2026-26_KommunalwahlO-AendVO.pdf - BadenWuerttemberg/KomWO-BW-neu.txt - +HE-StVRZustV Hessen/StVRZustV-alt.txt Hessen/GVBl-2026-05_11-AendVO-verkehrsrechtl-Zustaendigkeiten.pdf - Hessen/StVRZustV-neu.txt - +TH-KiGaFinVO Thueringen/ThuerKigaFinVO-alt.txt Thueringen/GVBl-TH-2026-02_KiGaFinanzVO-AendVO-ua.pdf - - - +BB-FraktG Brandenburg/FraktG-alt.txt Brandenburg/GVBl-I-2026-12_FraktG-AendG.pdf - Brandenburg/FraktG-neu.txt - +HH-GutachterausschussVO Hamburg/GAusschV-HH-alt.txt Hamburg/HmbGVBl-2026-17_GutachterausschussVO-AendVO.pdf - Hamburg/GAusschV-HH-neu.txt - +HB-BerufsfachschulVO Bremen/AssBerFSchulV-BR-alt.txt Bremen/BremGBl-2026-87_BerufsfachschulVO-AendVO.pdf - Bremen/AssBerFSchulV-BR-neu.txt - +MV-APOAmtsTA MecklenburgVorpommern/APOAmtsTA-MV-alt.txt MecklenburgVorpommern/GVOBl-MV-2026-21_Besoldungsanpassung-ua.pdf 44 - - +# Rheinland-Pfalz führt keine Vorfassungen; angewandt wird deshalb auf die Nachfassung, und +# aussagekräftig ist allein die Zahl der erschlossenen Befehle (23). Die liegengebliebenen sind +# die Folge des falschen Standes, nicht eines Mangels — siehe § 13 Absatz 4 des Handbuchs. +RP-UKAPOGS RheinlandPfalz/UKAPOGS-E3-neu.txt RheinlandPfalz/GVBl-2026-21_UKAPOGS-E3-AendVO.pdf - - - +# Entwürfe und Zusammenstellungen: hier gibt es keine Nachfassung, wohl aber die Frage, wie viel +# eine Vorlage hergibt. +GEG-GModG-RegE GEG/BJNR172810020.xml GEG/Regierungsentwurf_GModG_2026-05-13.pdf - - - +GEG-Beschlussempfehlung GEG/BJNR172810020.xml GEG/BT-Drs-20-7619_Beschlussempfehlung.pdf - - - +IfSG-Beschlussempfehlung IfSG/BJNR104510000.xml IfSG/1924334.pdf - - - +BayJG-Landtagsentwurf BayJG/BayJG-alt.txt BayJG/Ltg-Drs-19-9707_Gesetzentwurf.pdf - - - +BayJG-mit-Aenderungsantrag BayJG/BayJG-alt.txt BayJG/Ltg-Drs-19-9707_Gesetzentwurf.pdf,BayJG/Ltg-Drs-19-10365_Aenderungsantrag-Gruene.pdf - - - +IfSG-Stichtag IfSG/BJNR104510000-2020.xml IfSG/bgbl120s2397_78991.pdf - - 2020-11-19 |
