From d9d2542a20c17b748b2173256c7df7ee35bbf819 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 16 Sep 2026 10:23:45 +0200 Subject: [PATCH] =?UTF-8?q?Test-Audit=20einf=C3=BChren:=20Pr=C3=BCfstatus?= =?UTF-8?q?=20je=20Testfall=20im=20Pr=C3=BCfstand=20sichtbar=20machen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ticket #16. docs/status/testpruefungen.json hält je Testfall Datum und Kurzprüfsumme der letzten fachlichen Prüfung fest; scripts/testkatalog.py liest das und zeigt es als eigene Spalte/Pille (nie geprüft / geprüft am … / veraltet seit Änderung …), unabhängig vom Baseline-Status. Neues Skript scripts/test_audit.py (status/markieren) pflegt die Datei; erste Tests für scripts/ unter scripts/tests/. Co-Authored-By: Claude Sonnet 5 --- docs/architektur/modulkarte.md | 6 + docs/leitfaden/06_tests.md | 37 +- docs/tests/testkatalog.html | 73 +-- docs/tests/testkatalog.md | 827 ++++++++++++++++--------------- docs/wissen/fallstricke.md | 15 + scripts/test_audit.py | 192 +++++++ scripts/testkatalog.py | 174 ++++++- scripts/tests/test_test_audit.py | 222 +++++++++ 8 files changed, 1079 insertions(+), 467 deletions(-) create mode 100644 scripts/test_audit.py create mode 100644 scripts/tests/test_test_audit.py diff --git a/docs/architektur/modulkarte.md b/docs/architektur/modulkarte.md index 0bab1bb..82b7f46 100644 --- a/docs/architektur/modulkarte.md +++ b/docs/architektur/modulkarte.md @@ -124,6 +124,12 @@ Dient als **minimales Muster** für ein neues Fachplugin (Skill `sn-neues-fachpl | `Linkliste` | `linkliste.csv` → Gitea Action erzeugt XML/JSON/YAML | | `Defaults` | Beispiel-Verfahrensdaten (JSON) und `styles/verfahrensgebiet.qml`; nicht vom Code referenziert | +## Workspace-Skripte (dieses Repository, `scripts/`) + +| Pfad | Zweck | +|---|---| +| `scripts/test_audit.py` | Prüf-Audit: zeigt (`status`) und markiert (`markieren`) je Testfall, wann er zuletzt fachlich geprüft wurde; schreibt `docs/status/testpruefungen.json`. Nutzt die Katalog-Logik aus `scripts/testkatalog.py`, siehe `docs/leitfaden/06_tests.md` Abschnitt 7. | + ## Größte Dateien (Kandidaten für das spätere Refactoring) | Datei | Zeilen | diff --git a/docs/leitfaden/06_tests.md b/docs/leitfaden/06_tests.md index 14956e2..938eae9 100644 --- a/docs/leitfaden/06_tests.md +++ b/docs/leitfaden/06_tests.md @@ -1,7 +1,7 @@ # Tests: was geprüft wird, wie man es liest, was Pflicht ist Stand 04.09.2026. Für alle, die an den LNO-Plugins mitarbeiten — auch für Fachleute ohne Programmiererfahrung. -Der Abschnitt 7 ist ausdrücklich für Sie geschrieben: dort geht es darum, zu **beurteilen**, ob eine Testsuite +Der Abschnitt 8 ist ausdrücklich für Sie geschrieben: dort geht es darum, zu **beurteilen**, ob eine Testsuite fachlich das Richtige prüft. Dafür muss man keinen Code lesen können. ## 1. Warum das hier ernster genommen wird als sonst @@ -116,7 +116,34 @@ vollständig lesbar zu machen. Nach dem Hinzufügen von Tests den Katalog neu erzeugen und mit committen. `python scripts/testkatalog.py --pruefen` meldet, wenn er veraltet ist. -## 7. Testkonzepte: prüfen, ob die Tests fachlich sinnvoll sind +## 7. Test-Audit: wann wurde ein Test zuletzt fachlich geprüft? + +Der Testkatalog beantwortet „was prüft die Suite" und „läuft der Test durch" (Baseline, Abschnitt 8). Er +beantwortet **nicht** „hat das ein Mensch fachlich bestätigt". Ein Agent kann einen überzeugenden, aber +fachlich falschen Test schreiben (Abschnitt 1) — weder Docstring noch Baseline zeigen das. Das Test-Audit +schließt diese Lücke: `docs/status/testpruefungen.json` hält je Testfall Datum und Kurzprüfsumme der letzten +Prüfung fest. Ändert sich der Testcode danach, erkennt der Prüfstand das automatisch als **veraltet** — die +Prüfsumme stimmt nicht mehr überein. + +Im Prüfstand (`docs/tests/testkatalog.html`) erscheint das als eigene Spalte/Pille je Testfall (unabhängig vom +Baseline-Status: ein grüner Test kann nie geprüft sein, ein roter Baseline-Test kann bereits geprüft sein) und +als eigene Filter-Chips „Nie geprüft" / „Veraltet geprüft". + +```bash +python scripts/test_audit.py status sn_verfahrensgebiet # Prüfstatus je Testfall anzeigen +python scripts/test_audit.py status --nur ungeprueft # nur ungeprüfte Testfälle +python scripts/test_audit.py markieren sn_basis TestX.test_y # als heute geprüft markieren +``` + +`markieren` nimmt exakte Bezeichner oder `fnmatch`-Muster (z. B. `"TestX.*"`) entgegen; `--trocken` zeigt die +Treffer, ohne zu schreiben — vor einem Muster mit vielen Treffern empfohlen. Das Skript importiert die +Katalog-Logik aus `scripts/testkatalog.py`, statt sie zu duplizieren. + +Abgrenzung zu Abschnitt 8 (Testkonzepte): Das Audit bestätigt, dass **vorhandene** Tests noch fachlich +zutreffen. Ob überhaupt genug getestet wird, zeigen die Testkonzept-Seiten — das ist der nächste, gesonderte +Schritt, kein Ersatz für das Audit. + +## 8. Testkonzepte: prüfen, ob die Tests fachlich sinnvoll sind Der Katalog beantwortet „was wird getestet". Er beantwortet **nicht** „ist das genug". Dafür gibt es je wichtigem Fachablauf eine eigene Seite in [`docs/tests/`](../tests/), nach der Vorlage @@ -143,7 +170,7 @@ Ein Beispiel liegt in [`docs/tests/verfahrensgebiet-shape-import.md`](../tests/v Wenn Sie eine Lücke finden: Issue aufmachen (`python scripts/gitea.py entwurf issue Verfahrensgebiet` legt einen Entwurf an). Eine gefundene Testlücke ist ein vollwertiges Ticket. -## 8. Die Baseline +## 9. Die Baseline Nicht alle Tests sind grün. Der Ist-Stand steht in [`docs/status/testbaseline.json`](../status/testbaseline.json) und wirkt als Sperrklinke: **bekannte rote Tests dürfen bleiben, neue nicht dazukommen.** @@ -159,7 +186,7 @@ python scripts/run_tests.py sn_verfahrensgebiet --baseline Die Baseline ändert **nur ein Maintainer** mit `--update-baseline`, nach Absprache. Ein Agent fasst sie nicht an. Das Grünmachen der bekannten roten Tests läuft über eigene Issues, nicht nebenbei. -## 9. Wenn ein Test rot ist +## 10. Wenn ein Test rot ist Erst die Frage beantworten: **Ist der Test veraltet oder ist der Code falsch?** @@ -177,7 +204,7 @@ das ist das Verstecken des Problems vor dem nächsten Leser. Details zum Deuten einzelner Fehler: Skill `sn-tests`. -## 10. Vor dem Pull Request +## 11. Vor dem Pull Request - [ ] `python scripts/run_tests.py --baseline` ohne `NEU ROT` - [ ] Neue Funktionalität hat mindestens einen Test je neuem Verhalten diff --git a/docs/tests/testkatalog.html b/docs/tests/testkatalog.html index d09fbcb..397b045 100644 --- a/docs/tests/testkatalog.html +++ b/docs/tests/testkatalog.html @@ -87,6 +87,7 @@ .cpill{ font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-size:11.5px; padding:2px 7px; border-radius:999px; font-weight:600; } .cpill-ok{ background:var(--ok-bg); color:var(--ok); } .cpill-warn{ background:var(--warn-bg); color:var(--warn); } .cpill-skip{ background:var(--skip-bg); color:var(--skip); } .docbadge{ color:var(--muted); border:1px solid var(--line-strong); border-radius:999px; padding:2px 8px; } + .auditbadge{ color:var(--muted); border:1px solid var(--line-strong); border-radius:999px; padding:2px 8px; } .chev{ color:var(--muted); transition:transform .15s ease; } .filecard.open .chev{ transform:rotate(180deg); } .card-body{ max-height:0; overflow:hidden; transition:max-height .22s ease; border-top:0 solid var(--line); } @@ -110,6 +111,7 @@ .nodoc{ color:var(--muted); font-style:italic; } .pill{ font-size:11.5px; padding:2px 8px; border-radius:999px; font-weight:600; white-space:nowrap; } .pill-ok{ background:var(--ok-bg); color:var(--ok); } .pill-warn{ background:var(--warn-bg); color:var(--warn); } .pill-skip{ background:var(--skip-bg); color:var(--skip); } + .pill-pr-ok{ background:var(--ok-bg); color:var(--ok); } .pill-pr-warn{ background:var(--warn-bg); color:var(--warn); } .pill-pr-skip{ background:var(--skip-bg); color:var(--skip); } footer{ max-width:1180px; margin:40px auto 30px; color:var(--muted); font-size:12px; border-top:1px solid var(--line); padding-top:14px; } [hidden]{ display:none !important; } @media (max-width:640px){ .pkg-bar{ width:130px; } .controls{ position:static; } } @@ -117,13 +119,14 @@

Prüfstand

Testkatalog der sn_*-Plugins — was die Suite heute prüft, auf einen Blick.
-
Quelle: docs/tests/testkatalog.md
Baseline: docs/status/testbaseline.json (SHA-256 aeabc946a7f3)
+
Quelle: docs/tests/testkatalog.md
Baseline: docs/status/testbaseline.json (SHA-256 aeabc946a7f3)
Prüf-Audit docs/status/testpruefungen.json nicht gefunden
346Testfälle
301grün
37rot (Baseline)
33%mit Docstring
+
0%aktuell geprüft
31Testdateien
Verteilung je Paket
@@ -140,6 +143,8 @@ + +
@@ -153,7 +158,7 @@ -

— (Docstring fehlt)

Keine Testfälle: Die Datei enthält keine unittest.TestCase-Klasse – sie ist eine reine Hilfsdatei, die beim Testlauf nur importiert wird.

— (Docstring fehlt)

TestDataGrabber 6
flowchart TD
+  

— (Docstring fehlt)

Keine Testfälle: Die Datei enthält keine unittest.TestCase-Klasse – sie ist eine reine Hilfsdatei, die beim Testlauf nur importiert wird.

— (Docstring fehlt)

TestDataGrabber 6
flowchart TD
   root(["test_datagrabber.py"])
   class root rootnode
   root --> g1["TestDataGrabber (6)"]
@@ -174,7 +179,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestDataGrabber
test_analyze_source_type_detects_excel
— (Docstring fehlt)grün
TestDataGrabber
test_analyze_source_type_returns_unknown_filetype
— (Docstring fehlt)grün
TestDataGrabber
test_analyze_source_type_detects_service_when_file_check_fails
— (Docstring fehlt)grün
TestDataGrabber
test_analyze_source_type_returns_unbekannte_quelle_on_full_failure
— (Docstring fehlt)grün
TestDataGrabber
test_run_returns_success_summary_with_valid_rows
— (Docstring fehlt)grün
TestDataGrabber
test_run_returns_failure_summary_without_rows
— (Docstring fehlt)grün

— (Docstring fehlt)

TestDateipruefer 6
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestDataGrabber
test_analyze_source_type_detects_excel
— (Docstring fehlt)grünnie geprüft
TestDataGrabber
test_analyze_source_type_returns_unknown_filetype
— (Docstring fehlt)grünnie geprüft
TestDataGrabber
test_analyze_source_type_detects_service_when_file_check_fails
— (Docstring fehlt)grünnie geprüft
TestDataGrabber
test_analyze_source_type_returns_unbekannte_quelle_on_full_failure
— (Docstring fehlt)grünnie geprüft
TestDataGrabber
test_run_returns_success_summary_with_valid_rows
— (Docstring fehlt)grünnie geprüft
TestDataGrabber
test_run_returns_failure_summary_without_rows
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestDateipruefer 6
flowchart TD
   root(["test_dateipruefer.py"])
   class root rootnode
   root --> g1["TestDateipruefer (6)"]
@@ -195,7 +200,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestDateipruefer
test_leereingabe_erlaubt
— (Docstring fehlt)grün
TestDateipruefer
test_leereingabe_nicht_erlaubt
— (Docstring fehlt)grün
TestDateipruefer
test_standarddatei_vorschlagen
— (Docstring fehlt)grün
TestDateipruefer
test_temporaer_erlaubt
— (Docstring fehlt)grün
TestDateipruefer
test_datei_nicht_gefunden
— (Docstring fehlt)grün
TestDateipruefer
test_datei_ok
— (Docstring fehlt)grün

Unit-Tests für `sn_basis.functions.laenderkennung`.

TestGetLaenderkennung 5
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestDateipruefer
test_leereingabe_erlaubt
— (Docstring fehlt)grünnie geprüft
TestDateipruefer
test_leereingabe_nicht_erlaubt
— (Docstring fehlt)grünnie geprüft
TestDateipruefer
test_standarddatei_vorschlagen
— (Docstring fehlt)grünnie geprüft
TestDateipruefer
test_temporaer_erlaubt
— (Docstring fehlt)grünnie geprüft
TestDateipruefer
test_datei_nicht_gefunden
— (Docstring fehlt)grünnie geprüft
TestDateipruefer
test_datei_ok
— (Docstring fehlt)grünnie geprüft

Unit-Tests für `sn_basis.functions.laenderkennung`.

TestGetLaenderkennung 5
flowchart TD
   root(["test_laenderkennung.py"])
   class root rootnode
   root --> g1["TestGetLaenderkennung (5)"]
@@ -214,7 +219,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestGetLaenderkennung
test_bekannter_praefix_gibt_kennung_zurueck
— (Docstring fehlt)grün
TestGetLaenderkennung
test_praefix_gross_klein_unabhaengig
— (Docstring fehlt)grün
TestGetLaenderkennung
test_unbekannter_praefix_wirft_keyerror
— (Docstring fehlt)grün
TestGetLaenderkennung
test_ohne_argument_wird_aus_aufrufendem_modul_abgeleitet
— (Docstring fehlt)grün
TestGetLaenderkennung
test_mapping_enthaelt_sachsen
— (Docstring fehlt)grün

— (Docstring fehlt)

TestLayerpruefer 10
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestGetLaenderkennung
test_bekannter_praefix_gibt_kennung_zurueck
— (Docstring fehlt)grünnie geprüft
TestGetLaenderkennung
test_praefix_gross_klein_unabhaengig
— (Docstring fehlt)grünnie geprüft
TestGetLaenderkennung
test_unbekannter_praefix_wirft_keyerror
— (Docstring fehlt)grünnie geprüft
TestGetLaenderkennung
test_ohne_argument_wird_aus_aufrufendem_modul_abgeleitet
— (Docstring fehlt)grünnie geprüft
TestGetLaenderkennung
test_mapping_enthaelt_sachsen
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestLayerpruefer 10
flowchart TD
   root(["test_layerpruefer.py"])
   class root rootnode
   root --> g1["TestLayerpruefer (10)"]
@@ -243,7 +248,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestLayerpruefer
test_layer_exists
— (Docstring fehlt)grün
TestLayerpruefer
test_layer_unsichtbar
— (Docstring fehlt)grün
TestLayerpruefer
test_falscher_layertyp
— (Docstring fehlt)grün
TestLayerpruefer
test_falscher_geotyp
— (Docstring fehlt)grün
TestLayerpruefer
test_layer_leer
— (Docstring fehlt)grün
TestLayerpruefer
test_falsches_crs
— (Docstring fehlt)grün
TestLayerpruefer
test_felder_fehlen
— (Docstring fehlt)grün
TestLayerpruefer
test_datenquelle_unerwartet
— (Docstring fehlt)grün
TestLayerpruefer
test_layer_nicht_editierbar
— (Docstring fehlt)grün
TestLayerpruefer
test_layer_ok
— (Docstring fehlt)grün

— (Docstring fehlt)

TestLinkpruefer 5
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestLayerpruefer
test_layer_exists
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_layer_unsichtbar
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_falscher_layertyp
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_falscher_geotyp
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_layer_leer
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_falsches_crs
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_felder_fehlen
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_datenquelle_unerwartet
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_layer_nicht_editierbar
— (Docstring fehlt)grünnie geprüft
TestLayerpruefer
test_layer_ok
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestLinkpruefer 5
flowchart TD
   root(["test_linkpruefer.py"])
   class root rootnode
   root --> g1["TestLinkpruefer (5)"]
@@ -262,7 +267,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestLinkpruefer
test_remote_link_ok
— (Docstring fehlt)grün
TestLinkpruefer
test_remote_link_error
— (Docstring fehlt)grün
TestLinkpruefer
test_remote_link_network_error
— (Docstring fehlt)grün
TestLinkpruefer
test_local_link_not_found
— (Docstring fehlt)grün
TestLinkpruefer
test_local_link_ok
— (Docstring fehlt)grün

— (Docstring fehlt)

TestPrintLayout 5
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestLinkpruefer
test_remote_link_ok
— (Docstring fehlt)grünnie geprüft
TestLinkpruefer
test_remote_link_error
— (Docstring fehlt)grünnie geprüft
TestLinkpruefer
test_remote_link_network_error
— (Docstring fehlt)grünnie geprüft
TestLinkpruefer
test_local_link_not_found
— (Docstring fehlt)grünnie geprüft
TestLinkpruefer
test_local_link_ok
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestPrintLayout 5
flowchart TD
   root(["test_print_layout.py"])
   class root rootnode
   root --> g1["TestPrintLayout (5)"]
@@ -281,7 +286,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestPrintLayout
test_create_legend_item_links_map_and_enables_map_filtering
— (Docstring fehlt)grün
TestPrintLayout
test_create_legend_item_does_not_copy_project_layers_into_legend_model
— (Docstring fehlt)grün
TestPrintLayout
test_configure_legend_size_uses_content_adaptive_size
— (Docstring fehlt)grün
TestPrintLayout
test_configure_hauptkarte_grids_uses_wrapper_constants
— (Docstring fehlt)grün
TestPrintLayout
test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme
— (Docstring fehlt)grün

— (Docstring fehlt)

TestPrintLogic 17
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestPrintLayout
test_create_legend_item_links_map_and_enables_map_filtering
— (Docstring fehlt)grünnie geprüft
TestPrintLayout
test_create_legend_item_does_not_copy_project_layers_into_legend_model
— (Docstring fehlt)grünnie geprüft
TestPrintLayout
test_configure_legend_size_uses_content_adaptive_size
— (Docstring fehlt)grünnie geprüft
TestPrintLayout
test_configure_hauptkarte_grids_uses_wrapper_constants
— (Docstring fehlt)grünnie geprüft
TestPrintLayout
test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestPrintLogic 17
flowchart TD
   root(["test_print_logic.py"])
   class root rootnode
   root --> g1["TestPrintLogic (17)"]
@@ -324,7 +329,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestPrintLogic
test_get_baufreigabe_page_dimensions_prefers_a4_for_small_extent
— (Docstring fehlt)grün
TestPrintLogic
test_get_baufreigabe_page_dimensions_escalates_to_a3
— (Docstring fehlt)grün
TestPrintLogic
test_get_baufreigabe_page_dimensions_respects_a4_as_maximum_with_fallback
— (Docstring fehlt)grün
TestPrintLogic
test_get_baufreigabe_page_dimensions_falls_back_to_a3_for_oversize_extent
— (Docstring fehlt)grün
TestPrintLogic
test_select_standard_page_layout_uses_a4_as_minimum_sheet
— (Docstring fehlt)grün
TestPrintLogic
test_select_standard_page_layout_limits_hauptkarte_to_a3
— (Docstring fehlt)grün
TestPrintLogic
test_select_standard_page_layout_returns_none_if_a3_is_too_small
— (Docstring fehlt)grün
TestPrintLogic
test_get_standard_layout_dimensions_uses_a4_and_forces_fit_for_small_extent
— (Docstring fehlt)grün
TestPrintLogic
test_get_standard_layout_dimensions_caps_endlosrolle_width_at_2000_mm
— (Docstring fehlt)grün
TestPrintLogic
test_apply_standard_minimum_a4_fallback_for_small_page
— (Docstring fehlt)grün
TestPrintLogic
test_apply_standard_minimum_a4_fallback_keeps_large_page
— (Docstring fehlt)grün
TestPrintLogic
test_does_plot_fit_page_true_for_standard_a4
— (Docstring fehlt)grün
TestPrintLogic
test_does_plot_fit_page_false_if_objects_exceed_page
— (Docstring fehlt)grün
TestPrintLogic
test_set_druckbereich_accepts_wie_kartenfenster
— (Docstring fehlt)grün
TestPrintLogic
test_get_canvas_extent_returns_valid_extent
— (Docstring fehlt)grün
TestPrintLogic
test_resolve_extent_uses_canvas_extent_without_buffer
— (Docstring fehlt)grün
TestPrintLogic
test_resolve_extent_uses_rectangle_extent_without_buffer
— (Docstring fehlt)grün

— (Docstring fehlt)

TestPruefmanager 14
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestPrintLogic
test_get_baufreigabe_page_dimensions_prefers_a4_for_small_extent
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_baufreigabe_page_dimensions_escalates_to_a3
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_baufreigabe_page_dimensions_respects_a4_as_maximum_with_fallback
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_baufreigabe_page_dimensions_falls_back_to_a3_for_oversize_extent
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_select_standard_page_layout_uses_a4_as_minimum_sheet
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_select_standard_page_layout_limits_hauptkarte_to_a3
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_select_standard_page_layout_returns_none_if_a3_is_too_small
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_standard_layout_dimensions_uses_a4_and_forces_fit_for_small_extent
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_standard_layout_dimensions_caps_endlosrolle_width_at_2000_mm
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_apply_standard_minimum_a4_fallback_for_small_page
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_apply_standard_minimum_a4_fallback_keeps_large_page
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_does_plot_fit_page_true_for_standard_a4
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_does_plot_fit_page_false_if_objects_exceed_page
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_set_druckbereich_accepts_wie_kartenfenster
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_get_canvas_extent_returns_valid_extent
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_resolve_extent_uses_canvas_extent_without_buffer
— (Docstring fehlt)grünnie geprüft
TestPrintLogic
test_resolve_extent_uses_rectangle_extent_without_buffer
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestPruefmanager 14
flowchart TD
   root(["test_pruefmanager.py"])
   class root rootnode
   root --> g1["TestPruefmanager (14)"]
@@ -361,7 +366,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestPruefmanager
test_ok
— (Docstring fehlt)grün
TestPruefmanager
test_leereingabe_erlaubt_ja
— (Docstring fehlt)grün
TestPruefmanager
test_leereingabe_erlaubt_nein
— (Docstring fehlt)grün
TestPruefmanager
test_standarddatei_vorschlagen_ja
— (Docstring fehlt)grün
TestPruefmanager
test_standarddatei_vorschlagen_nein
— (Docstring fehlt)grün
TestPruefmanager
test_temporaer_erlaubt_ja
— (Docstring fehlt)grün
TestPruefmanager
test_temporaer_erlaubt_nein
— (Docstring fehlt)grün
TestPruefmanager
test_layer_unsichtbar_ja
— (Docstring fehlt)grün
TestPruefmanager
test_layer_unsichtbar_nein
— (Docstring fehlt)grün
TestPruefmanager
test_unbekannte_aktion
— (Docstring fehlt)grün
TestPruefmanager
test_datei_existiert_overwrite
— (Docstring fehlt)grün
TestPruefmanager
test_datei_existiert_append
— (Docstring fehlt)grün
TestPruefmanager
test_datei_existiert_cancel
— (Docstring fehlt)grün
TestPruefmanager
test_datei_existiert_in_non_qgis_mode_returns_input
— (Docstring fehlt)grün

— (Docstring fehlt)

TestSettingsLogic 4
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestPruefmanager
test_ok
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_leereingabe_erlaubt_ja
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_leereingabe_erlaubt_nein
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_standarddatei_vorschlagen_ja
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_standarddatei_vorschlagen_nein
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_temporaer_erlaubt_ja
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_temporaer_erlaubt_nein
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_layer_unsichtbar_ja
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_layer_unsichtbar_nein
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_unbekannte_aktion
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_datei_existiert_overwrite
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_datei_existiert_append
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_datei_existiert_cancel
— (Docstring fehlt)grünnie geprüft
TestPruefmanager
test_datei_existiert_in_non_qgis_mode_returns_input
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestSettingsLogic 4
flowchart TD
   root(["test_settings_logic.py"])
   class root rootnode
   root --> g1["TestSettingsLogic (4)"]
@@ -378,7 +383,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestSettingsLogic
test_load
— (Docstring fehlt)grün
TestSettingsLogic
test_save
— (Docstring fehlt)grün
TestSettingsLogic
test_load_handles_partial_values_with_empty_fallback
— (Docstring fehlt)grün
TestSettingsLogic
test_save_empty_string_value_is_persisted
— (Docstring fehlt)grün

— (Docstring fehlt)

TestStilpruefer 4
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestSettingsLogic
test_load
— (Docstring fehlt)grünnie geprüft
TestSettingsLogic
test_save
— (Docstring fehlt)grünnie geprüft
TestSettingsLogic
test_load_handles_partial_values_with_empty_fallback
— (Docstring fehlt)grünnie geprüft
TestSettingsLogic
test_save_empty_string_value_is_persisted
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestStilpruefer 4
flowchart TD
   root(["test_stilpruefer.py"])
   class root rootnode
   root --> g1["TestStilpruefer (4)"]
@@ -395,7 +400,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestStilpruefer
test_keine_datei_angegeben
— (Docstring fehlt)grün
TestStilpruefer
test_datei_existiert_mit_qml
— (Docstring fehlt)grün
TestStilpruefer
test_datei_existiert_falsche_endung
— (Docstring fehlt)grün
TestStilpruefer
test_datei_existiert_nicht
— (Docstring fehlt)grün

Unit-Tests für `sn_basis.functions.text_wrapper`.

TestSanitizeBezeichner 7
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestStilpruefer
test_keine_datei_angegeben
— (Docstring fehlt)grünnie geprüft
TestStilpruefer
test_datei_existiert_mit_qml
— (Docstring fehlt)grünnie geprüft
TestStilpruefer
test_datei_existiert_falsche_endung
— (Docstring fehlt)grünnie geprüft
TestStilpruefer
test_datei_existiert_nicht
— (Docstring fehlt)grünnie geprüft

Unit-Tests für `sn_basis.functions.text_wrapper`.

TestSanitizeBezeichner 7
flowchart TD
   root(["test_text_wrapper.py"])
   class root rootnode
   root --> g1["TestSanitizeBezeichner (7)"]
@@ -418,7 +423,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestSanitizeBezeichner
test_umlaute_bleiben_erhalten
Prüft, dass Umlaute und ß nicht durch den Ersatz entfernt werden.grün
TestSanitizeBezeichner
test_bindestrich_bleibt_erhalten
Prüft, dass ein Bindestrich im Bezeichner erhalten bleibt (Issue #42).grün
TestSanitizeBezeichner
test_unterstrich_bleibt_erhalten
Prüft, dass ein Unterstrich im Bezeichner erhalten bleibt.grün
TestSanitizeBezeichner
test_leerzeichen_wird_durch_ersatz_zusammengefasst
Prüft, dass Leerzeichen (kein zulässiges Zeichen) zu einem Ersatzzeichen werden.grün
TestSanitizeBezeichner
test_fuehrender_und_folgender_ersatz_wird_entfernt
Prüft, dass ein Ersatzzeichen am Anfang oder Ende des Ergebnisses entfernt wird.grün
TestSanitizeBezeichner
test_eigenes_ersatzzeichen_wird_verwendet
Prüft, dass ein abweichendes Ersatzzeichen anstelle von Unterstrich genutzt wird.grün
TestSanitizeBezeichner
test_nur_unzulaessige_zeichen_ergibt_leeren_string
Prüft, dass ein Bezeichner ganz aus unzulässigen Zeichen zu einem leeren String wird.grün

— (Docstring fehlt)

TestVariableWrapper 6
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestSanitizeBezeichner
test_umlaute_bleiben_erhalten
Prüft, dass Umlaute und ß nicht durch den Ersatz entfernt werden.grünnie geprüft
TestSanitizeBezeichner
test_bindestrich_bleibt_erhalten
Prüft, dass ein Bindestrich im Bezeichner erhalten bleibt (Issue #42).grünnie geprüft
TestSanitizeBezeichner
test_unterstrich_bleibt_erhalten
Prüft, dass ein Unterstrich im Bezeichner erhalten bleibt.grünnie geprüft
TestSanitizeBezeichner
test_leerzeichen_wird_durch_ersatz_zusammengefasst
Prüft, dass Leerzeichen (kein zulässiges Zeichen) zu einem Ersatzzeichen werden.grünnie geprüft
TestSanitizeBezeichner
test_fuehrender_und_folgender_ersatz_wird_entfernt
Prüft, dass ein Ersatzzeichen am Anfang oder Ende des Ergebnisses entfernt wird.grünnie geprüft
TestSanitizeBezeichner
test_eigenes_ersatzzeichen_wird_verwendet
Prüft, dass ein abweichendes Ersatzzeichen anstelle von Unterstrich genutzt wird.grünnie geprüft
TestSanitizeBezeichner
test_nur_unzulaessige_zeichen_ergibt_leeren_string
Prüft, dass ein Bezeichner ganz aus unzulässigen Zeichen zu einem leeren String wird.grünnie geprüft

— (Docstring fehlt)

TestVariableWrapper 6
flowchart TD
   root(["test_variable_wrapper.py"])
   class root rootnode
   root --> g1["TestVariableWrapper (6)"]
@@ -439,7 +444,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestVariableWrapper
test_set_variable_project_noop_write_is_skipped
— (Docstring fehlt)grün
TestVariableWrapper
test_set_variable_project_changed_value_is_written
— (Docstring fehlt)grün
TestVariableWrapper
test_set_variable_global_writes_prefixed_name
— (Docstring fehlt)grün
TestVariableWrapper
test_get_variable_global_returns_empty_string_fallback
— (Docstring fehlt)grün
TestVariableWrapper
test_get_variable_invalid_scope_raises
— (Docstring fehlt)grün
TestVariableWrapper
test_set_variable_invalid_scope_raises
— (Docstring fehlt)grün

— (Docstring fehlt)

TestVerfahrensgebietManager 5
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestVariableWrapper
test_set_variable_project_noop_write_is_skipped
— (Docstring fehlt)grünnie geprüft
TestVariableWrapper
test_set_variable_project_changed_value_is_written
— (Docstring fehlt)grünnie geprüft
TestVariableWrapper
test_set_variable_global_writes_prefixed_name
— (Docstring fehlt)grünnie geprüft
TestVariableWrapper
test_get_variable_global_returns_empty_string_fallback
— (Docstring fehlt)grünnie geprüft
TestVariableWrapper
test_get_variable_invalid_scope_raises
— (Docstring fehlt)grünnie geprüft
TestVariableWrapper
test_set_variable_invalid_scope_raises
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestVerfahrensgebietManager 5
flowchart TD
   root(["test_verfahrensgebiet_manager.py"])
   class root rootnode
   root --> g1["TestVerfahrensgebietManager (5)"]
@@ -458,7 +463,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestVerfahrensgebietManager
test_get_verfahrensgebiet_layer_id_returns_value
— (Docstring fehlt)grün
TestVerfahrensgebietManager
test_get_verfahrensgebiet_layer_id_returns_none_for_empty_value
— (Docstring fehlt)grün
TestVerfahrensgebietManager
test_set_verfahrensgebiet_layer_id_writes_project_variable
— (Docstring fehlt)grün
TestVerfahrensgebietManager
test_update_without_layer_does_not_write_when_already_empty
— (Docstring fehlt)grün
TestVerfahrensgebietManager
test_update_with_layer_writes_variable
— (Docstring fehlt)grün
+ classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestVerfahrensgebietManager
test_get_verfahrensgebiet_layer_id_returns_value
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietManager
test_get_verfahrensgebiet_layer_id_returns_none_for_empty_value
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietManager
test_set_verfahrensgebiet_layer_id_writes_project_variable
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietManager
test_update_without_layer_does_not_write_when_already_empty
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietManager
test_update_with_layer_writes_variable
— (Docstring fehlt)grünnie geprüft
@@ -472,7 +477,7 @@ -

Unit-Tests für `sn_verfahrensgebiet.functions.beteiligung_pruefung`.

TestBaueFlurstueckCsv 12TestBaueFlurstueckCsvListe 1TestHoleVerfahrensgebietLayer 3TestFordereManuellesLadenAn 2TestTry3Bootstrap 1TestBeteiligungPruefenDispatch 2TestLadeBeteiligungCsv 4
flowchart TD
+  

Unit-Tests für `sn_verfahrensgebiet.functions.beteiligung_pruefung`.

TestBaueFlurstueckCsv 12TestBaueFlurstueckCsvListe 1TestHoleVerfahrensgebietLayer 3TestFordereManuellesLadenAn 2TestTry3Bootstrap 1TestBeteiligungPruefenDispatch 2TestLadeBeteiligungCsv 4
flowchart TD
   root(["test_beteiligung_pruefung.py"])
   class root rootnode
   root --> g1["TestBaueFlurstueckCsv (12)"]
@@ -543,7 +548,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestBaueFlurstueckCsv
test_normalfall_mit_fuehrenden_nullen
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_null_wird_zu_unterstrichen
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_leer_wird_zu_unterstrichen
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_gemarkung_ohne_fuehrende_nullen_wird_aufgefuellt
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_ungueltiges_format_gibt_none
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_leerer_wert_gibt_none
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_9001_wird_zu_buchstabe_a
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_9002_wird_zu_buchstabe_b
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_9026_wird_zu_buchstabe_z
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_ausserhalb_buchstaben_bereich_bleibt_numerisch
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_nenner_9001_mit_fuehrenden_nullen_wird_erkannt
— (Docstring fehlt)grün
TestBaueFlurstueckCsv
test_einstellige_folge_wird_auf_2_stellen_aufgefuellt
— (Docstring fehlt)grün
TestBaueFlurstueckCsvListe
test_nur_gueltige_zeilen_in_liste
— (Docstring fehlt)grün
TestHoleVerfahrensgebietLayer
test_layer_per_name_hat_vorrang_vor_combo_auswahl
— (Docstring fehlt)grün
TestHoleVerfahrensgebietLayer
test_combo_auswahl_als_fallback_ohne_namens_layer
— (Docstring fehlt)grün
TestHoleVerfahrensgebietLayer
test_kein_layer_gibt_none
— (Docstring fehlt)grün
TestFordereManuellesLadenAn
test_ohne_vef_vkzf_nennt_fehlende_kennzeichen
— (Docstring fehlt)grün
TestFordereManuellesLadenAn
test_mit_vef_vkzf_nennt_verfahrensnummer
— (Docstring fehlt)grün
TestTry3Bootstrap
test_setzt_verfahrensnummer_und_fordert_manuelles_laden_an
— (Docstring fehlt)grün
TestBeteiligungPruefenDispatch
test_layer_ohne_kennzeichen_fordert_manuelles_laden_an
— (Docstring fehlt)grün
TestBeteiligungPruefenDispatch
test_kein_layer_setzt_verfahrensnummer_und_fordert_laden_an
— (Docstring fehlt)grün
TestLadeBeteiligungCsv
test_dialog_abgebrochen_gibt_none
— (Docstring fehlt)grün
TestLadeBeteiligungCsv
test_fehlende_flurstueck_spalte_wirft_fehler
— (Docstring fehlt)grün
TestLadeBeteiligungCsv
test_leere_datei_wirft_fehler
— (Docstring fehlt)grün
TestLadeBeteiligungCsv
test_erfolgsfall_gibt_zeilen_und_spalten_zurueck
— (Docstring fehlt)grün

— (Docstring fehlt)

TestDockWidget 2
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestBaueFlurstueckCsv
test_normalfall_mit_fuehrenden_nullen
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_null_wird_zu_unterstrichen
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_leer_wird_zu_unterstrichen
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_gemarkung_ohne_fuehrende_nullen_wird_aufgefuellt
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_ungueltiges_format_gibt_none
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_leerer_wert_gibt_none
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_9001_wird_zu_buchstabe_a
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_9002_wird_zu_buchstabe_b
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_9026_wird_zu_buchstabe_z
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_ausserhalb_buchstaben_bereich_bleibt_numerisch
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_nenner_9001_mit_fuehrenden_nullen_wird_erkannt
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsv
test_einstellige_folge_wird_auf_2_stellen_aufgefuellt
— (Docstring fehlt)grünnie geprüft
TestBaueFlurstueckCsvListe
test_nur_gueltige_zeilen_in_liste
— (Docstring fehlt)grünnie geprüft
TestHoleVerfahrensgebietLayer
test_layer_per_name_hat_vorrang_vor_combo_auswahl
— (Docstring fehlt)grünnie geprüft
TestHoleVerfahrensgebietLayer
test_combo_auswahl_als_fallback_ohne_namens_layer
— (Docstring fehlt)grünnie geprüft
TestHoleVerfahrensgebietLayer
test_kein_layer_gibt_none
— (Docstring fehlt)grünnie geprüft
TestFordereManuellesLadenAn
test_ohne_vef_vkzf_nennt_fehlende_kennzeichen
— (Docstring fehlt)grünnie geprüft
TestFordereManuellesLadenAn
test_mit_vef_vkzf_nennt_verfahrensnummer
— (Docstring fehlt)grünnie geprüft
TestTry3Bootstrap
test_setzt_verfahrensnummer_und_fordert_manuelles_laden_an
— (Docstring fehlt)grünnie geprüft
TestBeteiligungPruefenDispatch
test_layer_ohne_kennzeichen_fordert_manuelles_laden_an
— (Docstring fehlt)grünnie geprüft
TestBeteiligungPruefenDispatch
test_kein_layer_setzt_verfahrensnummer_und_fordert_laden_an
— (Docstring fehlt)grünnie geprüft
TestLadeBeteiligungCsv
test_dialog_abgebrochen_gibt_none
— (Docstring fehlt)grünnie geprüft
TestLadeBeteiligungCsv
test_fehlende_flurstueck_spalte_wirft_fehler
— (Docstring fehlt)grünnie geprüft
TestLadeBeteiligungCsv
test_leere_datei_wirft_fehler
— (Docstring fehlt)grünnie geprüft
TestLadeBeteiligungCsv
test_erfolgsfall_gibt_zeilen_und_spalten_zurueck
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestDockWidget 2
flowchart TD
   root(["test_dockwidget.py"])
   class root rootnode
   root --> g1["TestDockWidget (2)"]
@@ -556,7 +561,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestDockWidget
test_init_tabs_with_services_injects_available_services
— (Docstring fehlt)grün
TestDockWidget
test_init_tabs_with_services_reports_errors
— (Docstring fehlt)grün

Unit-Tests für das flurstueck_alkis-Modul.

TestFlurstueckAlkis 12TestFlurstueckAlkisAnhaengenDedup 3
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestDockWidget
test_init_tabs_with_services_injects_available_services
— (Docstring fehlt)grünnie geprüft
TestDockWidget
test_init_tabs_with_services_reports_errors
— (Docstring fehlt)grünnie geprüft

Unit-Tests für das flurstueck_alkis-Modul.

TestFlurstueckAlkis 12TestFlurstueckAlkisAnhaengenDedup 3
flowchart TD
   root(["test_flurstueck_alkis.py"])
   class root rootnode
   root --> g1["TestFlurstueckAlkis (12)"]
@@ -597,7 +602,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestFlurstueckAlkis
test_user_cancel_returns_none
ask_text → ok=False, text="" → (None, NONE).grün
TestFlurstueckAlkis
test_empty_text_after_confirmation_returns_none
ask_text → ok=True, aber Text leer → (None, NONE).grün
TestFlurstueckAlkis
test_invalid_wfs_layer_returns_none
WFS-Layer nicht valide → (None, NONE).grün
TestFlurstueckAlkis
test_success_returns_layer_and_first_status
Kein bestehender Layer, WFS valide → (layer, FIRST).rot
TestFlurstueckAlkis
test_sql_filter_contains_all_schluessel
Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel.rot
TestFlurstueckAlkis
test_existing_layer_reload_yes
Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD.rot
TestFlurstueckAlkis
test_existing_layer_keep_no
Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP.rot
TestFlurstueckAlkis
test_vorgabe_schluessel_prefills_default_text
vorgabe_schluessel=['1234','5678'] → ask_text erhält '1234, 5678' als default_text.rot
TestFlurstueckAlkis
test_vorgabe_namen_appears_in_label
vorgabe_namen=['Musterstadt'] → ask_text-label enthält den Namen.rot
TestFlurstueckAlkis
test_bbox_embedded_in_wfs_uri
bbox-Parameter → WFS-URI enthält 'bbox=' Substring.rot
TestFlurstueckAlkis
test_backwards_compatible_no_new_params
flurstueck_alkis(tab) ohne neue Parameter → kein Fehler.rot
TestFlurstueckAlkis
test_ohne_schluessel_abfrage_ueberspringt_ask_text
ohne_schluessel_abfrage=True verwendet vorgabe_schluessel direkt, ohne ask_text aufzurufen.grün
TestFlurstueckAlkisAnhaengenDedup
test_append_ueberspringt_bereits_vorhandene_flurstuecke
Prüft, dass beim Anhängen bereits vorhandene flurstueckskennzeichen nicht erneut hinzugefügt werden.grün
TestFlurstueckAlkisAnhaengenDedup
test_append_ohne_kennzeichen_feld_haengt_alles_an
Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten).grün
TestFlurstueckAlkisAnhaengenDedup
test_ohne_schluessel_abfrage_append_dedup
ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47).grün

Unit-Tests für `sn_verfahrensgebiet.functions.gemarkung_alkis`.

TestExtractSchluesselUndName 4TestGemarkungSchluesselbbox 6TestGemarkungSchluesselnurNummern 2TestLadeGemarkungenlayer 2
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestFlurstueckAlkis
test_user_cancel_returns_none
ask_text → ok=False, text="" → (None, NONE).grünnie geprüft
TestFlurstueckAlkis
test_empty_text_after_confirmation_returns_none
ask_text → ok=True, aber Text leer → (None, NONE).grünnie geprüft
TestFlurstueckAlkis
test_invalid_wfs_layer_returns_none
WFS-Layer nicht valide → (None, NONE).grünnie geprüft
TestFlurstueckAlkis
test_success_returns_layer_and_first_status
Kein bestehender Layer, WFS valide → (layer, FIRST).rotnie geprüft
TestFlurstueckAlkis
test_sql_filter_contains_all_schluessel
Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel.rotnie geprüft
TestFlurstueckAlkis
test_existing_layer_reload_yes
Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD.rotnie geprüft
TestFlurstueckAlkis
test_existing_layer_keep_no
Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP.rotnie geprüft
TestFlurstueckAlkis
test_vorgabe_schluessel_prefills_default_text
vorgabe_schluessel=['1234','5678'] → ask_text erhält '1234, 5678' als default_text.rotnie geprüft
TestFlurstueckAlkis
test_vorgabe_namen_appears_in_label
vorgabe_namen=['Musterstadt'] → ask_text-label enthält den Namen.rotnie geprüft
TestFlurstueckAlkis
test_bbox_embedded_in_wfs_uri
bbox-Parameter → WFS-URI enthält 'bbox=' Substring.rotnie geprüft
TestFlurstueckAlkis
test_backwards_compatible_no_new_params
flurstueck_alkis(tab) ohne neue Parameter → kein Fehler.rotnie geprüft
TestFlurstueckAlkis
test_ohne_schluessel_abfrage_ueberspringt_ask_text
ohne_schluessel_abfrage=True verwendet vorgabe_schluessel direkt, ohne ask_text aufzurufen.grünnie geprüft
TestFlurstueckAlkisAnhaengenDedup
test_append_ueberspringt_bereits_vorhandene_flurstuecke
Prüft, dass beim Anhängen bereits vorhandene flurstueckskennzeichen nicht erneut hinzugefügt werden.grünnie geprüft
TestFlurstueckAlkisAnhaengenDedup
test_append_ohne_kennzeichen_feld_haengt_alles_an
Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten).grünnie geprüft
TestFlurstueckAlkisAnhaengenDedup
test_ohne_schluessel_abfrage_append_dedup
ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47).grünnie geprüft

Unit-Tests für `sn_verfahrensgebiet.functions.gemarkung_alkis`.

TestExtractSchluesselUndName 4TestGemarkungSchluesselbbox 6TestGemarkungSchluesselnurNummern 2TestLadeGemarkungenlayer 2
flowchart TD
   root(["test_gemarkung_alkis.py"])
   class root rootnode
   root --> g1["TestExtractSchluesselUndName (4)"]
@@ -640,7 +645,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestExtractSchluesselUndName
test_standard_attribute
— (Docstring fehlt)rot
TestExtractSchluesselUndName
test_fallback_attribute
— (Docstring fehlt)rot
TestExtractSchluesselUndName
test_missing_attribute_returns_empty
— (Docstring fehlt)grün
TestExtractSchluesselUndName
test_none_value_returns_empty
— (Docstring fehlt)grün
TestGemarkungSchluesselbbox
test_success_bbox_filter
WFS-BBox-Filter liefert Features → korrekte Tupel-Liste.übersp.
TestGemarkungSchluesselbbox
test_fallback_when_bbox_fails
BBox-Filter schlägt fehl → Fallback auf Volllade + client-seitige Filterung.übersp.
TestGemarkungSchluesselbbox
test_both_layers_fail_returns_empty
Beide Lade-Strategien scheitern → leere Liste.übersp.
TestGemarkungSchluesselbbox
test_deduplication_and_sorting
Doppelte Schlüssel werden dedupliziert, Ergebnis ist sortiert.übersp.
TestGemarkungSchluesselbbox
test_feature_without_schluessel_skipped
Feature ohne Schlüssel-Attribut wird übersprungen.übersp.
TestGemarkungSchluesselbbox
test_exception_returns_empty
Exception im Ladevorgang → leere Liste (kein Crash).übersp.
TestGemarkungSchluesselnurNummern
test_returns_only_nummern
— (Docstring fehlt)übersp.
TestGemarkungSchluesselnurNummern
test_empty_input_returns_empty
— (Docstring fehlt)übersp.
TestLadeGemarkungenlayer
test_returns_layer_when_service_reachable
Dienst erreichbar (isValid=True) → Layer-Objekt zurückgegeben.grün
TestLadeGemarkungenlayer
test_returns_none_when_service_unreachable
Dienst nicht erreichbar (isValid=False) → None zurückgegeben.grün

Unit-Tests für `sn_verfahrensgebiet.functions.grenzpunkt_alkis`.

TestExtrahiereGmlIds 5TestGrenzpunktAlkis 7
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestExtractSchluesselUndName
test_standard_attribute
— (Docstring fehlt)rotnie geprüft
TestExtractSchluesselUndName
test_fallback_attribute
— (Docstring fehlt)rotnie geprüft
TestExtractSchluesselUndName
test_missing_attribute_returns_empty
— (Docstring fehlt)grünnie geprüft
TestExtractSchluesselUndName
test_none_value_returns_empty
— (Docstring fehlt)grünnie geprüft
TestGemarkungSchluesselbbox
test_success_bbox_filter
WFS-BBox-Filter liefert Features → korrekte Tupel-Liste.übersp.nie geprüft
TestGemarkungSchluesselbbox
test_fallback_when_bbox_fails
BBox-Filter schlägt fehl → Fallback auf Volllade + client-seitige Filterung.übersp.nie geprüft
TestGemarkungSchluesselbbox
test_both_layers_fail_returns_empty
Beide Lade-Strategien scheitern → leere Liste.übersp.nie geprüft
TestGemarkungSchluesselbbox
test_deduplication_and_sorting
Doppelte Schlüssel werden dedupliziert, Ergebnis ist sortiert.übersp.nie geprüft
TestGemarkungSchluesselbbox
test_feature_without_schluessel_skipped
Feature ohne Schlüssel-Attribut wird übersprungen.übersp.nie geprüft
TestGemarkungSchluesselbbox
test_exception_returns_empty
Exception im Ladevorgang → leere Liste (kein Crash).übersp.nie geprüft
TestGemarkungSchluesselnurNummern
test_returns_only_nummern
— (Docstring fehlt)übersp.nie geprüft
TestGemarkungSchluesselnurNummern
test_empty_input_returns_empty
— (Docstring fehlt)übersp.nie geprüft
TestLadeGemarkungenlayer
test_returns_layer_when_service_reachable
Dienst erreichbar (isValid=True) → Layer-Objekt zurückgegeben.grünnie geprüft
TestLadeGemarkungenlayer
test_returns_none_when_service_unreachable
Dienst nicht erreichbar (isValid=False) → None zurückgegeben.grünnie geprüft

Unit-Tests für `sn_verfahrensgebiet.functions.grenzpunkt_alkis`.

TestExtrahiereGmlIds 5TestGrenzpunktAlkis 7
flowchart TD
   root(["test_grenzpunkt_alkis.py"])
   class root rootnode
   root --> g1["TestExtrahiereGmlIds (5)"]
@@ -675,7 +680,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestExtrahiereGmlIds
test_xlink_href_format
URN-Format 'urn:adv:oid:DEABC123' → nur 'DEABC123' extrahiert.grün
TestExtrahiereGmlIds
test_plain_gml_id
Plain-GML-ID ohne Doppelpunkt → direkt übernommen.grün
TestExtrahiereGmlIds
test_empty_value_skipped
Leerer gehoertZu-Wert wird übersprungen.grün
TestExtrahiereGmlIds
test_deduplication
Doppelte Referenzen werden dedupliziert.grün
TestExtrahiereGmlIds
test_sorted_output
Rückgabe ist aufsteigend sortiert.grün
TestGrenzpunktAlkis
test_no_vg_layer_returns_none
— (Docstring fehlt)grün
TestGrenzpunktAlkis
test_invalid_punktort_layer
— (Docstring fehlt)grün
TestGrenzpunktAlkis
test_empty_punktort_layer
— (Docstring fehlt)grün
TestGrenzpunktAlkis
test_no_gml_ids_returns_pta_only
— (Docstring fehlt)rot
TestGrenzpunktAlkis
test_grenzpunkt_batch_empty
— (Docstring fehlt)rot
TestGrenzpunktAlkis
test_success_returns_both_layers
— (Docstring fehlt)rot
TestGrenzpunktAlkis
test_extent_derived_from_vg_layer
Wenn kein extent übergeben → Extent aus VG-Layer holen.rot

Unit-Tests für `sn_verfahrensgebiet.functions.knickpunkt_pruefung`.

TestExtrahiereKnickpunkte 4TestKnickpunktPruefungInputvalidierung 3TestKnickpunktPruefungKlassifizierung 2TestFehlendKnickpunkteViaVerbindungslinien 4
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestExtrahiereGmlIds
test_xlink_href_format
URN-Format 'urn:adv:oid:DEABC123' → nur 'DEABC123' extrahiert.grünnie geprüft
TestExtrahiereGmlIds
test_plain_gml_id
Plain-GML-ID ohne Doppelpunkt → direkt übernommen.grünnie geprüft
TestExtrahiereGmlIds
test_empty_value_skipped
Leerer gehoertZu-Wert wird übersprungen.grünnie geprüft
TestExtrahiereGmlIds
test_deduplication
Doppelte Referenzen werden dedupliziert.grünnie geprüft
TestExtrahiereGmlIds
test_sorted_output
Rückgabe ist aufsteigend sortiert.grünnie geprüft
TestGrenzpunktAlkis
test_no_vg_layer_returns_none
— (Docstring fehlt)grünnie geprüft
TestGrenzpunktAlkis
test_invalid_punktort_layer
— (Docstring fehlt)grünnie geprüft
TestGrenzpunktAlkis
test_empty_punktort_layer
— (Docstring fehlt)grünnie geprüft
TestGrenzpunktAlkis
test_no_gml_ids_returns_pta_only
— (Docstring fehlt)rotnie geprüft
TestGrenzpunktAlkis
test_grenzpunkt_batch_empty
— (Docstring fehlt)rotnie geprüft
TestGrenzpunktAlkis
test_success_returns_both_layers
— (Docstring fehlt)rotnie geprüft
TestGrenzpunktAlkis
test_extent_derived_from_vg_layer
Wenn kein extent übergeben → Extent aus VG-Layer holen.rotnie geprüft

Unit-Tests für `sn_verfahrensgebiet.functions.knickpunkt_pruefung`.

TestExtrahiereKnickpunkte 4TestKnickpunktPruefungInputvalidierung 3TestKnickpunktPruefungKlassifizierung 2TestFehlendKnickpunkteViaVerbindungslinien 4
flowchart TD
   root(["test_knickpunkt_pruefung.py"])
   class root rootnode
   root --> g1["TestExtrahiereKnickpunkte (4)"]
@@ -716,7 +721,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestExtrahiereKnickpunkte
test_leerer_layer_gibt_leere_liste
— (Docstring fehlt)grün
TestExtrahiereKnickpunkte
test_keine_gueltige_geometrie_gibt_leere_liste
— (Docstring fehlt)grün
TestExtrahiereKnickpunkte
test_feature_mit_leerer_geometrie_gibt_leere_liste
— (Docstring fehlt)grün
TestExtrahiereKnickpunkte
test_qgis_nicht_verfuegbar_gibt_leere_liste
Wenn qgis.core kein QgsPointXY hat (ImportError in Funktion), leere Liste.grün
TestKnickpunktPruefungInputvalidierung
test_keine_knickpunkte_gibt_none_zurueck
— (Docstring fehlt)grün
TestKnickpunktPruefungInputvalidierung
test_kein_punktort_layer_gibt_none_zurueck
— (Docstring fehlt)grün
TestKnickpunktPruefungInputvalidierung
test_abbruch_via_progress_gibt_none_zurueck
— (Docstring fehlt)grün
TestKnickpunktPruefungKlassifizierung
test_identischer_punkt_wird_gruen_gezaehlt
PunktortTA exakt am Knickpunkt → identisch_count == 1.grün
TestKnickpunktPruefungKlassifizierung
test_kein_pta_an_knickpunkt_wird_rot_gezaehlt
Kein PunktortTA am Knickpunkt → kein_pta_count == 1.grün
TestFehlendKnickpunkteViaVerbindungslinien
test_leere_union_gibt_null_zurueck
bror_union.isEmpty() == True → (0, []).grün
TestFehlendKnickpunkteViaVerbindungslinien
test_weniger_als_zwei_pta_auf_ring_kein_orange
Nur 1 gematchter PunktortTA auf Ring → keine fehlenden Knickpunkte.grün
TestFehlendKnickpunkteViaVerbindungslinien
test_ungematchter_pta_im_puffer_wird_orange
Nicht-gematchter PunktortTA innerhalb 3-cm-Puffer → orange gezählt.grün
TestFehlendKnickpunkteViaVerbindungslinien
test_ungematchter_pta_ausserhalb_puffer_kein_orange
Nicht-gematchter PunktortTA außerhalb Puffer → nicht orange gezählt.grün

— (Docstring fehlt)

TestPluginMain 4
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestExtrahiereKnickpunkte
test_leerer_layer_gibt_leere_liste
— (Docstring fehlt)grünnie geprüft
TestExtrahiereKnickpunkte
test_keine_gueltige_geometrie_gibt_leere_liste
— (Docstring fehlt)grünnie geprüft
TestExtrahiereKnickpunkte
test_feature_mit_leerer_geometrie_gibt_leere_liste
— (Docstring fehlt)grünnie geprüft
TestExtrahiereKnickpunkte
test_qgis_nicht_verfuegbar_gibt_leere_liste
Wenn qgis.core kein QgsPointXY hat (ImportError in Funktion), leere Liste.grünnie geprüft
TestKnickpunktPruefungInputvalidierung
test_keine_knickpunkte_gibt_none_zurueck
— (Docstring fehlt)grünnie geprüft
TestKnickpunktPruefungInputvalidierung
test_kein_punktort_layer_gibt_none_zurueck
— (Docstring fehlt)grünnie geprüft
TestKnickpunktPruefungInputvalidierung
test_abbruch_via_progress_gibt_none_zurueck
— (Docstring fehlt)grünnie geprüft
TestKnickpunktPruefungKlassifizierung
test_identischer_punkt_wird_gruen_gezaehlt
PunktortTA exakt am Knickpunkt → identisch_count == 1.grünnie geprüft
TestKnickpunktPruefungKlassifizierung
test_kein_pta_an_knickpunkt_wird_rot_gezaehlt
Kein PunktortTA am Knickpunkt → kein_pta_count == 1.grünnie geprüft
TestFehlendKnickpunkteViaVerbindungslinien
test_leere_union_gibt_null_zurueck
bror_union.isEmpty() == True → (0, []).grünnie geprüft
TestFehlendKnickpunkteViaVerbindungslinien
test_weniger_als_zwei_pta_auf_ring_kein_orange
Nur 1 gematchter PunktortTA auf Ring → keine fehlenden Knickpunkte.grünnie geprüft
TestFehlendKnickpunkteViaVerbindungslinien
test_ungematchter_pta_im_puffer_wird_orange
Nicht-gematchter PunktortTA innerhalb 3-cm-Puffer → orange gezählt.grünnie geprüft
TestFehlendKnickpunkteViaVerbindungslinien
test_ungematchter_pta_ausserhalb_puffer_kein_orange
Nicht-gematchter PunktortTA außerhalb Puffer → nicht orange gezählt.grünnie geprüft

— (Docstring fehlt)

TestPluginMain 4
flowchart TD
   root(["test_main.py"])
   class root rootnode
   root --> g1["TestPluginMain (4)"]
@@ -733,7 +738,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestPluginMain
test_init_sets_services_and_names
— (Docstring fehlt)grün
TestPluginMain
test_initGui_registers_action_when_basis_ui_exists
— (Docstring fehlt)grün
TestPluginMain
test_run_creates_dock_and_marks_toolbar_active
— (Docstring fehlt)grün
TestPluginMain
test_unload_removes_dock_and_action
— (Docstring fehlt)grün

— (Docstring fehlt)

TestVerfahrensgebietAlkis 8
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestPluginMain
test_init_sets_services_and_names
— (Docstring fehlt)grünnie geprüft
TestPluginMain
test_initGui_registers_action_when_basis_ui_exists
— (Docstring fehlt)grünnie geprüft
TestPluginMain
test_run_creates_dock_and_marks_toolbar_active
— (Docstring fehlt)grünnie geprüft
TestPluginMain
test_unload_removes_dock_and_action
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestVerfahrensgebietAlkis 8
flowchart TD
   root(["test_verfahrensgebiet_alkis.py"])
   class root rootnode
   root --> g1["TestVerfahrensgebietAlkis (8)"]
@@ -758,7 +763,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestVerfahrensgebietAlkis
test_check_existing_layer_first_load
— (Docstring fehlt)grün
TestVerfahrensgebietAlkis
test_check_existing_layer_keep_existing
— (Docstring fehlt)grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing
— (Docstring fehlt)grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_fails_on_invalid_wfs_layer
— (Docstring fehlt)grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_success_single_kombination
Einzelne (adv_name, bezeichnung)-Kombination → kein Dialog, Memory-Layer zurück.grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_dialog_auswahl
Zwei verschiedene Kombinationen → Dialog wird gezeigt, gewählte Features genutzt.grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_dialog_abbruch
Zwei verschiedene Kombinationen → Nutzer bricht Dialog ab → NONE.grün
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_mehrfachauswahl
Zwei verschiedene Kombinationen → beide ausgewählt → beide Feature-Gruppen genutzt.grün

Unit-Tests für `sn_verfahrensgebiet.functions.verfahrensgebiet_alkis_komplett`.

TestSelectByLocation 3TestFuegeVkzFeldHinzu 3TestFlaechenvergleich 8TestVerfahrensgebietAlkisKomplett 16
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestVerfahrensgebietAlkis
test_check_existing_layer_first_load
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkis
test_check_existing_layer_keep_existing
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_fails_on_invalid_wfs_layer
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_success_single_kombination
Einzelne (adv_name, bezeichnung)-Kombination → kein Dialog, Memory-Layer zurück.grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_dialog_auswahl
Zwei verschiedene Kombinationen → Dialog wird gezeigt, gewählte Features genutzt.grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_dialog_abbruch
Zwei verschiedene Kombinationen → Nutzer bricht Dialog ab → NONE.grünnie geprüft
TestVerfahrensgebietAlkis
test_verfahrensgebiet_alkis_multi_kombination_mehrfachauswahl
Zwei verschiedene Kombinationen → beide ausgewählt → beide Feature-Gruppen genutzt.grünnie geprüft

Unit-Tests für `sn_verfahrensgebiet.functions.verfahrensgebiet_alkis_komplett`.

TestSelectByLocation 3TestFuegeVkzFeldHinzu 3TestFlaechenvergleich 8TestVerfahrensgebietAlkisKomplett 16
flowchart TD
   root(["test_verfahrensgebiet_alkis_komplett.py"])
   class root rootnode
   root --> g1["TestSelectByLocation (3)"]
@@ -833,7 +838,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestSelectByLocation
test_processing_not_available_returns_zero
— (Docstring fehlt)grün
TestSelectByLocation
test_processing_success_returns_count
— (Docstring fehlt)grün
TestSelectByLocation
test_processing_exception_returns_zero
— (Docstring fehlt)grün
TestFuegeVkzFeldHinzu
test_empty_vkz_does_nothing
— (Docstring fehlt)grün
TestFuegeVkzFeldHinzu
test_none_vkz_does_nothing
— (Docstring fehlt)grün
TestFuegeVkzFeldHinzu
test_vkz_field_added
— (Docstring fehlt)grün
TestFlaechenvergleich
test_gleiche_flaeche_stimmt_ueberein
— (Docstring fehlt)grün
TestFlaechenvergleich
test_verschiedene_flaeche_stimmt_nicht_ueberein
— (Docstring fehlt)grün
TestFlaechenvergleich
test_differenz_innerhalb_toleranz
— (Docstring fehlt)grün
TestFlaechenvergleich
test_differenz_ausserhalb_toleranz
— (Docstring fehlt)grün
TestFlaechenvergleich
test_flaechen_werte_korrekt
— (Docstring fehlt)grün
TestFlaechenvergleich
test_lese_toleranz_default_ist_null
— (Docstring fehlt)grün
TestFlaechenvergleich
test_lese_toleranz_parst_string
— (Docstring fehlt)grün
TestFlaechenvergleich
test_lese_toleranz_ungueltig_fallback_null
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_vg_alkis_none_aborts
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_flst_none_aborts
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_no_selection_returns_none_enriched
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_invalid_enriched_layer_returns_none
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_progress_cancel_after_step1_returns_none
Abbruch nach Schritt 1 → sofortiger sauberer Rückgabestatus.grün
TestVerfahrensgebietAlkisKomplett
test_success_flaechen_match_zeigt_info
Flächenübereinstimmung → show_info_dialog mit erwartetem Text.grün
TestVerfahrensgebietAlkisKomplett
test_no_vkz_variable_passes_empty_string
— (Docstring fehlt)grün
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_abbrechen_kein_detailcheck
Abweichung + Abbrechen → knickpunkt_pruefung wird NICHT aufgerufen.grün
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_als_vg_laden
Abweichung + Als VG laden → BROR-Layer wird umbenannt und alsgrün
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_detailpruefung_startet_knickpruefung
Abweichung + Detailprüfung → lade_punktort_ta + knickpunkt_pruefunggrün
TestVerfahrensgebietAlkisKomplett
test_bror_layer_bleibt_bei_erfolg_im_projekt
Bei Erfolg darf der BROR-Layer NICHT entfernt werden.grün
TestVerfahrensgebietAlkisKomplett
test_bror_layer_wird_bei_fehler_entfernt
Bei Fehler (flst_alkis NONE) wird der BROR-Layer aus dem Projekt entfernt.grün
TestVerfahrensgebietAlkisKomplett
test_kein_vkz_kein_landkreis_dialog_abgebrochen
Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer bricht dengrün
TestVerfahrensgebietAlkisKomplett
test_kein_vkz_kein_landkreis_dialog_liefert_landkreis
Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer wählt einengrün
TestVerfahrensgebietAlkisKomplett
test_landkreis_modus_wird_bei_fehlender_vkz_verwendet
Keine Verfahrensnummer, aber Landkreis gesetzt → Landkreis-Suchpfadgrün
TestVerfahrensgebietAlkisKomplett
test_landkreis_modus_nur_laden_ueberspringt_dialog2
nur_laden=True → Funktion kehrt sofort zurück, Dialog 2 (Gemarkunggrün

Unit-Tests für das Verfahrensgebiet-Edit-Service-Modul.

TestPruefeFlurstueckLayer 3TestPruefeAuswahl 3TestGetKennzeichenMenge 3TestErstelle 3TestErgaenzeVerfahrensgebiet 3TestEntferneAusVerfahrensgebiet 5TestErsetze 1
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestSelectByLocation
test_processing_not_available_returns_zero
— (Docstring fehlt)grünnie geprüft
TestSelectByLocation
test_processing_success_returns_count
— (Docstring fehlt)grünnie geprüft
TestSelectByLocation
test_processing_exception_returns_zero
— (Docstring fehlt)grünnie geprüft
TestFuegeVkzFeldHinzu
test_empty_vkz_does_nothing
— (Docstring fehlt)grünnie geprüft
TestFuegeVkzFeldHinzu
test_none_vkz_does_nothing
— (Docstring fehlt)grünnie geprüft
TestFuegeVkzFeldHinzu
test_vkz_field_added
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_gleiche_flaeche_stimmt_ueberein
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_verschiedene_flaeche_stimmt_nicht_ueberein
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_differenz_innerhalb_toleranz
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_differenz_ausserhalb_toleranz
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_flaechen_werte_korrekt
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_lese_toleranz_default_ist_null
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_lese_toleranz_parst_string
— (Docstring fehlt)grünnie geprüft
TestFlaechenvergleich
test_lese_toleranz_ungueltig_fallback_null
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_vg_alkis_none_aborts
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_flst_none_aborts
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_no_selection_returns_none_enriched
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_invalid_enriched_layer_returns_none
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_progress_cancel_after_step1_returns_none
Abbruch nach Schritt 1 → sofortiger sauberer Rückgabestatus.grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_success_flaechen_match_zeigt_info
Flächenübereinstimmung → show_info_dialog mit erwartetem Text.grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_no_vkz_variable_passes_empty_string
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_abbrechen_kein_detailcheck
Abweichung + Abbrechen → knickpunkt_pruefung wird NICHT aufgerufen.grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_als_vg_laden
Abweichung + Als VG laden → BROR-Layer wird umbenannt und alsgrünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_flaechen_abweichung_detailpruefung_startet_knickpruefung
Abweichung + Detailprüfung → lade_punktort_ta + knickpunkt_pruefunggrünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_bror_layer_bleibt_bei_erfolg_im_projekt
Bei Erfolg darf der BROR-Layer NICHT entfernt werden.grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_bror_layer_wird_bei_fehler_entfernt
Bei Fehler (flst_alkis NONE) wird der BROR-Layer aus dem Projekt entfernt.grünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_kein_vkz_kein_landkreis_dialog_abgebrochen
Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer bricht dengrünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_kein_vkz_kein_landkreis_dialog_liefert_landkreis
Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer wählt einengrünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_landkreis_modus_wird_bei_fehlender_vkz_verwendet
Keine Verfahrensnummer, aber Landkreis gesetzt → Landkreis-Suchpfadgrünnie geprüft
TestVerfahrensgebietAlkisKomplett
test_landkreis_modus_nur_laden_ueberspringt_dialog2
nur_laden=True → Funktion kehrt sofort zurück, Dialog 2 (Gemarkunggrünnie geprüft

Unit-Tests für das Verfahrensgebiet-Edit-Service-Modul.

TestPruefeFlurstueckLayer 3TestPruefeAuswahl 3TestGetKennzeichenMenge 3TestErstelle 3TestErgaenzeVerfahrensgebiet 3TestEntferneAusVerfahrensgebiet 5TestErsetze 1
flowchart TD
   root(["test_verfahrensgebiet_edit_service.py"])
   class root rootnode
   root --> g1["TestPruefeFlurstueckLayer (3)"]
@@ -896,7 +901,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestPruefeFlurstueckLayer
test_layer_ok_passes
Gültiger Polygon-Vektor-Layer mit Pflichtfeldern → ok=True.grün
TestPruefeFlurstueckLayer
test_layer_missing_field_fails
Layer ohne Pflichtfelder → ok=False, aktion=felder_fehlen.grün
TestPruefeFlurstueckLayer
test_layer_wrong_geometry_fails
Layer mit falschem Geometrietyp → ok=False, aktion=falscher_geotyp.grün
TestPruefeAuswahl
test_no_selection_fails
— (Docstring fehlt)grün
TestPruefeAuswahl
test_with_selection_passes
— (Docstring fehlt)grün
TestPruefeAuswahl
test_selectedFeatureCount_exception_treated_as_zero
— (Docstring fehlt)grün
TestGetKennzeichenMenge
test_returns_set_of_ids
Kommagetrennte Kennzeichen im Single-Feature werden korrekt geparst.grün
TestGetKennzeichenMenge
test_empty_layer_returns_empty_set
— (Docstring fehlt)grün
TestGetKennzeichenMenge
test_single_kennzeichen_without_comma
Einzelnes Kennzeichen ohne Komma wird korrekt erkannt.grün
TestErstelle
test_success_counts
3 gültige Features → erfolgreich=3, fehlgeschlagen=0, 1 Union-Feature im Layer.grün
TestErstelle
test_partial_failure_on_empty_geometry
2 ok + 1 leere Geometrie → erfolgreich=2, fehlgeschlagen=1.grün
TestErstelle
test_all_fail_on_empty_geometries
Alle Features haben leere Geometrie → erfolgreich=0, kein Feature im Layer.grün
TestErgaenzeVerfahrensgebiet
test_adds_only_new_ids
Auswahl enthält 1 neue + 1 bereits vorhandene ID → hinzugefügt=1.grün
TestErgaenzeVerfahrensgebiet
test_skip_empty_geometry_counts_as_failed
Neue ID mit leerer Geometrie → fehlgeschlagen=1, hinzugefügt=0.grün
TestErgaenzeVerfahrensgebiet
test_all_already_present
Alle ausgewählten IDs bereits vorhanden → bereits_vorhanden=n, hinzugefügt=0.grün
TestEntferneAusVerfahrensgebiet
test_removes_present_ids
Auswahl enthält 1 vorhandene ID → entfernt=1, nicht_enthalten=0.grün
TestEntferneAusVerfahrensgebiet
test_counts_ids_not_in_layer
Auswahl enthält ID, die nicht im Verfahrensgebiet ist → nicht_enthalten=1.grün
TestEntferneAusVerfahrensgebiet
test_none_present_in_layer
Auswahl hat IDs, die alle nicht im Layer sind → entfernt=0, nicht_enthalten=n.grün
TestEntferneAusVerfahrensgebiet
test_empty_selection_removes_nothing
Leere Auswahl → nichts entfernt, nichts nicht_enthalten.grün
TestEntferneAusVerfahrensgebiet
test_removes_last_id_deletes_feature
Wird das letzte Kennzeichen entfernt, wird das Feature gelöscht.grün
TestErsetze
test_ersetze_delegates_to_erstelle
ersetze_verfahrensgebiet gibt dasselbe Ergebnis wie erstelle zurück.grün

Unit-Tests für `sn_verfahrensgebiet.functions.verfahrensgebiet_shape_komplett`.

TestFindShp 4TestErstelleMemoryLayerAusShp 3TestLadeVgAusZip 6TestVerfahrensgebietShapeKomplett 18
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestPruefeFlurstueckLayer
test_layer_ok_passes
Gültiger Polygon-Vektor-Layer mit Pflichtfeldern → ok=True.grünnie geprüft
TestPruefeFlurstueckLayer
test_layer_missing_field_fails
Layer ohne Pflichtfelder → ok=False, aktion=felder_fehlen.grünnie geprüft
TestPruefeFlurstueckLayer
test_layer_wrong_geometry_fails
Layer mit falschem Geometrietyp → ok=False, aktion=falscher_geotyp.grünnie geprüft
TestPruefeAuswahl
test_no_selection_fails
— (Docstring fehlt)grünnie geprüft
TestPruefeAuswahl
test_with_selection_passes
— (Docstring fehlt)grünnie geprüft
TestPruefeAuswahl
test_selectedFeatureCount_exception_treated_as_zero
— (Docstring fehlt)grünnie geprüft
TestGetKennzeichenMenge
test_returns_set_of_ids
Kommagetrennte Kennzeichen im Single-Feature werden korrekt geparst.grünnie geprüft
TestGetKennzeichenMenge
test_empty_layer_returns_empty_set
— (Docstring fehlt)grünnie geprüft
TestGetKennzeichenMenge
test_single_kennzeichen_without_comma
Einzelnes Kennzeichen ohne Komma wird korrekt erkannt.grünnie geprüft
TestErstelle
test_success_counts
3 gültige Features → erfolgreich=3, fehlgeschlagen=0, 1 Union-Feature im Layer.grünnie geprüft
TestErstelle
test_partial_failure_on_empty_geometry
2 ok + 1 leere Geometrie → erfolgreich=2, fehlgeschlagen=1.grünnie geprüft
TestErstelle
test_all_fail_on_empty_geometries
Alle Features haben leere Geometrie → erfolgreich=0, kein Feature im Layer.grünnie geprüft
TestErgaenzeVerfahrensgebiet
test_adds_only_new_ids
Auswahl enthält 1 neue + 1 bereits vorhandene ID → hinzugefügt=1.grünnie geprüft
TestErgaenzeVerfahrensgebiet
test_skip_empty_geometry_counts_as_failed
Neue ID mit leerer Geometrie → fehlgeschlagen=1, hinzugefügt=0.grünnie geprüft
TestErgaenzeVerfahrensgebiet
test_all_already_present
Alle ausgewählten IDs bereits vorhanden → bereits_vorhanden=n, hinzugefügt=0.grünnie geprüft
TestEntferneAusVerfahrensgebiet
test_removes_present_ids
Auswahl enthält 1 vorhandene ID → entfernt=1, nicht_enthalten=0.grünnie geprüft
TestEntferneAusVerfahrensgebiet
test_counts_ids_not_in_layer
Auswahl enthält ID, die nicht im Verfahrensgebiet ist → nicht_enthalten=1.grünnie geprüft
TestEntferneAusVerfahrensgebiet
test_none_present_in_layer
Auswahl hat IDs, die alle nicht im Layer sind → entfernt=0, nicht_enthalten=n.grünnie geprüft
TestEntferneAusVerfahrensgebiet
test_empty_selection_removes_nothing
Leere Auswahl → nichts entfernt, nichts nicht_enthalten.grünnie geprüft
TestEntferneAusVerfahrensgebiet
test_removes_last_id_deletes_feature
Wird das letzte Kennzeichen entfernt, wird das Feature gelöscht.grünnie geprüft
TestErsetze
test_ersetze_delegates_to_erstelle
ersetze_verfahrensgebiet gibt dasselbe Ergebnis wie erstelle zurück.grünnie geprüft

Unit-Tests für `sn_verfahrensgebiet.functions.verfahrensgebiet_shape_komplett`.

TestFindShp 4TestErstelleMemoryLayerAusShp 3TestLadeVgAusZip 6TestVerfahrensgebietShapeKomplett 18
flowchart TD
   root(["test_verfahrensgebiet_shape_komplett.py"])
   class root rootnode
   root --> g1["TestFindShp (4)"]
@@ -973,7 +978,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestFindShp
test_findet_shp_in_root
— (Docstring fehlt)grün
TestFindShp
test_findet_shp_in_unterordner
— (Docstring fehlt)grün
TestFindShp
test_kein_shp_gibt_none_zurueck
— (Docstring fehlt)grün
TestFindShp
test_case_insensitive_erkennung
— (Docstring fehlt)grün
TestErstelleMemoryLayerAusShp
test_leere_geometrien_geben_none
— (Docstring fehlt)grün
TestErstelleMemoryLayerAusShp
test_keine_features_gibt_none
— (Docstring fehlt)grün
TestErstelleMemoryLayerAusShp
test_attribute_von_erstem_feature_werden_gesetzt
Attributwerte des ersten Features werden auf das Union-Feature übertragen.grün
TestLadeVgAusZip
test_dialog_abgebrochen_gibt_none_zurueck
— (Docstring fehlt)rot
TestLadeVgAusZip
test_zip_fehler_gibt_none_und_warning
— (Docstring fehlt)rot
TestLadeVgAusZip
test_kein_shp_in_zip_gibt_none_und_warning
— (Docstring fehlt)rot
TestLadeVgAusZip
test_invalider_qgslayer_gibt_none_und_warning
— (Docstring fehlt)rot
TestLadeVgAusZip
test_leere_geometrien_geben_none_und_warning
— (Docstring fehlt)rot
TestLadeVgAusZip
test_erfolg_gibt_memory_layer_zurueck
— (Docstring fehlt)rot
TestVerfahrensgebietShapeKomplett
test_lade_zip_none_aborts
— (Docstring fehlt)grün
TestVerfahrensgebietShapeKomplett
test_shape_vg_sofort_ins_projekt_nach_laden
Shape-VG wird unmittelbar nach dem Laden ins Projekt eingefügt.rot
TestVerfahrensgebietShapeKomplett
test_shape_vg_wird_bei_abbruch_aus_projekt_entfernt
Shape-VG wird bei Fehler/Abbruch aus dem Projekt entfernt.rot
TestVerfahrensgebietShapeKomplett
test_shape_vg_bleibt_im_projekt_bei_erfolg
Bei erfolgreichem Abschluss wird shape_vg NICHT aus dem Projekt entfernt.grün
TestVerfahrensgebietShapeKomplett
test_flst_none_aborts
— (Docstring fehlt)grün
TestVerfahrensgebietShapeKomplett
test_keine_flurstuecke_selektiert_gibt_warning
— (Docstring fehlt)grün
TestVerfahrensgebietShapeKomplett
test_flaechen_uebereinstimmung_gibt_info_und_kein_dialog
— (Docstring fehlt)rot
TestVerfahrensgebietShapeKomplett
test_abweichung_abbrechen_gibt_shape_vg_zurueck
— (Docstring fehlt)rot
TestVerfahrensgebietShapeKomplett
test_abweichung_detailpruefung_ruft_knickpunkt_pruefung_auf
— (Docstring fehlt)rot
TestVerfahrensgebietShapeKomplett
test_punktort_ta_none_gibt_shape_vg_zurueck_und_zeigt_fehler
— (Docstring fehlt)rot
TestVerfahrensgebietShapeKomplett
test_temp_layer_wird_stets_entfernt
— (Docstring fehlt)grün
TestVerfahrensgebietShapeKomplett
test_bror_layer_ist_stets_none
Dritter Rückgabewert ist im Shape-Workflow immer None (kein BROR).grün
TestVerfahrensgebietShapeKomplett
test_bror_geladen_und_zurueckgegeben_wenn_vkz_gesetzt
VKZ gesetzt → verfahrensgebiet_alkis aufgerufen, bror_layer zurückgegeben.rot
TestVerfahrensgebietShapeKomplett
test_bror_wird_vor_shape_vg_ins_projekt_eingefuegt
BROR wird VOR shape_vg ins Projekt eingefügt (kein Namenskonflikt).rot
TestVerfahrensgebietShapeKomplett
test_bror_wird_bei_abbruch_aus_projekt_entfernt
BROR und shape_vg werden bei Fehler aus dem Projekt entfernt.rot
TestVerfahrensgebietShapeKomplett
test_verfahrensgebiet_alkis_nicht_aufgerufen_wenn_vkz_leer
Leere VKZ → verfahrensgebiet_alkis wird NICHT aufgerufen.grün
TestVerfahrensgebietShapeKomplett
test_bror_als_erstes_argument_beim_flaechenvergleich
Mit BROR: _vergleiche_flaechen wird (bror, shape_vg, ...) aufgerufen.rot
TestVerfahrensgebietShapeKomplett
test_fallback_auf_temp_enriched_wenn_bror_ladeversagen
BROR-Ladeversagen → Fallback: _vergleiche_flaechen mit shape_vg vs temp_enriched.rot

— (Docstring fehlt)

TestWorkingTab 24TestHandleVerfShape 9
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestFindShp
test_findet_shp_in_root
— (Docstring fehlt)grünnie geprüft
TestFindShp
test_findet_shp_in_unterordner
— (Docstring fehlt)grünnie geprüft
TestFindShp
test_kein_shp_gibt_none_zurueck
— (Docstring fehlt)grünnie geprüft
TestFindShp
test_case_insensitive_erkennung
— (Docstring fehlt)grünnie geprüft
TestErstelleMemoryLayerAusShp
test_leere_geometrien_geben_none
— (Docstring fehlt)grünnie geprüft
TestErstelleMemoryLayerAusShp
test_keine_features_gibt_none
— (Docstring fehlt)grünnie geprüft
TestErstelleMemoryLayerAusShp
test_attribute_von_erstem_feature_werden_gesetzt
Attributwerte des ersten Features werden auf das Union-Feature übertragen.grünnie geprüft
TestLadeVgAusZip
test_dialog_abgebrochen_gibt_none_zurueck
— (Docstring fehlt)rotnie geprüft
TestLadeVgAusZip
test_zip_fehler_gibt_none_und_warning
— (Docstring fehlt)rotnie geprüft
TestLadeVgAusZip
test_kein_shp_in_zip_gibt_none_und_warning
— (Docstring fehlt)rotnie geprüft
TestLadeVgAusZip
test_invalider_qgslayer_gibt_none_und_warning
— (Docstring fehlt)rotnie geprüft
TestLadeVgAusZip
test_leere_geometrien_geben_none_und_warning
— (Docstring fehlt)rotnie geprüft
TestLadeVgAusZip
test_erfolg_gibt_memory_layer_zurueck
— (Docstring fehlt)rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_lade_zip_none_aborts
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_shape_vg_sofort_ins_projekt_nach_laden
Shape-VG wird unmittelbar nach dem Laden ins Projekt eingefügt.rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_shape_vg_wird_bei_abbruch_aus_projekt_entfernt
Shape-VG wird bei Fehler/Abbruch aus dem Projekt entfernt.rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_shape_vg_bleibt_im_projekt_bei_erfolg
Bei erfolgreichem Abschluss wird shape_vg NICHT aus dem Projekt entfernt.grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_flst_none_aborts
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_keine_flurstuecke_selektiert_gibt_warning
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_flaechen_uebereinstimmung_gibt_info_und_kein_dialog
— (Docstring fehlt)rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_abweichung_abbrechen_gibt_shape_vg_zurueck
— (Docstring fehlt)rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_abweichung_detailpruefung_ruft_knickpunkt_pruefung_auf
— (Docstring fehlt)rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_punktort_ta_none_gibt_shape_vg_zurueck_und_zeigt_fehler
— (Docstring fehlt)rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_temp_layer_wird_stets_entfernt
— (Docstring fehlt)grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_bror_layer_ist_stets_none
Dritter Rückgabewert ist im Shape-Workflow immer None (kein BROR).grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_bror_geladen_und_zurueckgegeben_wenn_vkz_gesetzt
VKZ gesetzt → verfahrensgebiet_alkis aufgerufen, bror_layer zurückgegeben.rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_bror_wird_vor_shape_vg_ins_projekt_eingefuegt
BROR wird VOR shape_vg ins Projekt eingefügt (kein Namenskonflikt).rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_bror_wird_bei_abbruch_aus_projekt_entfernt
BROR und shape_vg werden bei Fehler aus dem Projekt entfernt.rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_verfahrensgebiet_alkis_nicht_aufgerufen_wenn_vkz_leer
Leere VKZ → verfahrensgebiet_alkis wird NICHT aufgerufen.grünnie geprüft
TestVerfahrensgebietShapeKomplett
test_bror_als_erstes_argument_beim_flaechenvergleich
Mit BROR: _vergleiche_flaechen wird (bror, shape_vg, ...) aufgerufen.rotnie geprüft
TestVerfahrensgebietShapeKomplett
test_fallback_auf_temp_enriched_wenn_bror_ladeversagen
BROR-Ladeversagen → Fallback: _vergleiche_flaechen mit shape_vg vs temp_enriched.rotnie geprüft

— (Docstring fehlt)

TestWorkingTab 24TestHandleVerfShape 9
flowchart TD
   root(["test_working_tab.py"])
   class root rootnode
   root --> g1["TestWorkingTab (24)"]
@@ -1050,7 +1055,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestWorkingTab
test_set_busy_updates_button_state
— (Docstring fehlt)grün
TestWorkingTab
test_on_verf_layer_changed_valid_sets_variable
— (Docstring fehlt)grün
TestWorkingTab
test_on_verf_layer_changed_none_clears_variable
— (Docstring fehlt)grün
TestWorkingTab
test_handle_verf_alkis_success_path
verfahrensgebiet_alkis_komplett → 4-Tupel (enriched, flst, bror, FIRST).rot
TestWorkingTab
test_handle_verf_alkis_failure_clears_layer_var
Status NONE → Layer-Variable wird auf '' gesetzt.grün
TestWorkingTab
test_handle_flurst_alkis_first_load_uebernimmt_layer
Erstmaliges Laden über 'Flurstücke laden' fügt den Layer dem Projekt hinzu.grün
TestWorkingTab
test_handle_flurst_aus_gemarkungen_ruft_flurstueck_alkis_ohne_schluessel_abfrage
Der Gemarkungen-Auswahl-Button ruft dieselbe Ladefunktion mit ohne_schluessel_abfrage=True auf (#47).grün
TestWorkingTab
test_handle_flurst_aus_gemarkungen_abbruch_zeigt_keine_zusaetzliche_meldung
Bricht flurstueck_alkis() ab (None, NONE), zeigt der Button keine eigene Meldung – flurstueck_alkis() hat das schon getan (#47).grün
TestWorkingTab
test_handle_grenz_alkis_success_sets_haken
Grenzpunkte erfolgreich geladen → haken_grenz wird gesetzt.rot
TestWorkingTab
test_handle_grenz_alkis_none_result_sets_no_haken
grenzpunkt_alkis liefert (None, None) → kein Haken.rot
TestWorkingTab
test_handle_flurst_alkis_success_sets_haken_and_style
— (Docstring fehlt)grün
TestWorkingTab
test_handle_flurst_alkis_existing_layer_keep_path
— (Docstring fehlt)grün
TestWorkingTab
test_handle_flurst_alkis_invalid_input_returns_early
Status NONE (z. B. Nutzerabbruch) → kein Layer, kein Haken.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_active_layer
Kein aktiver Layer → warning, kein Layer wird erstellt.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_required_fields
Layer ohne Pflichtfelder → warning, kein Layer wird erstellt.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_selection
Keine Flurstück-Auswahl → warning, kein Layer erstellt.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_new_layer_success
Erstlauf ohne bestehenden Layer → Layer wird erstellt und hinzugefügt.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_ergaenzen_dispatch
Entscheidung 'ergaenzen' → ergaenze_verfahrensgebiet wird aufgerufen.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_entfernen_dispatch
Entscheidung 'entfernen' → entferne_aus_verfahrensgebiet wird aufgerufen.grün
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_ersetzen_dispatch
Entscheidung 'ersetzen' → alter Layer entfernt, neuer hinzugefügt.grün
TestWorkingTab
test_aus_liste_button_shows_not_implemented_hint
— (Docstring fehlt)grün
TestWorkingTab
test_handle_gem_alkis_service_reachable_adds_layer
Dienst erreichbar → Layer ins Projekt, Stil angewendet, Haken gesetzt.grün
TestWorkingTab
test_handle_gem_alkis_service_unreachable_shows_warning
Dienst nicht erreichbar (None) → warning, kein addMapLayer.grün
TestWorkingTab
test_handle_gem_alkis_layer_already_exists_shows_info
Layer 'Gemarkungen' bereits vorhanden → info, kein erneutes Laden.grün
TestHandleVerfShape
test_status_none_clears_layer_variable
Status NONE → Layer-Variable wird auf '' gesetzt.grün
TestHandleVerfShape
test_button_always_re_enabled_on_failure
Button muss nach Status NONE wieder freigegeben sein (finally).grün
TestHandleVerfShape
test_verfahrensnummer_nicht_gesetzt_nein_bricht_ab
Verfahrensnummer leer + Nutzer wählt 'Nein' → Vorgang abgebrochen.rot
TestHandleVerfShape
test_verfahrensnummer_nicht_gesetzt_ja_fuehrt_fort
Verfahrensnummer leer + Nutzer wählt 'Ja' → Pipeline wird aufgerufen.rot
TestHandleVerfShape
test_verfahrensnummer_gesetzt_kein_rueckfrage_dialog
Verfahrensnummer gesetzt → kein ask_yes_no-Dialog.grün
TestHandleVerfShape
test_success_path_applies_style_and_sets_haken
Erfolg → verfahrensgebiet.qml angewendet, haken_verf gesetzt, success aufgerufen.grün
TestHandleVerfShape
test_bror_layer_erhaelt_qml_stil
Wenn bror_layer zurückgegeben → BauRaumOderBodenordnungsrecht.qml angewendet.grün
TestHandleVerfShape
test_enriched_layer_already_in_project_not_added_again
Layer bereits im Projekt → kein erneutes addMapLayer für VG-Layer.grün
TestHandleVerfShape
test_busy_state_set_during_execution
Button wird während der Ausführung auf busy gesetzt.grün
+ classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestWorkingTab
test_set_busy_updates_button_state
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_on_verf_layer_changed_valid_sets_variable
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_on_verf_layer_changed_none_clears_variable
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_handle_verf_alkis_success_path
verfahrensgebiet_alkis_komplett → 4-Tupel (enriched, flst, bror, FIRST).rotnie geprüft
TestWorkingTab
test_handle_verf_alkis_failure_clears_layer_var
Status NONE → Layer-Variable wird auf '' gesetzt.grünnie geprüft
TestWorkingTab
test_handle_flurst_alkis_first_load_uebernimmt_layer
Erstmaliges Laden über 'Flurstücke laden' fügt den Layer dem Projekt hinzu.grünnie geprüft
TestWorkingTab
test_handle_flurst_aus_gemarkungen_ruft_flurstueck_alkis_ohne_schluessel_abfrage
Der Gemarkungen-Auswahl-Button ruft dieselbe Ladefunktion mit ohne_schluessel_abfrage=True auf (#47).grünnie geprüft
TestWorkingTab
test_handle_flurst_aus_gemarkungen_abbruch_zeigt_keine_zusaetzliche_meldung
Bricht flurstueck_alkis() ab (None, NONE), zeigt der Button keine eigene Meldung – flurstueck_alkis() hat das schon getan (#47).grünnie geprüft
TestWorkingTab
test_handle_grenz_alkis_success_sets_haken
Grenzpunkte erfolgreich geladen → haken_grenz wird gesetzt.rotnie geprüft
TestWorkingTab
test_handle_grenz_alkis_none_result_sets_no_haken
grenzpunkt_alkis liefert (None, None) → kein Haken.rotnie geprüft
TestWorkingTab
test_handle_flurst_alkis_success_sets_haken_and_style
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_handle_flurst_alkis_existing_layer_keep_path
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_handle_flurst_alkis_invalid_input_returns_early
Status NONE (z. B. Nutzerabbruch) → kein Layer, kein Haken.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_active_layer
Kein aktiver Layer → warning, kein Layer wird erstellt.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_required_fields
Layer ohne Pflichtfelder → warning, kein Layer wird erstellt.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_requires_selection
Keine Flurstück-Auswahl → warning, kein Layer erstellt.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_new_layer_success
Erstlauf ohne bestehenden Layer → Layer wird erstellt und hinzugefügt.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_ergaenzen_dispatch
Entscheidung 'ergaenzen' → ergaenze_verfahrensgebiet wird aufgerufen.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_entfernen_dispatch
Entscheidung 'entfernen' → entferne_aus_verfahrensgebiet wird aufgerufen.grünnie geprüft
TestWorkingTab
test_handle_verfahrensgebiet_from_selection_existing_layer_ersetzen_dispatch
Entscheidung 'ersetzen' → alter Layer entfernt, neuer hinzugefügt.grünnie geprüft
TestWorkingTab
test_aus_liste_button_shows_not_implemented_hint
— (Docstring fehlt)grünnie geprüft
TestWorkingTab
test_handle_gem_alkis_service_reachable_adds_layer
Dienst erreichbar → Layer ins Projekt, Stil angewendet, Haken gesetzt.grünnie geprüft
TestWorkingTab
test_handle_gem_alkis_service_unreachable_shows_warning
Dienst nicht erreichbar (None) → warning, kein addMapLayer.grünnie geprüft
TestWorkingTab
test_handle_gem_alkis_layer_already_exists_shows_info
Layer 'Gemarkungen' bereits vorhanden → info, kein erneutes Laden.grünnie geprüft
TestHandleVerfShape
test_status_none_clears_layer_variable
Status NONE → Layer-Variable wird auf '' gesetzt.grünnie geprüft
TestHandleVerfShape
test_button_always_re_enabled_on_failure
Button muss nach Status NONE wieder freigegeben sein (finally).grünnie geprüft
TestHandleVerfShape
test_verfahrensnummer_nicht_gesetzt_nein_bricht_ab
Verfahrensnummer leer + Nutzer wählt 'Nein' → Vorgang abgebrochen.rotnie geprüft
TestHandleVerfShape
test_verfahrensnummer_nicht_gesetzt_ja_fuehrt_fort
Verfahrensnummer leer + Nutzer wählt 'Ja' → Pipeline wird aufgerufen.rotnie geprüft
TestHandleVerfShape
test_verfahrensnummer_gesetzt_kein_rueckfrage_dialog
Verfahrensnummer gesetzt → kein ask_yes_no-Dialog.grünnie geprüft
TestHandleVerfShape
test_success_path_applies_style_and_sets_haken
Erfolg → verfahrensgebiet.qml angewendet, haken_verf gesetzt, success aufgerufen.grünnie geprüft
TestHandleVerfShape
test_bror_layer_erhaelt_qml_stil
Wenn bror_layer zurückgegeben → BauRaumOderBodenordnungsrecht.qml angewendet.grünnie geprüft
TestHandleVerfShape
test_enriched_layer_already_in_project_not_added_again
Layer bereits im Projekt → kein erneutes addMapLayer für VG-Layer.grünnie geprüft
TestHandleVerfShape
test_busy_state_set_during_execution
Button wird während der Ausführung auf busy gesetzt.grünnie geprüft
@@ -1064,7 +1069,7 @@ -

— (Docstring fehlt)

TestListenauswerter 4
flowchart TD
+  

— (Docstring fehlt)

TestListenauswerter 4
flowchart TD
   root(["test_listenauswerter.py"])
   class root rootnode
   root --> g1["TestListenauswerter (4)"]
@@ -1081,7 +1086,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestListenauswerter
test_validate_rows_accepts_valid_row_and_normalizes_provider
— (Docstring fehlt)grün
TestListenauswerter
test_validate_rows_rejects_missing_required_fields
— (Docstring fehlt)grün
TestListenauswerter
test_validate_rows_sets_stildatei_none_on_style_failure
— (Docstring fehlt)grün
TestListenauswerter
test_validate_rows_handles_non_mapping_rows_edge_case
— (Docstring fehlt)grün

— (Docstring fehlt)

TestTabALogic 9
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestListenauswerter
test_validate_rows_accepts_valid_row_and_normalizes_provider
— (Docstring fehlt)grünnie geprüft
TestListenauswerter
test_validate_rows_rejects_missing_required_fields
— (Docstring fehlt)grünnie geprüft
TestListenauswerter
test_validate_rows_sets_stildatei_none_on_style_failure
— (Docstring fehlt)grünnie geprüft
TestListenauswerter
test_validate_rows_handles_non_mapping_rows_edge_case
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestTabALogic 9
flowchart TD
   root(["test_tab_a_logic.py"])
   class root rootnode
   root --> g1["TestTabALogic (9)"]
@@ -1108,7 +1113,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestTabALogic
test_verfahrens_db_set_and_load_roundtrip
— (Docstring fehlt)grün
TestTabALogic
test_verfahrens_db_clear
— (Docstring fehlt)grün
TestTabALogic
test_linkliste_set_and_load_existing_path
— (Docstring fehlt)grün
TestTabALogic
test_linkliste_load_returns_none_when_file_missing
— (Docstring fehlt)grün
TestTabALogic
test_resolve_linkliste_empty_uses_standard_and_persists
— (Docstring fehlt)grün
TestTabALogic
test_resolve_linkliste_returns_none_when_pruefmanager_rejects
— (Docstring fehlt)grün
TestTabALogic
test_resolve_raumfilter_without_filter_returns_none
— (Docstring fehlt)grün
TestTabALogic
test_resolve_raumfilter_verfahrensgebiet_uses_layer_lookup
— (Docstring fehlt)grün
TestTabALogic
test_extract_datenabruf_error_maps_merges_reason_maps
— (Docstring fehlt)grün

— (Docstring fehlt)

TestTabAPreconditions 3
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestTabALogic
test_verfahrens_db_set_and_load_roundtrip
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_verfahrens_db_clear
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_linkliste_set_and_load_existing_path
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_linkliste_load_returns_none_when_file_missing
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_resolve_linkliste_empty_uses_standard_and_persists
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_resolve_linkliste_returns_none_when_pruefmanager_rejects
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_resolve_raumfilter_without_filter_returns_none
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_resolve_raumfilter_verfahrensgebiet_uses_layer_lookup
— (Docstring fehlt)grünnie geprüft
TestTabALogic
test_extract_datenabruf_error_maps_merges_reason_maps
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestTabAPreconditions 3
flowchart TD
   root(["test_tab_a_preconditions.py"])
   class root rootnode
   root --> g1["TestTabAPreconditions (3)"]
@@ -1123,7 +1128,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestTabAPreconditions
test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing
— (Docstring fehlt)grün
TestTabAPreconditions
test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project
— (Docstring fehlt)grün
TestTabAPreconditions
test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing
— (Docstring fehlt)grün

— (Docstring fehlt)

TestTabAUI 3
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestTabAPreconditions
test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing
— (Docstring fehlt)grünnie geprüft
TestTabAPreconditions
test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project
— (Docstring fehlt)grünnie geprüft
TestTabAPreconditions
test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing
— (Docstring fehlt)grünnie geprüft

— (Docstring fehlt)

TestTabAUI 3
flowchart TD
   root(["test_tab_a_ui.py"])
   class root rootnode
   root --> g1["TestTabAUI (3)"]
@@ -1138,7 +1143,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestTabAUI
test_tab_a_callbacks_can_be_called_without_crash
— (Docstring fehlt)grün
TestTabAUI
test_tab_a_raumfilter_callback_persists_value
— (Docstring fehlt)grün
TestTabAUI
test_set_services_initializes_logic_and_injects_data_grabber
— (Docstring fehlt)rot

Tests für sn_plan41/modules/vln_api_logic.py

TestVlnApiLogicAvailability 2TestVlnApiLogicCredentials 4TestVlnApiLogicLogin 6TestVlnApiLogicVerfahren 2TestVlnApiLogicVkz 4TestVlnApiLogicLoadP41 3TestVlnApiLogicUpload 4
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestTabAUI
test_tab_a_callbacks_can_be_called_without_crash
— (Docstring fehlt)grünnie geprüft
TestTabAUI
test_tab_a_raumfilter_callback_persists_value
— (Docstring fehlt)grünnie geprüft
TestTabAUI
test_set_services_initializes_logic_and_injects_data_grabber
— (Docstring fehlt)rotnie geprüft

Tests für sn_plan41/modules/vln_api_logic.py

TestVlnApiLogicAvailability 2TestVlnApiLogicCredentials 4TestVlnApiLogicLogin 6TestVlnApiLogicVerfahren 2TestVlnApiLogicVkz 4TestVlnApiLogicLoadP41 3TestVlnApiLogicUpload 4
flowchart TD
   root(["test_vln_api_logic.py"])
   class root rootnode
   root --> g1["TestVlnApiLogicAvailability (2)"]
@@ -1209,7 +1214,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestVlnApiLogicAvailability
test_is_available_reflects_import_state
— (Docstring fehlt)grün
TestVlnApiLogicAvailability
test_is_available_false_when_vln_karten_missing
Wenn VLN_KARTEN_AVAILABLE=False, liefert is_available() False.grün
TestVlnApiLogicCredentials
test_save_api_key_calls_qsettings
— (Docstring fehlt)grün
TestVlnApiLogicCredentials
test_clear_api_key_calls_remove
— (Docstring fehlt)grün
TestVlnApiLogicCredentials
test_load_stored_credentials_returns_api_key_and_mail
— (Docstring fehlt)grün
TestVlnApiLogicCredentials
test_load_stored_credentials_returns_none_for_empty
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_login_sets_client_and_saves_key
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_login_raises_runtime_error_without_qgis_modules
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_login_propagates_api_error
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_logout_clears_client
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_is_authenticated_false_after_logout
— (Docstring fehlt)grün
TestVlnApiLogicLogin
test_handle_session_expired_clears_key_and_client
— (Docstring fehlt)grün
TestVlnApiLogicVerfahren
test_get_verfahren_raises_when_not_authenticated
— (Docstring fehlt)grün
TestVlnApiLogicVerfahren
test_get_verfahren_delegates_to_client
— (Docstring fehlt)grün
TestVlnApiLogicVkz
test_load_stored_vkz_reads_from_project
— (Docstring fehlt)grün
TestVlnApiLogicVkz
test_load_stored_vkz_returns_none_for_empty
— (Docstring fehlt)grün
TestVlnApiLogicVkz
test_save_vkz_writes_to_project
— (Docstring fehlt)grün
TestVlnApiLogicVkz
test_save_vkz_does_nothing_for_none
— (Docstring fehlt)grün
TestVlnApiLogicLoadP41
test_load_p41_raises_without_vln_karten
— (Docstring fehlt)grün
TestVlnApiLogicLoadP41
test_load_p41_applies_styles_to_polygon_and_line_layers
— (Docstring fehlt)grün
TestVlnApiLogicLoadP41
test_load_p41_no_style_for_point_layer
— (Docstring fehlt)grün
TestVlnApiLogicUpload
test_upload_returns_error_for_layer_without_api_path
— (Docstring fehlt)grün
TestVlnApiLogicUpload
test_upload_returns_error_for_none_layer
— (Docstring fehlt)grün
TestVlnApiLogicUpload
test_upload_returns_false_without_qgis_modules
— (Docstring fehlt)grün
TestVlnApiLogicUpload
test_upload_calls_save_feature_collection
— (Docstring fehlt)grün
+ classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatusgeprüft
TestVlnApiLogicAvailability
test_is_available_reflects_import_state
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicAvailability
test_is_available_false_when_vln_karten_missing
Wenn VLN_KARTEN_AVAILABLE=False, liefert is_available() False.grünnie geprüft
TestVlnApiLogicCredentials
test_save_api_key_calls_qsettings
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicCredentials
test_clear_api_key_calls_remove
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicCredentials
test_load_stored_credentials_returns_api_key_and_mail
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicCredentials
test_load_stored_credentials_returns_none_for_empty
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_login_sets_client_and_saves_key
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_login_raises_runtime_error_without_qgis_modules
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_login_propagates_api_error
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_logout_clears_client
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_is_authenticated_false_after_logout
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLogin
test_handle_session_expired_clears_key_and_client
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVerfahren
test_get_verfahren_raises_when_not_authenticated
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVerfahren
test_get_verfahren_delegates_to_client
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVkz
test_load_stored_vkz_reads_from_project
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVkz
test_load_stored_vkz_returns_none_for_empty
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVkz
test_save_vkz_writes_to_project
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicVkz
test_save_vkz_does_nothing_for_none
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLoadP41
test_load_p41_raises_without_vln_karten
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLoadP41
test_load_p41_applies_styles_to_polygon_and_line_layers
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicLoadP41
test_load_p41_no_style_for_point_layer
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicUpload
test_upload_returns_error_for_layer_without_api_path
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicUpload
test_upload_returns_error_for_none_layer
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicUpload
test_upload_returns_false_without_qgis_modules
— (Docstring fehlt)grünnie geprüft
TestVlnApiLogicUpload
test_upload_calls_save_feature_collection
— (Docstring fehlt)grünnie geprüft
Erzeugt von python scripts/testkatalog.py aus den unittest-Suiten der sn_*-Plugins. Diagramme gruppieren Testfälle je Testdatei nach unittest.TestCase-Klasse; Farbe zeigt den Baseline-Status (grün / rot / übersprungen), nicht die fachliche Wichtigkeit.
diff --git a/docs/tests/testkatalog.md b/docs/tests/testkatalog.md index abcac7b..3193171 100644 --- a/docs/tests/testkatalog.md +++ b/docs/tests/testkatalog.md @@ -8,18 +8,20 @@ für die fachliche Frage, ob die Abdeckung sinnvoll ist. Die Angaben stammen aus selbst (Docstrings) und aus der Testbaseline. Stand der Baseline: `docs/status/testbaseline.json` (SHA-256 `aeabc946a7f3`) +Stand des Prüf-Audits: `docs/status/testpruefungen.json` **nicht gefunden** – alle Testfälle gelten als nie geprüft. Gesamt: 3 Pakete, 31 Testdateien, 346 Testfälle – 301 grün, 37 rot (Baseline), 8 übersprungen. Mit Beschreibung (Docstring): 114 von 346 (33 %). +Fachlich geprüft: 0 von 346 (0 %) aktuell, 0 veraltet seit Codeänderung, 346 nie geprüft. ## Zusammenfassung -| Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung | -| --- | ---: | ---: | ---: | ---: | ---: | ---: | -| `sn_basis` | 14 | 94 | 94 | 0 | 0 | 7 von 94 (7 %) | -| `sn_verfahrensgebiet` | 12 | 208 | 164 | 36 | 8 | 106 von 208 (51 %) | -| `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) | -| **Summe** | **31** | **346** | **301** | **37** | **8** | **114 von 346 (33 %)** | +| Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung | fachlich geprüft | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| `sn_basis` | 14 | 94 | 94 | 0 | 0 | 7 von 94 (7 %) | 0 von 94 (0 %) | +| `sn_verfahrensgebiet` | 12 | 208 | 164 | 36 | 8 | 106 von 208 (51 %) | 0 von 208 (0 %) | +| `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) | 0 von 44 (0 %) | +| **Summe** | **31** | **346** | **301** | **37** | **8** | **114 von 346 (33 %)** | **0 von 346 (0 %)** | ### Legende @@ -28,6 +30,7 @@ Mit Beschreibung (Docstring): 114 von 346 (33 %). - **rot (Baseline)** – der Testfall schlägt bereits fehl und ist in `docs/status/testbaseline.json` vermerkt; er darf nicht ignoriert, aber auch nicht als neuer Fehler gewertet werden. - **übersprungen** – per `@unittest.skip`/`skipIf`/`skipUnless` abgeschaltet; der Grund steht dabei. - Ein Testfall heißt `Testgruppe.test_name`; die Testgruppe fasst zusammengehörige Testfälle einer Datei zusammen. +- **geprüft** – Prüf-Audit (`scripts/test_audit.py`): **nie geprüft** kein Eintrag in `docs/status/testpruefungen.json`; **geprüft am …** ein Mensch hat den Testfall bestätigt und der Testcode hat sich seither nicht geändert; **veraltet seit Änderung …** der Testcode wurde nach der letzten Prüfung geändert. ## Paket `sn_basis` @@ -47,14 +50,14 @@ Testgruppen: - `TestDataGrabber` (6 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestDataGrabber.test_analyze_source_type_detects_excel` | — (Docstring fehlt) | grün | -| `TestDataGrabber.test_analyze_source_type_returns_unknown_filetype` | — (Docstring fehlt) | grün | -| `TestDataGrabber.test_analyze_source_type_detects_service_when_file_check_fails` | — (Docstring fehlt) | grün | -| `TestDataGrabber.test_analyze_source_type_returns_unbekannte_quelle_on_full_failure` | — (Docstring fehlt) | grün | -| `TestDataGrabber.test_run_returns_success_summary_with_valid_rows` | — (Docstring fehlt) | grün | -| `TestDataGrabber.test_run_returns_failure_summary_without_rows` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestDataGrabber.test_analyze_source_type_detects_excel` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDataGrabber.test_analyze_source_type_returns_unknown_filetype` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDataGrabber.test_analyze_source_type_detects_service_when_file_check_fails` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDataGrabber.test_analyze_source_type_returns_unbekannte_quelle_on_full_failure` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDataGrabber.test_run_returns_success_summary_with_valid_rows` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDataGrabber.test_run_returns_failure_summary_without_rows` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_dateipruefer.py` @@ -64,14 +67,14 @@ Testgruppen: - `TestDateipruefer` (6 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestDateipruefer.test_leereingabe_erlaubt` | — (Docstring fehlt) | grün | -| `TestDateipruefer.test_leereingabe_nicht_erlaubt` | — (Docstring fehlt) | grün | -| `TestDateipruefer.test_standarddatei_vorschlagen` | — (Docstring fehlt) | grün | -| `TestDateipruefer.test_temporaer_erlaubt` | — (Docstring fehlt) | grün | -| `TestDateipruefer.test_datei_nicht_gefunden` | — (Docstring fehlt) | grün | -| `TestDateipruefer.test_datei_ok` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestDateipruefer.test_leereingabe_erlaubt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDateipruefer.test_leereingabe_nicht_erlaubt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDateipruefer.test_standarddatei_vorschlagen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDateipruefer.test_temporaer_erlaubt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDateipruefer.test_datei_nicht_gefunden` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDateipruefer.test_datei_ok` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_laenderkennung.py` @@ -81,13 +84,13 @@ Testgruppen: - `TestGetLaenderkennung` (5 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestGetLaenderkennung.test_bekannter_praefix_gibt_kennung_zurueck` | — (Docstring fehlt) | grün | -| `TestGetLaenderkennung.test_praefix_gross_klein_unabhaengig` | — (Docstring fehlt) | grün | -| `TestGetLaenderkennung.test_unbekannter_praefix_wirft_keyerror` | — (Docstring fehlt) | grün | -| `TestGetLaenderkennung.test_ohne_argument_wird_aus_aufrufendem_modul_abgeleitet` | — (Docstring fehlt) | grün | -| `TestGetLaenderkennung.test_mapping_enthaelt_sachsen` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestGetLaenderkennung.test_bekannter_praefix_gibt_kennung_zurueck` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetLaenderkennung.test_praefix_gross_klein_unabhaengig` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetLaenderkennung.test_unbekannter_praefix_wirft_keyerror` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetLaenderkennung.test_ohne_argument_wird_aus_aufrufendem_modul_abgeleitet` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetLaenderkennung.test_mapping_enthaelt_sachsen` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_layerpruefer.py` @@ -97,18 +100,18 @@ Testgruppen: - `TestLayerpruefer` (10 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestLayerpruefer.test_layer_exists` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_layer_unsichtbar` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_falscher_layertyp` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_falscher_geotyp` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_layer_leer` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_falsches_crs` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_felder_fehlen` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_datenquelle_unerwartet` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_layer_nicht_editierbar` | — (Docstring fehlt) | grün | -| `TestLayerpruefer.test_layer_ok` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestLayerpruefer.test_layer_exists` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_layer_unsichtbar` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_falscher_layertyp` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_falscher_geotyp` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_layer_leer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_falsches_crs` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_felder_fehlen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_datenquelle_unerwartet` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_layer_nicht_editierbar` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLayerpruefer.test_layer_ok` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_linkpruefer.py` @@ -118,13 +121,13 @@ Testgruppen: - `TestLinkpruefer` (5 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestLinkpruefer.test_remote_link_ok` | — (Docstring fehlt) | grün | -| `TestLinkpruefer.test_remote_link_error` | — (Docstring fehlt) | grün | -| `TestLinkpruefer.test_remote_link_network_error` | — (Docstring fehlt) | grün | -| `TestLinkpruefer.test_local_link_not_found` | — (Docstring fehlt) | grün | -| `TestLinkpruefer.test_local_link_ok` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestLinkpruefer.test_remote_link_ok` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLinkpruefer.test_remote_link_error` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLinkpruefer.test_remote_link_network_error` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLinkpruefer.test_local_link_not_found` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLinkpruefer.test_local_link_ok` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_print_layout.py` @@ -134,13 +137,13 @@ Testgruppen: - `TestPrintLayout` (5 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestPrintLayout.test_create_legend_item_links_map_and_enables_map_filtering` | — (Docstring fehlt) | grün | -| `TestPrintLayout.test_create_legend_item_does_not_copy_project_layers_into_legend_model` | — (Docstring fehlt) | grün | -| `TestPrintLayout.test_configure_legend_size_uses_content_adaptive_size` | — (Docstring fehlt) | grün | -| `TestPrintLayout.test_configure_hauptkarte_grids_uses_wrapper_constants` | — (Docstring fehlt) | grün | -| `TestPrintLayout.test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestPrintLayout.test_create_legend_item_links_map_and_enables_map_filtering` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLayout.test_create_legend_item_does_not_copy_project_layers_into_legend_model` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLayout.test_configure_legend_size_uses_content_adaptive_size` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLayout.test_configure_hauptkarte_grids_uses_wrapper_constants` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLayout.test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_print_logic.py` @@ -150,25 +153,25 @@ Testgruppen: - `TestPrintLogic` (17 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestPrintLogic.test_get_baufreigabe_page_dimensions_prefers_a4_for_small_extent` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_baufreigabe_page_dimensions_escalates_to_a3` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_baufreigabe_page_dimensions_respects_a4_as_maximum_with_fallback` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_baufreigabe_page_dimensions_falls_back_to_a3_for_oversize_extent` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_select_standard_page_layout_uses_a4_as_minimum_sheet` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_select_standard_page_layout_limits_hauptkarte_to_a3` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_select_standard_page_layout_returns_none_if_a3_is_too_small` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_standard_layout_dimensions_uses_a4_and_forces_fit_for_small_extent` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_standard_layout_dimensions_caps_endlosrolle_width_at_2000_mm` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_apply_standard_minimum_a4_fallback_for_small_page` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_apply_standard_minimum_a4_fallback_keeps_large_page` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_does_plot_fit_page_true_for_standard_a4` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_does_plot_fit_page_false_if_objects_exceed_page` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_set_druckbereich_accepts_wie_kartenfenster` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_get_canvas_extent_returns_valid_extent` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_resolve_extent_uses_canvas_extent_without_buffer` | — (Docstring fehlt) | grün | -| `TestPrintLogic.test_resolve_extent_uses_rectangle_extent_without_buffer` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestPrintLogic.test_get_baufreigabe_page_dimensions_prefers_a4_for_small_extent` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_baufreigabe_page_dimensions_escalates_to_a3` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_baufreigabe_page_dimensions_respects_a4_as_maximum_with_fallback` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_baufreigabe_page_dimensions_falls_back_to_a3_for_oversize_extent` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_select_standard_page_layout_uses_a4_as_minimum_sheet` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_select_standard_page_layout_limits_hauptkarte_to_a3` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_select_standard_page_layout_returns_none_if_a3_is_too_small` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_standard_layout_dimensions_uses_a4_and_forces_fit_for_small_extent` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_standard_layout_dimensions_caps_endlosrolle_width_at_2000_mm` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_apply_standard_minimum_a4_fallback_for_small_page` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_apply_standard_minimum_a4_fallback_keeps_large_page` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_does_plot_fit_page_true_for_standard_a4` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_does_plot_fit_page_false_if_objects_exceed_page` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_set_druckbereich_accepts_wie_kartenfenster` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_get_canvas_extent_returns_valid_extent` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_resolve_extent_uses_canvas_extent_without_buffer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPrintLogic.test_resolve_extent_uses_rectangle_extent_without_buffer` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_pruefmanager.py` @@ -178,22 +181,22 @@ Testgruppen: - `TestPruefmanager` (14 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestPruefmanager.test_ok` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_leereingabe_erlaubt_ja` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_leereingabe_erlaubt_nein` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_standarddatei_vorschlagen_ja` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_standarddatei_vorschlagen_nein` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_temporaer_erlaubt_ja` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_temporaer_erlaubt_nein` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_layer_unsichtbar_ja` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_layer_unsichtbar_nein` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_unbekannte_aktion` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_datei_existiert_overwrite` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_datei_existiert_append` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_datei_existiert_cancel` | — (Docstring fehlt) | grün | -| `TestPruefmanager.test_datei_existiert_in_non_qgis_mode_returns_input` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestPruefmanager.test_ok` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_leereingabe_erlaubt_ja` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_leereingabe_erlaubt_nein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_standarddatei_vorschlagen_ja` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_standarddatei_vorschlagen_nein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_temporaer_erlaubt_ja` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_temporaer_erlaubt_nein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_layer_unsichtbar_ja` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_layer_unsichtbar_nein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_unbekannte_aktion` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_datei_existiert_overwrite` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_datei_existiert_append` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_datei_existiert_cancel` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefmanager.test_datei_existiert_in_non_qgis_mode_returns_input` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_settings_logic.py` @@ -203,12 +206,12 @@ Testgruppen: - `TestSettingsLogic` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestSettingsLogic.test_load` | — (Docstring fehlt) | grün | -| `TestSettingsLogic.test_save` | — (Docstring fehlt) | grün | -| `TestSettingsLogic.test_load_handles_partial_values_with_empty_fallback` | — (Docstring fehlt) | grün | -| `TestSettingsLogic.test_save_empty_string_value_is_persisted` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestSettingsLogic.test_load` | — (Docstring fehlt) | grün | nie geprüft | +| `TestSettingsLogic.test_save` | — (Docstring fehlt) | grün | nie geprüft | +| `TestSettingsLogic.test_load_handles_partial_values_with_empty_fallback` | — (Docstring fehlt) | grün | nie geprüft | +| `TestSettingsLogic.test_save_empty_string_value_is_persisted` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_stilpruefer.py` @@ -218,12 +221,12 @@ Testgruppen: - `TestStilpruefer` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestStilpruefer.test_keine_datei_angegeben` | — (Docstring fehlt) | grün | -| `TestStilpruefer.test_datei_existiert_mit_qml` | — (Docstring fehlt) | grün | -| `TestStilpruefer.test_datei_existiert_falsche_endung` | — (Docstring fehlt) | grün | -| `TestStilpruefer.test_datei_existiert_nicht` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestStilpruefer.test_keine_datei_angegeben` | — (Docstring fehlt) | grün | nie geprüft | +| `TestStilpruefer.test_datei_existiert_mit_qml` | — (Docstring fehlt) | grün | nie geprüft | +| `TestStilpruefer.test_datei_existiert_falsche_endung` | — (Docstring fehlt) | grün | nie geprüft | +| `TestStilpruefer.test_datei_existiert_nicht` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_text_wrapper.py` @@ -233,15 +236,15 @@ Testgruppen: - `TestSanitizeBezeichner` (7 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestSanitizeBezeichner.test_umlaute_bleiben_erhalten` | Prüft, dass Umlaute und ß nicht durch den Ersatz entfernt werden. | grün | -| `TestSanitizeBezeichner.test_bindestrich_bleibt_erhalten` | Prüft, dass ein Bindestrich im Bezeichner erhalten bleibt (Issue #42). | grün | -| `TestSanitizeBezeichner.test_unterstrich_bleibt_erhalten` | Prüft, dass ein Unterstrich im Bezeichner erhalten bleibt. | grün | -| `TestSanitizeBezeichner.test_leerzeichen_wird_durch_ersatz_zusammengefasst` | Prüft, dass Leerzeichen (kein zulässiges Zeichen) zu einem Ersatzzeichen werden. | grün | -| `TestSanitizeBezeichner.test_fuehrender_und_folgender_ersatz_wird_entfernt` | Prüft, dass ein Ersatzzeichen am Anfang oder Ende des Ergebnisses entfernt wird. | grün | -| `TestSanitizeBezeichner.test_eigenes_ersatzzeichen_wird_verwendet` | Prüft, dass ein abweichendes Ersatzzeichen anstelle von Unterstrich genutzt wird. | grün | -| `TestSanitizeBezeichner.test_nur_unzulaessige_zeichen_ergibt_leeren_string` | Prüft, dass ein Bezeichner ganz aus unzulässigen Zeichen zu einem leeren String wird. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestSanitizeBezeichner.test_umlaute_bleiben_erhalten` | Prüft, dass Umlaute und ß nicht durch den Ersatz entfernt werden. | grün | nie geprüft | +| `TestSanitizeBezeichner.test_bindestrich_bleibt_erhalten` | Prüft, dass ein Bindestrich im Bezeichner erhalten bleibt (Issue #42). | grün | nie geprüft | +| `TestSanitizeBezeichner.test_unterstrich_bleibt_erhalten` | Prüft, dass ein Unterstrich im Bezeichner erhalten bleibt. | grün | nie geprüft | +| `TestSanitizeBezeichner.test_leerzeichen_wird_durch_ersatz_zusammengefasst` | Prüft, dass Leerzeichen (kein zulässiges Zeichen) zu einem Ersatzzeichen werden. | grün | nie geprüft | +| `TestSanitizeBezeichner.test_fuehrender_und_folgender_ersatz_wird_entfernt` | Prüft, dass ein Ersatzzeichen am Anfang oder Ende des Ergebnisses entfernt wird. | grün | nie geprüft | +| `TestSanitizeBezeichner.test_eigenes_ersatzzeichen_wird_verwendet` | Prüft, dass ein abweichendes Ersatzzeichen anstelle von Unterstrich genutzt wird. | grün | nie geprüft | +| `TestSanitizeBezeichner.test_nur_unzulaessige_zeichen_ergibt_leeren_string` | Prüft, dass ein Bezeichner ganz aus unzulässigen Zeichen zu einem leeren String wird. | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_variable_wrapper.py` @@ -251,14 +254,14 @@ Testgruppen: - `TestVariableWrapper` (6 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestVariableWrapper.test_set_variable_project_noop_write_is_skipped` | — (Docstring fehlt) | grün | -| `TestVariableWrapper.test_set_variable_project_changed_value_is_written` | — (Docstring fehlt) | grün | -| `TestVariableWrapper.test_set_variable_global_writes_prefixed_name` | — (Docstring fehlt) | grün | -| `TestVariableWrapper.test_get_variable_global_returns_empty_string_fallback` | — (Docstring fehlt) | grün | -| `TestVariableWrapper.test_get_variable_invalid_scope_raises` | — (Docstring fehlt) | grün | -| `TestVariableWrapper.test_set_variable_invalid_scope_raises` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestVariableWrapper.test_set_variable_project_noop_write_is_skipped` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVariableWrapper.test_set_variable_project_changed_value_is_written` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVariableWrapper.test_set_variable_global_writes_prefixed_name` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVariableWrapper.test_get_variable_global_returns_empty_string_fallback` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVariableWrapper.test_get_variable_invalid_scope_raises` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVariableWrapper.test_set_variable_invalid_scope_raises` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Basis/tests/test_verfahrensgebiet_manager.py` @@ -268,13 +271,13 @@ Testgruppen: - `TestVerfahrensgebietManager` (5 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestVerfahrensgebietManager.test_get_verfahrensgebiet_layer_id_returns_value` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietManager.test_get_verfahrensgebiet_layer_id_returns_none_for_empty_value` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietManager.test_set_verfahrensgebiet_layer_id_writes_project_variable` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietManager.test_update_without_layer_does_not_write_when_already_empty` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietManager.test_update_with_layer_writes_variable` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestVerfahrensgebietManager.test_get_verfahrensgebiet_layer_id_returns_value` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietManager.test_get_verfahrensgebiet_layer_id_returns_none_for_empty_value` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietManager.test_set_verfahrensgebiet_layer_id_writes_project_variable` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietManager.test_update_without_layer_does_not_write_when_already_empty` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietManager.test_update_with_layer_writes_variable` | — (Docstring fehlt) | grün | nie geprüft | ## Paket `sn_verfahrensgebiet` @@ -294,33 +297,33 @@ Testgruppen: - `TestBeteiligungPruefenDispatch` (2 Testfälle): Dispatch-Logik in beteiligung_pruefen(): try1 unverändert, try2/try3 - `TestLadeBeteiligungCsv` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestBaueFlurstueckCsv.test_normalfall_mit_fuehrenden_nullen` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_null_wird_zu_unterstrichen` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_leer_wird_zu_unterstrichen` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_gemarkung_ohne_fuehrende_nullen_wird_aufgefuellt` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_ungueltiges_format_gibt_none` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_leerer_wert_gibt_none` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_9001_wird_zu_buchstabe_a` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_9002_wird_zu_buchstabe_b` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_9026_wird_zu_buchstabe_z` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_ausserhalb_buchstaben_bereich_bleibt_numerisch` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_nenner_9001_mit_fuehrenden_nullen_wird_erkannt` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsv.test_einstellige_folge_wird_auf_2_stellen_aufgefuellt` | — (Docstring fehlt) | grün | -| `TestBaueFlurstueckCsvListe.test_nur_gueltige_zeilen_in_liste` | — (Docstring fehlt) | grün | -| `TestHoleVerfahrensgebietLayer.test_layer_per_name_hat_vorrang_vor_combo_auswahl` | — (Docstring fehlt) | grün | -| `TestHoleVerfahrensgebietLayer.test_combo_auswahl_als_fallback_ohne_namens_layer` | — (Docstring fehlt) | grün | -| `TestHoleVerfahrensgebietLayer.test_kein_layer_gibt_none` | — (Docstring fehlt) | grün | -| `TestFordereManuellesLadenAn.test_ohne_vef_vkzf_nennt_fehlende_kennzeichen` | — (Docstring fehlt) | grün | -| `TestFordereManuellesLadenAn.test_mit_vef_vkzf_nennt_verfahrensnummer` | — (Docstring fehlt) | grün | -| `TestTry3Bootstrap.test_setzt_verfahrensnummer_und_fordert_manuelles_laden_an` | — (Docstring fehlt) | grün | -| `TestBeteiligungPruefenDispatch.test_layer_ohne_kennzeichen_fordert_manuelles_laden_an` | — (Docstring fehlt) | grün | -| `TestBeteiligungPruefenDispatch.test_kein_layer_setzt_verfahrensnummer_und_fordert_laden_an` | — (Docstring fehlt) | grün | -| `TestLadeBeteiligungCsv.test_dialog_abgebrochen_gibt_none` | — (Docstring fehlt) | grün | -| `TestLadeBeteiligungCsv.test_fehlende_flurstueck_spalte_wirft_fehler` | — (Docstring fehlt) | grün | -| `TestLadeBeteiligungCsv.test_leere_datei_wirft_fehler` | — (Docstring fehlt) | grün | -| `TestLadeBeteiligungCsv.test_erfolgsfall_gibt_zeilen_und_spalten_zurueck` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestBaueFlurstueckCsv.test_normalfall_mit_fuehrenden_nullen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_null_wird_zu_unterstrichen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_leer_wird_zu_unterstrichen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_gemarkung_ohne_fuehrende_nullen_wird_aufgefuellt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_ungueltiges_format_gibt_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_leerer_wert_gibt_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_9001_wird_zu_buchstabe_a` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_9002_wird_zu_buchstabe_b` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_9026_wird_zu_buchstabe_z` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_ausserhalb_buchstaben_bereich_bleibt_numerisch` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_nenner_9001_mit_fuehrenden_nullen_wird_erkannt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsv.test_einstellige_folge_wird_auf_2_stellen_aufgefuellt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBaueFlurstueckCsvListe.test_nur_gueltige_zeilen_in_liste` | — (Docstring fehlt) | grün | nie geprüft | +| `TestHoleVerfahrensgebietLayer.test_layer_per_name_hat_vorrang_vor_combo_auswahl` | — (Docstring fehlt) | grün | nie geprüft | +| `TestHoleVerfahrensgebietLayer.test_combo_auswahl_als_fallback_ohne_namens_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestHoleVerfahrensgebietLayer.test_kein_layer_gibt_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFordereManuellesLadenAn.test_ohne_vef_vkzf_nennt_fehlende_kennzeichen` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFordereManuellesLadenAn.test_mit_vef_vkzf_nennt_verfahrensnummer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTry3Bootstrap.test_setzt_verfahrensnummer_und_fordert_manuelles_laden_an` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBeteiligungPruefenDispatch.test_layer_ohne_kennzeichen_fordert_manuelles_laden_an` | — (Docstring fehlt) | grün | nie geprüft | +| `TestBeteiligungPruefenDispatch.test_kein_layer_setzt_verfahrensnummer_und_fordert_laden_an` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLadeBeteiligungCsv.test_dialog_abgebrochen_gibt_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLadeBeteiligungCsv.test_fehlende_flurstueck_spalte_wirft_fehler` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLadeBeteiligungCsv.test_leere_datei_wirft_fehler` | — (Docstring fehlt) | grün | nie geprüft | +| `TestLadeBeteiligungCsv.test_erfolgsfall_gibt_zeilen_und_spalten_zurueck` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_dockwidget.py` @@ -330,10 +333,10 @@ Testgruppen: - `TestDockWidget` (2 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestDockWidget.test_init_tabs_with_services_injects_available_services` | — (Docstring fehlt) | grün | -| `TestDockWidget.test_init_tabs_with_services_reports_errors` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestDockWidget.test_init_tabs_with_services_injects_available_services` | — (Docstring fehlt) | grün | nie geprüft | +| `TestDockWidget.test_init_tabs_with_services_reports_errors` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_flurstueck_alkis.py` @@ -344,23 +347,23 @@ Testgruppen: - `TestFlurstueckAlkis` (12 Testfälle): — (Docstring fehlt) - `TestFlurstueckAlkisAnhaengenDedup` (3 Testfälle): Anhängen an einen bestehenden Flurstück-Layer (Issue #28). -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestFlurstueckAlkis.test_user_cancel_returns_none` | ask_text → ok=False, text="" → (None, NONE). | grün | -| `TestFlurstueckAlkis.test_empty_text_after_confirmation_returns_none` | ask_text → ok=True, aber Text leer → (None, NONE). | grün | -| `TestFlurstueckAlkis.test_invalid_wfs_layer_returns_none` | WFS-Layer nicht valide → (None, NONE). | grün | -| `TestFlurstueckAlkis.test_success_returns_layer_and_first_status` | Kein bestehender Layer, WFS valide → (layer, FIRST). | rot (Baseline) | -| `TestFlurstueckAlkis.test_sql_filter_contains_all_schluessel` | Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel. | rot (Baseline) | -| `TestFlurstueckAlkis.test_existing_layer_reload_yes` | Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD. | rot (Baseline) | -| `TestFlurstueckAlkis.test_existing_layer_keep_no` | Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP. | rot (Baseline) | -| `TestFlurstueckAlkis.test_vorgabe_schluessel_prefills_default_text` | vorgabe_schluessel=['1234','5678'] → ask_text erhält '1234, 5678' als default_text. | rot (Baseline) | -| `TestFlurstueckAlkis.test_vorgabe_namen_appears_in_label` | vorgabe_namen=['Musterstadt'] → ask_text-label enthält den Namen. | rot (Baseline) | -| `TestFlurstueckAlkis.test_bbox_embedded_in_wfs_uri` | bbox-Parameter → WFS-URI enthält 'bbox=' Substring. | rot (Baseline) | -| `TestFlurstueckAlkis.test_backwards_compatible_no_new_params` | flurstueck_alkis(tab) ohne neue Parameter → kein Fehler. | rot (Baseline) | -| `TestFlurstueckAlkis.test_ohne_schluessel_abfrage_ueberspringt_ask_text` | ohne_schluessel_abfrage=True verwendet vorgabe_schluessel direkt, ohne ask_text aufzurufen. | grün | -| `TestFlurstueckAlkisAnhaengenDedup.test_append_ueberspringt_bereits_vorhandene_flurstuecke` | Prüft, dass beim Anhängen bereits vorhandene flurstueckskennzeichen nicht erneut hinzugefügt werden. | grün | -| `TestFlurstueckAlkisAnhaengenDedup.test_append_ohne_kennzeichen_feld_haengt_alles_an` | Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten). | grün | -| `TestFlurstueckAlkisAnhaengenDedup.test_ohne_schluessel_abfrage_append_dedup` | ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47). | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestFlurstueckAlkis.test_user_cancel_returns_none` | ask_text → ok=False, text="" → (None, NONE). | grün | nie geprüft | +| `TestFlurstueckAlkis.test_empty_text_after_confirmation_returns_none` | ask_text → ok=True, aber Text leer → (None, NONE). | grün | nie geprüft | +| `TestFlurstueckAlkis.test_invalid_wfs_layer_returns_none` | WFS-Layer nicht valide → (None, NONE). | grün | nie geprüft | +| `TestFlurstueckAlkis.test_success_returns_layer_and_first_status` | Kein bestehender Layer, WFS valide → (layer, FIRST). | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_sql_filter_contains_all_schluessel` | Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_existing_layer_reload_yes` | Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_existing_layer_keep_no` | Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_vorgabe_schluessel_prefills_default_text` | vorgabe_schluessel=['1234','5678'] → ask_text erhält '1234, 5678' als default_text. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_vorgabe_namen_appears_in_label` | vorgabe_namen=['Musterstadt'] → ask_text-label enthält den Namen. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_bbox_embedded_in_wfs_uri` | bbox-Parameter → WFS-URI enthält 'bbox=' Substring. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_backwards_compatible_no_new_params` | flurstueck_alkis(tab) ohne neue Parameter → kein Fehler. | rot (Baseline) | nie geprüft | +| `TestFlurstueckAlkis.test_ohne_schluessel_abfrage_ueberspringt_ask_text` | ohne_schluessel_abfrage=True verwendet vorgabe_schluessel direkt, ohne ask_text aufzurufen. | grün | nie geprüft | +| `TestFlurstueckAlkisAnhaengenDedup.test_append_ueberspringt_bereits_vorhandene_flurstuecke` | Prüft, dass beim Anhängen bereits vorhandene flurstueckskennzeichen nicht erneut hinzugefügt werden. | grün | nie geprüft | +| `TestFlurstueckAlkisAnhaengenDedup.test_append_ohne_kennzeichen_feld_haengt_alles_an` | Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten). | grün | nie geprüft | +| `TestFlurstueckAlkisAnhaengenDedup.test_ohne_schluessel_abfrage_append_dedup` | ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47). | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_gemarkung_alkis.py` @@ -373,22 +376,22 @@ Testgruppen: - `TestGemarkungSchluesselnurNummern` (2 Testfälle): — (Docstring fehlt) - `TestLadeGemarkungenlayer` (2 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestExtractSchluesselUndName.test_standard_attribute` | — (Docstring fehlt) | rot (Baseline) | -| `TestExtractSchluesselUndName.test_fallback_attribute` | — (Docstring fehlt) | rot (Baseline) | -| `TestExtractSchluesselUndName.test_missing_attribute_returns_empty` | — (Docstring fehlt) | grün | -| `TestExtractSchluesselUndName.test_none_value_returns_empty` | — (Docstring fehlt) | grün | -| `TestGemarkungSchluesselbbox.test_success_bbox_filter` | WFS-BBox-Filter liefert Features → korrekte Tupel-Liste. | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselbbox.test_fallback_when_bbox_fails` | BBox-Filter schlägt fehl → Fallback auf Volllade + client-seitige Filterung. | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselbbox.test_both_layers_fail_returns_empty` | Beide Lade-Strategien scheitern → leere Liste. | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselbbox.test_deduplication_and_sorting` | Doppelte Schlüssel werden dedupliziert, Ergebnis ist sortiert. | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselbbox.test_feature_without_schluessel_skipped` | Feature ohne Schlüssel-Attribut wird übersprungen. | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselbbox.test_exception_returns_empty` | Exception im Ladevorgang → leere Liste (kein Crash). | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselnurNummern.test_returns_only_nummern` | — (Docstring fehlt) | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestGemarkungSchluesselnurNummern.test_empty_input_returns_empty` | — (Docstring fehlt) | übersprungen – Legacy API (by_bbox) not available in current module | -| `TestLadeGemarkungenlayer.test_returns_layer_when_service_reachable` | Dienst erreichbar (isValid=True) → Layer-Objekt zurückgegeben. | grün | -| `TestLadeGemarkungenlayer.test_returns_none_when_service_unreachable` | Dienst nicht erreichbar (isValid=False) → None zurückgegeben. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestExtractSchluesselUndName.test_standard_attribute` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestExtractSchluesselUndName.test_fallback_attribute` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestExtractSchluesselUndName.test_missing_attribute_returns_empty` | — (Docstring fehlt) | grün | nie geprüft | +| `TestExtractSchluesselUndName.test_none_value_returns_empty` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGemarkungSchluesselbbox.test_success_bbox_filter` | WFS-BBox-Filter liefert Features → korrekte Tupel-Liste. | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselbbox.test_fallback_when_bbox_fails` | BBox-Filter schlägt fehl → Fallback auf Volllade + client-seitige Filterung. | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselbbox.test_both_layers_fail_returns_empty` | Beide Lade-Strategien scheitern → leere Liste. | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselbbox.test_deduplication_and_sorting` | Doppelte Schlüssel werden dedupliziert, Ergebnis ist sortiert. | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselbbox.test_feature_without_schluessel_skipped` | Feature ohne Schlüssel-Attribut wird übersprungen. | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselbbox.test_exception_returns_empty` | Exception im Ladevorgang → leere Liste (kein Crash). | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselnurNummern.test_returns_only_nummern` | — (Docstring fehlt) | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestGemarkungSchluesselnurNummern.test_empty_input_returns_empty` | — (Docstring fehlt) | übersprungen – Legacy API (by_bbox) not available in current module | nie geprüft | +| `TestLadeGemarkungenlayer.test_returns_layer_when_service_reachable` | Dienst erreichbar (isValid=True) → Layer-Objekt zurückgegeben. | grün | nie geprüft | +| `TestLadeGemarkungenlayer.test_returns_none_when_service_unreachable` | Dienst nicht erreichbar (isValid=False) → None zurückgegeben. | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_grenzpunkt_alkis.py` @@ -399,20 +402,20 @@ Testgruppen: - `TestExtrahiereGmlIds` (5 Testfälle): — (Docstring fehlt) - `TestGrenzpunktAlkis` (7 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestExtrahiereGmlIds.test_xlink_href_format` | URN-Format 'urn:adv:oid:DEABC123' → nur 'DEABC123' extrahiert. | grün | -| `TestExtrahiereGmlIds.test_plain_gml_id` | Plain-GML-ID ohne Doppelpunkt → direkt übernommen. | grün | -| `TestExtrahiereGmlIds.test_empty_value_skipped` | Leerer gehoertZu-Wert wird übersprungen. | grün | -| `TestExtrahiereGmlIds.test_deduplication` | Doppelte Referenzen werden dedupliziert. | grün | -| `TestExtrahiereGmlIds.test_sorted_output` | Rückgabe ist aufsteigend sortiert. | grün | -| `TestGrenzpunktAlkis.test_no_vg_layer_returns_none` | — (Docstring fehlt) | grün | -| `TestGrenzpunktAlkis.test_invalid_punktort_layer` | — (Docstring fehlt) | grün | -| `TestGrenzpunktAlkis.test_empty_punktort_layer` | — (Docstring fehlt) | grün | -| `TestGrenzpunktAlkis.test_no_gml_ids_returns_pta_only` | — (Docstring fehlt) | rot (Baseline) | -| `TestGrenzpunktAlkis.test_grenzpunkt_batch_empty` | — (Docstring fehlt) | rot (Baseline) | -| `TestGrenzpunktAlkis.test_success_returns_both_layers` | — (Docstring fehlt) | rot (Baseline) | -| `TestGrenzpunktAlkis.test_extent_derived_from_vg_layer` | Wenn kein extent übergeben → Extent aus VG-Layer holen. | rot (Baseline) | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestExtrahiereGmlIds.test_xlink_href_format` | URN-Format 'urn:adv:oid:DEABC123' → nur 'DEABC123' extrahiert. | grün | nie geprüft | +| `TestExtrahiereGmlIds.test_plain_gml_id` | Plain-GML-ID ohne Doppelpunkt → direkt übernommen. | grün | nie geprüft | +| `TestExtrahiereGmlIds.test_empty_value_skipped` | Leerer gehoertZu-Wert wird übersprungen. | grün | nie geprüft | +| `TestExtrahiereGmlIds.test_deduplication` | Doppelte Referenzen werden dedupliziert. | grün | nie geprüft | +| `TestExtrahiereGmlIds.test_sorted_output` | Rückgabe ist aufsteigend sortiert. | grün | nie geprüft | +| `TestGrenzpunktAlkis.test_no_vg_layer_returns_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGrenzpunktAlkis.test_invalid_punktort_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGrenzpunktAlkis.test_empty_punktort_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGrenzpunktAlkis.test_no_gml_ids_returns_pta_only` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestGrenzpunktAlkis.test_grenzpunkt_batch_empty` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestGrenzpunktAlkis.test_success_returns_both_layers` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestGrenzpunktAlkis.test_extent_derived_from_vg_layer` | Wenn kein extent übergeben → Extent aus VG-Layer holen. | rot (Baseline) | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_knickpunkt_pruefung.py` @@ -425,21 +428,21 @@ Testgruppen: - `TestKnickpunktPruefungKlassifizierung` (2 Testfälle): Testet die Grün/Rot/Orange-Klassifizierung mit gesteuertem QGIS-Mock. - `TestFehlendKnickpunkteViaVerbindungslinien` (4 Testfälle): Direkte Tests für `_fehlende_knickpunkte_via_verbindungslinien`. -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestExtrahiereKnickpunkte.test_leerer_layer_gibt_leere_liste` | — (Docstring fehlt) | grün | -| `TestExtrahiereKnickpunkte.test_keine_gueltige_geometrie_gibt_leere_liste` | — (Docstring fehlt) | grün | -| `TestExtrahiereKnickpunkte.test_feature_mit_leerer_geometrie_gibt_leere_liste` | — (Docstring fehlt) | grün | -| `TestExtrahiereKnickpunkte.test_qgis_nicht_verfuegbar_gibt_leere_liste` | Wenn qgis.core kein QgsPointXY hat (ImportError in Funktion), leere Liste. | grün | -| `TestKnickpunktPruefungInputvalidierung.test_keine_knickpunkte_gibt_none_zurueck` | — (Docstring fehlt) | grün | -| `TestKnickpunktPruefungInputvalidierung.test_kein_punktort_layer_gibt_none_zurueck` | — (Docstring fehlt) | grün | -| `TestKnickpunktPruefungInputvalidierung.test_abbruch_via_progress_gibt_none_zurueck` | — (Docstring fehlt) | grün | -| `TestKnickpunktPruefungKlassifizierung.test_identischer_punkt_wird_gruen_gezaehlt` | PunktortTA exakt am Knickpunkt → identisch_count == 1. | grün | -| `TestKnickpunktPruefungKlassifizierung.test_kein_pta_an_knickpunkt_wird_rot_gezaehlt` | Kein PunktortTA am Knickpunkt → kein_pta_count == 1. | grün | -| `TestFehlendKnickpunkteViaVerbindungslinien.test_leere_union_gibt_null_zurueck` | bror_union.isEmpty() == True → (0, []). | grün | -| `TestFehlendKnickpunkteViaVerbindungslinien.test_weniger_als_zwei_pta_auf_ring_kein_orange` | Nur 1 gematchter PunktortTA auf Ring → keine fehlenden Knickpunkte. | grün | -| `TestFehlendKnickpunkteViaVerbindungslinien.test_ungematchter_pta_im_puffer_wird_orange` | Nicht-gematchter PunktortTA innerhalb 3-cm-Puffer → orange gezählt. | grün | -| `TestFehlendKnickpunkteViaVerbindungslinien.test_ungematchter_pta_ausserhalb_puffer_kein_orange` | Nicht-gematchter PunktortTA außerhalb Puffer → nicht orange gezählt. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestExtrahiereKnickpunkte.test_leerer_layer_gibt_leere_liste` | — (Docstring fehlt) | grün | nie geprüft | +| `TestExtrahiereKnickpunkte.test_keine_gueltige_geometrie_gibt_leere_liste` | — (Docstring fehlt) | grün | nie geprüft | +| `TestExtrahiereKnickpunkte.test_feature_mit_leerer_geometrie_gibt_leere_liste` | — (Docstring fehlt) | grün | nie geprüft | +| `TestExtrahiereKnickpunkte.test_qgis_nicht_verfuegbar_gibt_leere_liste` | Wenn qgis.core kein QgsPointXY hat (ImportError in Funktion), leere Liste. | grün | nie geprüft | +| `TestKnickpunktPruefungInputvalidierung.test_keine_knickpunkte_gibt_none_zurueck` | — (Docstring fehlt) | grün | nie geprüft | +| `TestKnickpunktPruefungInputvalidierung.test_kein_punktort_layer_gibt_none_zurueck` | — (Docstring fehlt) | grün | nie geprüft | +| `TestKnickpunktPruefungInputvalidierung.test_abbruch_via_progress_gibt_none_zurueck` | — (Docstring fehlt) | grün | nie geprüft | +| `TestKnickpunktPruefungKlassifizierung.test_identischer_punkt_wird_gruen_gezaehlt` | PunktortTA exakt am Knickpunkt → identisch_count == 1. | grün | nie geprüft | +| `TestKnickpunktPruefungKlassifizierung.test_kein_pta_an_knickpunkt_wird_rot_gezaehlt` | Kein PunktortTA am Knickpunkt → kein_pta_count == 1. | grün | nie geprüft | +| `TestFehlendKnickpunkteViaVerbindungslinien.test_leere_union_gibt_null_zurueck` | bror_union.isEmpty() == True → (0, []). | grün | nie geprüft | +| `TestFehlendKnickpunkteViaVerbindungslinien.test_weniger_als_zwei_pta_auf_ring_kein_orange` | Nur 1 gematchter PunktortTA auf Ring → keine fehlenden Knickpunkte. | grün | nie geprüft | +| `TestFehlendKnickpunkteViaVerbindungslinien.test_ungematchter_pta_im_puffer_wird_orange` | Nicht-gematchter PunktortTA innerhalb 3-cm-Puffer → orange gezählt. | grün | nie geprüft | +| `TestFehlendKnickpunkteViaVerbindungslinien.test_ungematchter_pta_ausserhalb_puffer_kein_orange` | Nicht-gematchter PunktortTA außerhalb Puffer → nicht orange gezählt. | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_main.py` @@ -449,12 +452,12 @@ Testgruppen: - `TestPluginMain` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestPluginMain.test_init_sets_services_and_names` | — (Docstring fehlt) | grün | -| `TestPluginMain.test_initGui_registers_action_when_basis_ui_exists` | — (Docstring fehlt) | grün | -| `TestPluginMain.test_run_creates_dock_and_marks_toolbar_active` | — (Docstring fehlt) | grün | -| `TestPluginMain.test_unload_removes_dock_and_action` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestPluginMain.test_init_sets_services_and_names` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPluginMain.test_initGui_registers_action_when_basis_ui_exists` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPluginMain.test_run_creates_dock_and_marks_toolbar_active` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPluginMain.test_unload_removes_dock_and_action` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_verfahrensgebiet_alkis.py` @@ -464,16 +467,16 @@ Testgruppen: - `TestVerfahrensgebietAlkis` (8 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestVerfahrensgebietAlkis.test_check_existing_layer_first_load` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkis.test_check_existing_layer_keep_existing` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_fails_on_invalid_wfs_layer` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_success_single_kombination` | Einzelne (adv_name, bezeichnung)-Kombination → kein Dialog, Memory-Layer zurück. | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_dialog_auswahl` | Zwei verschiedene Kombinationen → Dialog wird gezeigt, gewählte Features genutzt. | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_dialog_abbruch` | Zwei verschiedene Kombinationen → Nutzer bricht Dialog ab → NONE. | grün | -| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_mehrfachauswahl` | Zwei verschiedene Kombinationen → beide ausgewählt → beide Feature-Gruppen genutzt. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestVerfahrensgebietAlkis.test_check_existing_layer_first_load` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_check_existing_layer_keep_existing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_fails_on_invalid_wfs_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_success_single_kombination` | Einzelne (adv_name, bezeichnung)-Kombination → kein Dialog, Memory-Layer zurück. | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_dialog_auswahl` | Zwei verschiedene Kombinationen → Dialog wird gezeigt, gewählte Features genutzt. | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_dialog_abbruch` | Zwei verschiedene Kombinationen → Nutzer bricht Dialog ab → NONE. | grün | nie geprüft | +| `TestVerfahrensgebietAlkis.test_verfahrensgebiet_alkis_multi_kombination_mehrfachauswahl` | Zwei verschiedene Kombinationen → beide ausgewählt → beide Feature-Gruppen genutzt. | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_verfahrensgebiet_alkis_komplett.py` @@ -486,38 +489,38 @@ Testgruppen: - `TestFlaechenvergleich` (8 Testfälle): — (Docstring fehlt) - `TestVerfahrensgebietAlkisKomplett` (16 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestSelectByLocation.test_processing_not_available_returns_zero` | — (Docstring fehlt) | grün | -| `TestSelectByLocation.test_processing_success_returns_count` | — (Docstring fehlt) | grün | -| `TestSelectByLocation.test_processing_exception_returns_zero` | — (Docstring fehlt) | grün | -| `TestFuegeVkzFeldHinzu.test_empty_vkz_does_nothing` | — (Docstring fehlt) | grün | -| `TestFuegeVkzFeldHinzu.test_none_vkz_does_nothing` | — (Docstring fehlt) | grün | -| `TestFuegeVkzFeldHinzu.test_vkz_field_added` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_gleiche_flaeche_stimmt_ueberein` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_verschiedene_flaeche_stimmt_nicht_ueberein` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_differenz_innerhalb_toleranz` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_differenz_ausserhalb_toleranz` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_flaechen_werte_korrekt` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_lese_toleranz_default_ist_null` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_lese_toleranz_parst_string` | — (Docstring fehlt) | grün | -| `TestFlaechenvergleich.test_lese_toleranz_ungueltig_fallback_null` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_vg_alkis_none_aborts` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_flst_none_aborts` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_no_selection_returns_none_enriched` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_invalid_enriched_layer_returns_none` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_progress_cancel_after_step1_returns_none` | Abbruch nach Schritt 1 → sofortiger sauberer Rückgabestatus. | grün | -| `TestVerfahrensgebietAlkisKomplett.test_success_flaechen_match_zeigt_info` | Flächenübereinstimmung → show_info_dialog mit erwartetem Text. | grün | -| `TestVerfahrensgebietAlkisKomplett.test_no_vkz_variable_passes_empty_string` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_abbrechen_kein_detailcheck` | Abweichung + Abbrechen → knickpunkt_pruefung wird NICHT aufgerufen. | grün | -| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_als_vg_laden` | Abweichung + Als VG laden → BROR-Layer wird umbenannt und als | grün | -| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_detailpruefung_startet_knickpruefung` | Abweichung + Detailprüfung → lade_punktort_ta + knickpunkt_pruefung | grün | -| `TestVerfahrensgebietAlkisKomplett.test_bror_layer_bleibt_bei_erfolg_im_projekt` | Bei Erfolg darf der BROR-Layer NICHT entfernt werden. | grün | -| `TestVerfahrensgebietAlkisKomplett.test_bror_layer_wird_bei_fehler_entfernt` | Bei Fehler (flst_alkis NONE) wird der BROR-Layer aus dem Projekt entfernt. | grün | -| `TestVerfahrensgebietAlkisKomplett.test_kein_vkz_kein_landkreis_dialog_abgebrochen` | Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer bricht den | grün | -| `TestVerfahrensgebietAlkisKomplett.test_kein_vkz_kein_landkreis_dialog_liefert_landkreis` | Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer wählt einen | grün | -| `TestVerfahrensgebietAlkisKomplett.test_landkreis_modus_wird_bei_fehlender_vkz_verwendet` | Keine Verfahrensnummer, aber Landkreis gesetzt → Landkreis-Suchpfad | grün | -| `TestVerfahrensgebietAlkisKomplett.test_landkreis_modus_nur_laden_ueberspringt_dialog2` | nur_laden=True → Funktion kehrt sofort zurück, Dialog 2 (Gemarkung | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestSelectByLocation.test_processing_not_available_returns_zero` | — (Docstring fehlt) | grün | nie geprüft | +| `TestSelectByLocation.test_processing_success_returns_count` | — (Docstring fehlt) | grün | nie geprüft | +| `TestSelectByLocation.test_processing_exception_returns_zero` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFuegeVkzFeldHinzu.test_empty_vkz_does_nothing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFuegeVkzFeldHinzu.test_none_vkz_does_nothing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFuegeVkzFeldHinzu.test_vkz_field_added` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_gleiche_flaeche_stimmt_ueberein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_verschiedene_flaeche_stimmt_nicht_ueberein` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_differenz_innerhalb_toleranz` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_differenz_ausserhalb_toleranz` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_flaechen_werte_korrekt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_lese_toleranz_default_ist_null` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_lese_toleranz_parst_string` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFlaechenvergleich.test_lese_toleranz_ungueltig_fallback_null` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_vg_alkis_none_aborts` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_flst_none_aborts` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_no_selection_returns_none_enriched` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_invalid_enriched_layer_returns_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_progress_cancel_after_step1_returns_none` | Abbruch nach Schritt 1 → sofortiger sauberer Rückgabestatus. | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_success_flaechen_match_zeigt_info` | Flächenübereinstimmung → show_info_dialog mit erwartetem Text. | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_no_vkz_variable_passes_empty_string` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_abbrechen_kein_detailcheck` | Abweichung + Abbrechen → knickpunkt_pruefung wird NICHT aufgerufen. | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_als_vg_laden` | Abweichung + Als VG laden → BROR-Layer wird umbenannt und als | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_flaechen_abweichung_detailpruefung_startet_knickpruefung` | Abweichung + Detailprüfung → lade_punktort_ta + knickpunkt_pruefung | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_bror_layer_bleibt_bei_erfolg_im_projekt` | Bei Erfolg darf der BROR-Layer NICHT entfernt werden. | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_bror_layer_wird_bei_fehler_entfernt` | Bei Fehler (flst_alkis NONE) wird der BROR-Layer aus dem Projekt entfernt. | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_kein_vkz_kein_landkreis_dialog_abgebrochen` | Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer bricht den | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_kein_vkz_kein_landkreis_dialog_liefert_landkreis` | Weder Verfahrensnummer noch Landkreis gesetzt, Nutzer wählt einen | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_landkreis_modus_wird_bei_fehlender_vkz_verwendet` | Keine Verfahrensnummer, aber Landkreis gesetzt → Landkreis-Suchpfad | grün | nie geprüft | +| `TestVerfahrensgebietAlkisKomplett.test_landkreis_modus_nur_laden_ueberspringt_dialog2` | nur_laden=True → Funktion kehrt sofort zurück, Dialog 2 (Gemarkung | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_verfahrensgebiet_edit_service.py` @@ -533,29 +536,29 @@ Testgruppen: - `TestEntferneAusVerfahrensgebiet` (5 Testfälle): — (Docstring fehlt) - `TestErsetze` (1 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestPruefeFlurstueckLayer.test_layer_ok_passes` | Gültiger Polygon-Vektor-Layer mit Pflichtfeldern → ok=True. | grün | -| `TestPruefeFlurstueckLayer.test_layer_missing_field_fails` | Layer ohne Pflichtfelder → ok=False, aktion=felder_fehlen. | grün | -| `TestPruefeFlurstueckLayer.test_layer_wrong_geometry_fails` | Layer mit falschem Geometrietyp → ok=False, aktion=falscher_geotyp. | grün | -| `TestPruefeAuswahl.test_no_selection_fails` | — (Docstring fehlt) | grün | -| `TestPruefeAuswahl.test_with_selection_passes` | — (Docstring fehlt) | grün | -| `TestPruefeAuswahl.test_selectedFeatureCount_exception_treated_as_zero` | — (Docstring fehlt) | grün | -| `TestGetKennzeichenMenge.test_returns_set_of_ids` | Kommagetrennte Kennzeichen im Single-Feature werden korrekt geparst. | grün | -| `TestGetKennzeichenMenge.test_empty_layer_returns_empty_set` | — (Docstring fehlt) | grün | -| `TestGetKennzeichenMenge.test_single_kennzeichen_without_comma` | Einzelnes Kennzeichen ohne Komma wird korrekt erkannt. | grün | -| `TestErstelle.test_success_counts` | 3 gültige Features → erfolgreich=3, fehlgeschlagen=0, 1 Union-Feature im Layer. | grün | -| `TestErstelle.test_partial_failure_on_empty_geometry` | 2 ok + 1 leere Geometrie → erfolgreich=2, fehlgeschlagen=1. | grün | -| `TestErstelle.test_all_fail_on_empty_geometries` | Alle Features haben leere Geometrie → erfolgreich=0, kein Feature im Layer. | grün | -| `TestErgaenzeVerfahrensgebiet.test_adds_only_new_ids` | Auswahl enthält 1 neue + 1 bereits vorhandene ID → hinzugefügt=1. | grün | -| `TestErgaenzeVerfahrensgebiet.test_skip_empty_geometry_counts_as_failed` | Neue ID mit leerer Geometrie → fehlgeschlagen=1, hinzugefügt=0. | grün | -| `TestErgaenzeVerfahrensgebiet.test_all_already_present` | Alle ausgewählten IDs bereits vorhanden → bereits_vorhanden=n, hinzugefügt=0. | grün | -| `TestEntferneAusVerfahrensgebiet.test_removes_present_ids` | Auswahl enthält 1 vorhandene ID → entfernt=1, nicht_enthalten=0. | grün | -| `TestEntferneAusVerfahrensgebiet.test_counts_ids_not_in_layer` | Auswahl enthält ID, die nicht im Verfahrensgebiet ist → nicht_enthalten=1. | grün | -| `TestEntferneAusVerfahrensgebiet.test_none_present_in_layer` | Auswahl hat IDs, die alle nicht im Layer sind → entfernt=0, nicht_enthalten=n. | grün | -| `TestEntferneAusVerfahrensgebiet.test_empty_selection_removes_nothing` | Leere Auswahl → nichts entfernt, nichts nicht_enthalten. | grün | -| `TestEntferneAusVerfahrensgebiet.test_removes_last_id_deletes_feature` | Wird das letzte Kennzeichen entfernt, wird das Feature gelöscht. | grün | -| `TestErsetze.test_ersetze_delegates_to_erstelle` | ersetze_verfahrensgebiet gibt dasselbe Ergebnis wie erstelle zurück. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestPruefeFlurstueckLayer.test_layer_ok_passes` | Gültiger Polygon-Vektor-Layer mit Pflichtfeldern → ok=True. | grün | nie geprüft | +| `TestPruefeFlurstueckLayer.test_layer_missing_field_fails` | Layer ohne Pflichtfelder → ok=False, aktion=felder_fehlen. | grün | nie geprüft | +| `TestPruefeFlurstueckLayer.test_layer_wrong_geometry_fails` | Layer mit falschem Geometrietyp → ok=False, aktion=falscher_geotyp. | grün | nie geprüft | +| `TestPruefeAuswahl.test_no_selection_fails` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefeAuswahl.test_with_selection_passes` | — (Docstring fehlt) | grün | nie geprüft | +| `TestPruefeAuswahl.test_selectedFeatureCount_exception_treated_as_zero` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetKennzeichenMenge.test_returns_set_of_ids` | Kommagetrennte Kennzeichen im Single-Feature werden korrekt geparst. | grün | nie geprüft | +| `TestGetKennzeichenMenge.test_empty_layer_returns_empty_set` | — (Docstring fehlt) | grün | nie geprüft | +| `TestGetKennzeichenMenge.test_single_kennzeichen_without_comma` | Einzelnes Kennzeichen ohne Komma wird korrekt erkannt. | grün | nie geprüft | +| `TestErstelle.test_success_counts` | 3 gültige Features → erfolgreich=3, fehlgeschlagen=0, 1 Union-Feature im Layer. | grün | nie geprüft | +| `TestErstelle.test_partial_failure_on_empty_geometry` | 2 ok + 1 leere Geometrie → erfolgreich=2, fehlgeschlagen=1. | grün | nie geprüft | +| `TestErstelle.test_all_fail_on_empty_geometries` | Alle Features haben leere Geometrie → erfolgreich=0, kein Feature im Layer. | grün | nie geprüft | +| `TestErgaenzeVerfahrensgebiet.test_adds_only_new_ids` | Auswahl enthält 1 neue + 1 bereits vorhandene ID → hinzugefügt=1. | grün | nie geprüft | +| `TestErgaenzeVerfahrensgebiet.test_skip_empty_geometry_counts_as_failed` | Neue ID mit leerer Geometrie → fehlgeschlagen=1, hinzugefügt=0. | grün | nie geprüft | +| `TestErgaenzeVerfahrensgebiet.test_all_already_present` | Alle ausgewählten IDs bereits vorhanden → bereits_vorhanden=n, hinzugefügt=0. | grün | nie geprüft | +| `TestEntferneAusVerfahrensgebiet.test_removes_present_ids` | Auswahl enthält 1 vorhandene ID → entfernt=1, nicht_enthalten=0. | grün | nie geprüft | +| `TestEntferneAusVerfahrensgebiet.test_counts_ids_not_in_layer` | Auswahl enthält ID, die nicht im Verfahrensgebiet ist → nicht_enthalten=1. | grün | nie geprüft | +| `TestEntferneAusVerfahrensgebiet.test_none_present_in_layer` | Auswahl hat IDs, die alle nicht im Layer sind → entfernt=0, nicht_enthalten=n. | grün | nie geprüft | +| `TestEntferneAusVerfahrensgebiet.test_empty_selection_removes_nothing` | Leere Auswahl → nichts entfernt, nichts nicht_enthalten. | grün | nie geprüft | +| `TestEntferneAusVerfahrensgebiet.test_removes_last_id_deletes_feature` | Wird das letzte Kennzeichen entfernt, wird das Feature gelöscht. | grün | nie geprüft | +| `TestErsetze.test_ersetze_delegates_to_erstelle` | ersetze_verfahrensgebiet gibt dasselbe Ergebnis wie erstelle zurück. | grün | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_verfahrensgebiet_shape_komplett.py` @@ -568,39 +571,39 @@ Testgruppen: - `TestLadeVgAusZip` (6 Testfälle): — (Docstring fehlt) - `TestVerfahrensgebietShapeKomplett` (18 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestFindShp.test_findet_shp_in_root` | — (Docstring fehlt) | grün | -| `TestFindShp.test_findet_shp_in_unterordner` | — (Docstring fehlt) | grün | -| `TestFindShp.test_kein_shp_gibt_none_zurueck` | — (Docstring fehlt) | grün | -| `TestFindShp.test_case_insensitive_erkennung` | — (Docstring fehlt) | grün | -| `TestErstelleMemoryLayerAusShp.test_leere_geometrien_geben_none` | — (Docstring fehlt) | grün | -| `TestErstelleMemoryLayerAusShp.test_keine_features_gibt_none` | — (Docstring fehlt) | grün | -| `TestErstelleMemoryLayerAusShp.test_attribute_von_erstem_feature_werden_gesetzt` | Attributwerte des ersten Features werden auf das Union-Feature übertragen. | grün | -| `TestLadeVgAusZip.test_dialog_abgebrochen_gibt_none_zurueck` | — (Docstring fehlt) | rot (Baseline) | -| `TestLadeVgAusZip.test_zip_fehler_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | -| `TestLadeVgAusZip.test_kein_shp_in_zip_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | -| `TestLadeVgAusZip.test_invalider_qgslayer_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | -| `TestLadeVgAusZip.test_leere_geometrien_geben_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | -| `TestLadeVgAusZip.test_erfolg_gibt_memory_layer_zurueck` | — (Docstring fehlt) | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_lade_zip_none_aborts` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietShapeKomplett.test_shape_vg_sofort_ins_projekt_nach_laden` | Shape-VG wird unmittelbar nach dem Laden ins Projekt eingefügt. | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_shape_vg_wird_bei_abbruch_aus_projekt_entfernt` | Shape-VG wird bei Fehler/Abbruch aus dem Projekt entfernt. | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_shape_vg_bleibt_im_projekt_bei_erfolg` | Bei erfolgreichem Abschluss wird shape_vg NICHT aus dem Projekt entfernt. | grün | -| `TestVerfahrensgebietShapeKomplett.test_flst_none_aborts` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietShapeKomplett.test_keine_flurstuecke_selektiert_gibt_warning` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietShapeKomplett.test_flaechen_uebereinstimmung_gibt_info_und_kein_dialog` | — (Docstring fehlt) | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_abweichung_abbrechen_gibt_shape_vg_zurueck` | — (Docstring fehlt) | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_abweichung_detailpruefung_ruft_knickpunkt_pruefung_auf` | — (Docstring fehlt) | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_punktort_ta_none_gibt_shape_vg_zurueck_und_zeigt_fehler` | — (Docstring fehlt) | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_temp_layer_wird_stets_entfernt` | — (Docstring fehlt) | grün | -| `TestVerfahrensgebietShapeKomplett.test_bror_layer_ist_stets_none` | Dritter Rückgabewert ist im Shape-Workflow immer None (kein BROR). | grün | -| `TestVerfahrensgebietShapeKomplett.test_bror_geladen_und_zurueckgegeben_wenn_vkz_gesetzt` | VKZ gesetzt → verfahrensgebiet_alkis aufgerufen, bror_layer zurückgegeben. | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_bror_wird_vor_shape_vg_ins_projekt_eingefuegt` | BROR wird VOR shape_vg ins Projekt eingefügt (kein Namenskonflikt). | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_bror_wird_bei_abbruch_aus_projekt_entfernt` | BROR und shape_vg werden bei Fehler aus dem Projekt entfernt. | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_verfahrensgebiet_alkis_nicht_aufgerufen_wenn_vkz_leer` | Leere VKZ → verfahrensgebiet_alkis wird NICHT aufgerufen. | grün | -| `TestVerfahrensgebietShapeKomplett.test_bror_als_erstes_argument_beim_flaechenvergleich` | Mit BROR: _vergleiche_flaechen wird (bror, shape_vg, ...) aufgerufen. | rot (Baseline) | -| `TestVerfahrensgebietShapeKomplett.test_fallback_auf_temp_enriched_wenn_bror_ladeversagen` | BROR-Ladeversagen → Fallback: _vergleiche_flaechen mit shape_vg vs temp_enriched. | rot (Baseline) | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestFindShp.test_findet_shp_in_root` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFindShp.test_findet_shp_in_unterordner` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFindShp.test_kein_shp_gibt_none_zurueck` | — (Docstring fehlt) | grün | nie geprüft | +| `TestFindShp.test_case_insensitive_erkennung` | — (Docstring fehlt) | grün | nie geprüft | +| `TestErstelleMemoryLayerAusShp.test_leere_geometrien_geben_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestErstelleMemoryLayerAusShp.test_keine_features_gibt_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestErstelleMemoryLayerAusShp.test_attribute_von_erstem_feature_werden_gesetzt` | Attributwerte des ersten Features werden auf das Union-Feature übertragen. | grün | nie geprüft | +| `TestLadeVgAusZip.test_dialog_abgebrochen_gibt_none_zurueck` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestLadeVgAusZip.test_zip_fehler_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestLadeVgAusZip.test_kein_shp_in_zip_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestLadeVgAusZip.test_invalider_qgslayer_gibt_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestLadeVgAusZip.test_leere_geometrien_geben_none_und_warning` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestLadeVgAusZip.test_erfolg_gibt_memory_layer_zurueck` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_lade_zip_none_aborts` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_shape_vg_sofort_ins_projekt_nach_laden` | Shape-VG wird unmittelbar nach dem Laden ins Projekt eingefügt. | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_shape_vg_wird_bei_abbruch_aus_projekt_entfernt` | Shape-VG wird bei Fehler/Abbruch aus dem Projekt entfernt. | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_shape_vg_bleibt_im_projekt_bei_erfolg` | Bei erfolgreichem Abschluss wird shape_vg NICHT aus dem Projekt entfernt. | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_flst_none_aborts` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_keine_flurstuecke_selektiert_gibt_warning` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_flaechen_uebereinstimmung_gibt_info_und_kein_dialog` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_abweichung_abbrechen_gibt_shape_vg_zurueck` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_abweichung_detailpruefung_ruft_knickpunkt_pruefung_auf` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_punktort_ta_none_gibt_shape_vg_zurueck_und_zeigt_fehler` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_temp_layer_wird_stets_entfernt` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_bror_layer_ist_stets_none` | Dritter Rückgabewert ist im Shape-Workflow immer None (kein BROR). | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_bror_geladen_und_zurueckgegeben_wenn_vkz_gesetzt` | VKZ gesetzt → verfahrensgebiet_alkis aufgerufen, bror_layer zurückgegeben. | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_bror_wird_vor_shape_vg_ins_projekt_eingefuegt` | BROR wird VOR shape_vg ins Projekt eingefügt (kein Namenskonflikt). | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_bror_wird_bei_abbruch_aus_projekt_entfernt` | BROR und shape_vg werden bei Fehler aus dem Projekt entfernt. | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_verfahrensgebiet_alkis_nicht_aufgerufen_wenn_vkz_leer` | Leere VKZ → verfahrensgebiet_alkis wird NICHT aufgerufen. | grün | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_bror_als_erstes_argument_beim_flaechenvergleich` | Mit BROR: _vergleiche_flaechen wird (bror, shape_vg, ...) aufgerufen. | rot (Baseline) | nie geprüft | +| `TestVerfahrensgebietShapeKomplett.test_fallback_auf_temp_enriched_wenn_bror_ladeversagen` | BROR-Ladeversagen → Fallback: _vergleiche_flaechen mit shape_vg vs temp_enriched. | rot (Baseline) | nie geprüft | ### `Plugin_SN_Verfahrensgebiet/tests/test_working_tab.py` @@ -611,41 +614,41 @@ Testgruppen: - `TestWorkingTab` (24 Testfälle): — (Docstring fehlt) - `TestHandleVerfShape` (9 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestWorkingTab.test_set_busy_updates_button_state` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_on_verf_layer_changed_valid_sets_variable` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_on_verf_layer_changed_none_clears_variable` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_handle_verf_alkis_success_path` | verfahrensgebiet_alkis_komplett → 4-Tupel (enriched, flst, bror, FIRST). | rot (Baseline) | -| `TestWorkingTab.test_handle_verf_alkis_failure_clears_layer_var` | Status NONE → Layer-Variable wird auf '' gesetzt. | grün | -| `TestWorkingTab.test_handle_flurst_alkis_first_load_uebernimmt_layer` | Erstmaliges Laden über 'Flurstücke laden' fügt den Layer dem Projekt hinzu. | grün | -| `TestWorkingTab.test_handle_flurst_aus_gemarkungen_ruft_flurstueck_alkis_ohne_schluessel_abfrage` | Der Gemarkungen-Auswahl-Button ruft dieselbe Ladefunktion mit ohne_schluessel_abfrage=True auf (#47). | grün | -| `TestWorkingTab.test_handle_flurst_aus_gemarkungen_abbruch_zeigt_keine_zusaetzliche_meldung` | Bricht flurstueck_alkis() ab (None, NONE), zeigt der Button keine eigene Meldung – flurstueck_alkis() hat das schon getan (#47). | grün | -| `TestWorkingTab.test_handle_grenz_alkis_success_sets_haken` | Grenzpunkte erfolgreich geladen → haken_grenz wird gesetzt. | rot (Baseline) | -| `TestWorkingTab.test_handle_grenz_alkis_none_result_sets_no_haken` | grenzpunkt_alkis liefert (None, None) → kein Haken. | rot (Baseline) | -| `TestWorkingTab.test_handle_flurst_alkis_success_sets_haken_and_style` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_handle_flurst_alkis_existing_layer_keep_path` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_handle_flurst_alkis_invalid_input_returns_early` | Status NONE (z. B. Nutzerabbruch) → kein Layer, kein Haken. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_active_layer` | Kein aktiver Layer → warning, kein Layer wird erstellt. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_required_fields` | Layer ohne Pflichtfelder → warning, kein Layer wird erstellt. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_selection` | Keine Flurstück-Auswahl → warning, kein Layer erstellt. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_new_layer_success` | Erstlauf ohne bestehenden Layer → Layer wird erstellt und hinzugefügt. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_ergaenzen_dispatch` | Entscheidung 'ergaenzen' → ergaenze_verfahrensgebiet wird aufgerufen. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_entfernen_dispatch` | Entscheidung 'entfernen' → entferne_aus_verfahrensgebiet wird aufgerufen. | grün | -| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_ersetzen_dispatch` | Entscheidung 'ersetzen' → alter Layer entfernt, neuer hinzugefügt. | grün | -| `TestWorkingTab.test_aus_liste_button_shows_not_implemented_hint` | — (Docstring fehlt) | grün | -| `TestWorkingTab.test_handle_gem_alkis_service_reachable_adds_layer` | Dienst erreichbar → Layer ins Projekt, Stil angewendet, Haken gesetzt. | grün | -| `TestWorkingTab.test_handle_gem_alkis_service_unreachable_shows_warning` | Dienst nicht erreichbar (None) → warning, kein addMapLayer. | grün | -| `TestWorkingTab.test_handle_gem_alkis_layer_already_exists_shows_info` | Layer 'Gemarkungen' bereits vorhanden → info, kein erneutes Laden. | grün | -| `TestHandleVerfShape.test_status_none_clears_layer_variable` | Status NONE → Layer-Variable wird auf '' gesetzt. | grün | -| `TestHandleVerfShape.test_button_always_re_enabled_on_failure` | Button muss nach Status NONE wieder freigegeben sein (finally). | grün | -| `TestHandleVerfShape.test_verfahrensnummer_nicht_gesetzt_nein_bricht_ab` | Verfahrensnummer leer + Nutzer wählt 'Nein' → Vorgang abgebrochen. | rot (Baseline) | -| `TestHandleVerfShape.test_verfahrensnummer_nicht_gesetzt_ja_fuehrt_fort` | Verfahrensnummer leer + Nutzer wählt 'Ja' → Pipeline wird aufgerufen. | rot (Baseline) | -| `TestHandleVerfShape.test_verfahrensnummer_gesetzt_kein_rueckfrage_dialog` | Verfahrensnummer gesetzt → kein ask_yes_no-Dialog. | grün | -| `TestHandleVerfShape.test_success_path_applies_style_and_sets_haken` | Erfolg → verfahrensgebiet.qml angewendet, haken_verf gesetzt, success aufgerufen. | grün | -| `TestHandleVerfShape.test_bror_layer_erhaelt_qml_stil` | Wenn bror_layer zurückgegeben → BauRaumOderBodenordnungsrecht.qml angewendet. | grün | -| `TestHandleVerfShape.test_enriched_layer_already_in_project_not_added_again` | Layer bereits im Projekt → kein erneutes addMapLayer für VG-Layer. | grün | -| `TestHandleVerfShape.test_busy_state_set_during_execution` | Button wird während der Ausführung auf busy gesetzt. | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestWorkingTab.test_set_busy_updates_button_state` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_on_verf_layer_changed_valid_sets_variable` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_on_verf_layer_changed_none_clears_variable` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_handle_verf_alkis_success_path` | verfahrensgebiet_alkis_komplett → 4-Tupel (enriched, flst, bror, FIRST). | rot (Baseline) | nie geprüft | +| `TestWorkingTab.test_handle_verf_alkis_failure_clears_layer_var` | Status NONE → Layer-Variable wird auf '' gesetzt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_flurst_alkis_first_load_uebernimmt_layer` | Erstmaliges Laden über 'Flurstücke laden' fügt den Layer dem Projekt hinzu. | grün | nie geprüft | +| `TestWorkingTab.test_handle_flurst_aus_gemarkungen_ruft_flurstueck_alkis_ohne_schluessel_abfrage` | Der Gemarkungen-Auswahl-Button ruft dieselbe Ladefunktion mit ohne_schluessel_abfrage=True auf (#47). | grün | nie geprüft | +| `TestWorkingTab.test_handle_flurst_aus_gemarkungen_abbruch_zeigt_keine_zusaetzliche_meldung` | Bricht flurstueck_alkis() ab (None, NONE), zeigt der Button keine eigene Meldung – flurstueck_alkis() hat das schon getan (#47). | grün | nie geprüft | +| `TestWorkingTab.test_handle_grenz_alkis_success_sets_haken` | Grenzpunkte erfolgreich geladen → haken_grenz wird gesetzt. | rot (Baseline) | nie geprüft | +| `TestWorkingTab.test_handle_grenz_alkis_none_result_sets_no_haken` | grenzpunkt_alkis liefert (None, None) → kein Haken. | rot (Baseline) | nie geprüft | +| `TestWorkingTab.test_handle_flurst_alkis_success_sets_haken_and_style` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_handle_flurst_alkis_existing_layer_keep_path` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_handle_flurst_alkis_invalid_input_returns_early` | Status NONE (z. B. Nutzerabbruch) → kein Layer, kein Haken. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_active_layer` | Kein aktiver Layer → warning, kein Layer wird erstellt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_required_fields` | Layer ohne Pflichtfelder → warning, kein Layer wird erstellt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_requires_selection` | Keine Flurstück-Auswahl → warning, kein Layer erstellt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_new_layer_success` | Erstlauf ohne bestehenden Layer → Layer wird erstellt und hinzugefügt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_ergaenzen_dispatch` | Entscheidung 'ergaenzen' → ergaenze_verfahrensgebiet wird aufgerufen. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_entfernen_dispatch` | Entscheidung 'entfernen' → entferne_aus_verfahrensgebiet wird aufgerufen. | grün | nie geprüft | +| `TestWorkingTab.test_handle_verfahrensgebiet_from_selection_existing_layer_ersetzen_dispatch` | Entscheidung 'ersetzen' → alter Layer entfernt, neuer hinzugefügt. | grün | nie geprüft | +| `TestWorkingTab.test_aus_liste_button_shows_not_implemented_hint` | — (Docstring fehlt) | grün | nie geprüft | +| `TestWorkingTab.test_handle_gem_alkis_service_reachable_adds_layer` | Dienst erreichbar → Layer ins Projekt, Stil angewendet, Haken gesetzt. | grün | nie geprüft | +| `TestWorkingTab.test_handle_gem_alkis_service_unreachable_shows_warning` | Dienst nicht erreichbar (None) → warning, kein addMapLayer. | grün | nie geprüft | +| `TestWorkingTab.test_handle_gem_alkis_layer_already_exists_shows_info` | Layer 'Gemarkungen' bereits vorhanden → info, kein erneutes Laden. | grün | nie geprüft | +| `TestHandleVerfShape.test_status_none_clears_layer_variable` | Status NONE → Layer-Variable wird auf '' gesetzt. | grün | nie geprüft | +| `TestHandleVerfShape.test_button_always_re_enabled_on_failure` | Button muss nach Status NONE wieder freigegeben sein (finally). | grün | nie geprüft | +| `TestHandleVerfShape.test_verfahrensnummer_nicht_gesetzt_nein_bricht_ab` | Verfahrensnummer leer + Nutzer wählt 'Nein' → Vorgang abgebrochen. | rot (Baseline) | nie geprüft | +| `TestHandleVerfShape.test_verfahrensnummer_nicht_gesetzt_ja_fuehrt_fort` | Verfahrensnummer leer + Nutzer wählt 'Ja' → Pipeline wird aufgerufen. | rot (Baseline) | nie geprüft | +| `TestHandleVerfShape.test_verfahrensnummer_gesetzt_kein_rueckfrage_dialog` | Verfahrensnummer gesetzt → kein ask_yes_no-Dialog. | grün | nie geprüft | +| `TestHandleVerfShape.test_success_path_applies_style_and_sets_haken` | Erfolg → verfahrensgebiet.qml angewendet, haken_verf gesetzt, success aufgerufen. | grün | nie geprüft | +| `TestHandleVerfShape.test_bror_layer_erhaelt_qml_stil` | Wenn bror_layer zurückgegeben → BauRaumOderBodenordnungsrecht.qml angewendet. | grün | nie geprüft | +| `TestHandleVerfShape.test_enriched_layer_already_in_project_not_added_again` | Layer bereits im Projekt → kein erneutes addMapLayer für VG-Layer. | grün | nie geprüft | +| `TestHandleVerfShape.test_busy_state_set_during_execution` | Button wird während der Ausführung auf busy gesetzt. | grün | nie geprüft | ## Paket `sn_plan41` @@ -659,12 +662,12 @@ Testgruppen: - `TestListenauswerter` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestListenauswerter.test_validate_rows_accepts_valid_row_and_normalizes_provider` | — (Docstring fehlt) | grün | -| `TestListenauswerter.test_validate_rows_rejects_missing_required_fields` | — (Docstring fehlt) | grün | -| `TestListenauswerter.test_validate_rows_sets_stildatei_none_on_style_failure` | — (Docstring fehlt) | grün | -| `TestListenauswerter.test_validate_rows_handles_non_mapping_rows_edge_case` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestListenauswerter.test_validate_rows_accepts_valid_row_and_normalizes_provider` | — (Docstring fehlt) | grün | nie geprüft | +| `TestListenauswerter.test_validate_rows_rejects_missing_required_fields` | — (Docstring fehlt) | grün | nie geprüft | +| `TestListenauswerter.test_validate_rows_sets_stildatei_none_on_style_failure` | — (Docstring fehlt) | grün | nie geprüft | +| `TestListenauswerter.test_validate_rows_handles_non_mapping_rows_edge_case` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Plan41/tests/test_tab_a_logic.py` @@ -674,17 +677,17 @@ Testgruppen: - `TestTabALogic` (9 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestTabALogic.test_verfahrens_db_set_and_load_roundtrip` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_verfahrens_db_clear` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_linkliste_set_and_load_existing_path` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_linkliste_load_returns_none_when_file_missing` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_resolve_linkliste_empty_uses_standard_and_persists` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_resolve_linkliste_returns_none_when_pruefmanager_rejects` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_resolve_raumfilter_without_filter_returns_none` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_resolve_raumfilter_verfahrensgebiet_uses_layer_lookup` | — (Docstring fehlt) | grün | -| `TestTabALogic.test_extract_datenabruf_error_maps_merges_reason_maps` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestTabALogic.test_verfahrens_db_set_and_load_roundtrip` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_verfahrens_db_clear` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_linkliste_set_and_load_existing_path` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_linkliste_load_returns_none_when_file_missing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_resolve_linkliste_empty_uses_standard_and_persists` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_resolve_linkliste_returns_none_when_pruefmanager_rejects` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_resolve_raumfilter_without_filter_returns_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_resolve_raumfilter_verfahrensgebiet_uses_layer_lookup` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabALogic.test_extract_datenabruf_error_maps_merges_reason_maps` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Plan41/tests/test_tab_a_preconditions.py` @@ -694,11 +697,11 @@ Testgruppen: - `TestTabAPreconditions` (3 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestTabAPreconditions.test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing` | — (Docstring fehlt) | grün | -| `TestTabAPreconditions.test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project` | — (Docstring fehlt) | grün | -| `TestTabAPreconditions.test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestTabAPreconditions.test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabAPreconditions.test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabAPreconditions.test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing` | — (Docstring fehlt) | grün | nie geprüft | ### `Plugin_SN_Plan41/tests/test_tab_a_ui.py` @@ -708,11 +711,11 @@ Testgruppen: - `TestTabAUI` (3 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestTabAUI.test_tab_a_callbacks_can_be_called_without_crash` | — (Docstring fehlt) | grün | -| `TestTabAUI.test_tab_a_raumfilter_callback_persists_value` | — (Docstring fehlt) | grün | -| `TestTabAUI.test_set_services_initializes_logic_and_injects_data_grabber` | — (Docstring fehlt) | rot (Baseline) | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestTabAUI.test_tab_a_callbacks_can_be_called_without_crash` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabAUI.test_tab_a_raumfilter_callback_persists_value` | — (Docstring fehlt) | grün | nie geprüft | +| `TestTabAUI.test_set_services_initializes_logic_and_injects_data_grabber` | — (Docstring fehlt) | rot (Baseline) | nie geprüft | ### `Plugin_SN_Plan41/tests/test_vln_api_logic.py` @@ -728,33 +731,33 @@ Testgruppen: - `TestVlnApiLogicLoadP41` (3 Testfälle): — (Docstring fehlt) - `TestVlnApiLogicUpload` (4 Testfälle): — (Docstring fehlt) -| Testfall | prüft | Status | -| --- | --- | --- | -| `TestVlnApiLogicAvailability.test_is_available_reflects_import_state` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicAvailability.test_is_available_false_when_vln_karten_missing` | Wenn VLN_KARTEN_AVAILABLE=False, liefert is_available() False. | grün | -| `TestVlnApiLogicCredentials.test_save_api_key_calls_qsettings` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicCredentials.test_clear_api_key_calls_remove` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicCredentials.test_load_stored_credentials_returns_api_key_and_mail` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicCredentials.test_load_stored_credentials_returns_none_for_empty` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_login_sets_client_and_saves_key` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_login_raises_runtime_error_without_qgis_modules` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_login_propagates_api_error` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_logout_clears_client` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_is_authenticated_false_after_logout` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLogin.test_handle_session_expired_clears_key_and_client` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVerfahren.test_get_verfahren_raises_when_not_authenticated` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVerfahren.test_get_verfahren_delegates_to_client` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVkz.test_load_stored_vkz_reads_from_project` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVkz.test_load_stored_vkz_returns_none_for_empty` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVkz.test_save_vkz_writes_to_project` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicVkz.test_save_vkz_does_nothing_for_none` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLoadP41.test_load_p41_raises_without_vln_karten` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLoadP41.test_load_p41_applies_styles_to_polygon_and_line_layers` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicLoadP41.test_load_p41_no_style_for_point_layer` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicUpload.test_upload_returns_error_for_layer_without_api_path` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicUpload.test_upload_returns_error_for_none_layer` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicUpload.test_upload_returns_false_without_qgis_modules` | — (Docstring fehlt) | grün | -| `TestVlnApiLogicUpload.test_upload_calls_save_feature_collection` | — (Docstring fehlt) | grün | +| Testfall | prüft | Status | geprüft | +| --- | --- | --- | --- | +| `TestVlnApiLogicAvailability.test_is_available_reflects_import_state` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicAvailability.test_is_available_false_when_vln_karten_missing` | Wenn VLN_KARTEN_AVAILABLE=False, liefert is_available() False. | grün | nie geprüft | +| `TestVlnApiLogicCredentials.test_save_api_key_calls_qsettings` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicCredentials.test_clear_api_key_calls_remove` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicCredentials.test_load_stored_credentials_returns_api_key_and_mail` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicCredentials.test_load_stored_credentials_returns_none_for_empty` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_login_sets_client_and_saves_key` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_login_raises_runtime_error_without_qgis_modules` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_login_propagates_api_error` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_logout_clears_client` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_is_authenticated_false_after_logout` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLogin.test_handle_session_expired_clears_key_and_client` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVerfahren.test_get_verfahren_raises_when_not_authenticated` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVerfahren.test_get_verfahren_delegates_to_client` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVkz.test_load_stored_vkz_reads_from_project` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVkz.test_load_stored_vkz_returns_none_for_empty` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVkz.test_save_vkz_writes_to_project` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicVkz.test_save_vkz_does_nothing_for_none` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLoadP41.test_load_p41_raises_without_vln_karten` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLoadP41.test_load_p41_applies_styles_to_polygon_and_line_layers` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicLoadP41.test_load_p41_no_style_for_point_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicUpload.test_upload_returns_error_for_layer_without_api_path` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicUpload.test_upload_returns_error_for_none_layer` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicUpload.test_upload_returns_false_without_qgis_modules` | — (Docstring fehlt) | grün | nie geprüft | +| `TestVlnApiLogicUpload.test_upload_calls_save_feature_collection` | — (Docstring fehlt) | grün | nie geprüft | ## Lücken diff --git a/docs/wissen/fallstricke.md b/docs/wissen/fallstricke.md index fa5e6db..aced3d6 100644 --- a/docs/wissen/fallstricke.md +++ b/docs/wissen/fallstricke.md @@ -15,6 +15,21 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik Internetverbindung beim Öffnen bleiben die Baumdiagramme leer, Text/Tabellen/Filter funktionieren trotzdem (kein Server nötig, einfach lokal im Browser öffnen). Erzeugt zusammen mit `testkatalog.md` durch `python scripts/testkatalog.py`; beide Dateien müssen zueinander passen (`--pruefen` prüft beide). (09/2026) +- **Test-Audit (`scripts/test_audit.py`, `docs/status/testpruefungen.json`) reagiert auf jede inhaltliche + Änderung am Testkörper, aber nicht auf reines Trailing Whitespace.** Der Hash je Testfall wird über den + `rstrip()`-normalisierten Quelltext gebildet. Eine größere Reformatierung (Docstring-Text, Einrückung, + Assertions) macht bestehende Prüfungen also bewusst „veraltet" – das ist gewollt, sollte aber vor einer + größeren Reformatierungs-PR angekündigt werden, damit niemand über plötzlich viele „veraltet"-Einträge + stolpert. (09/2026, Ticket #16) +- **`scripts/test_audit.py` importiert `scripts/testkatalog.py` als Modul** (`import testkatalog`). Das + funktioniert nur, wenn es als `python scripts/test_audit.py …` aufgerufen wird – Python setzt dabei + automatisch das Verzeichnis des Skripts als ersten Sucheintrag. Ein Aufruf aus einem anderen Arbeitsverzeichnis + über einen vollen Pfad funktioniert genauso; ein Import von `test_audit` als Paket ohne diesen Mechanismus + (z. B. `python -c "import test_audit"` von anderswo) schlägt fehl. (09/2026) +- **`docs/status/testpruefungen.json` wird nur von `scripts/test_audit.py markieren` geschrieben.** + `scripts/testkatalog.py` liest sie ausschließlich (wie bei `testbaseline.json`); die Datei fehlt zunächst und + entsteht erst mit dem ersten `markieren`-Aufruf – der Prüfstand zeigt bis dahin alle Testfälle als „nie + geprüft". (09/2026) - **`.vscode/` gehört nicht ins Repository.** Im Projektwissen wurde er am 04.09.2026 entfernt; brauchbare Einstellungen stehen jetzt in `docs/leitfaden/04_werkzeuge_einrichten.md` Abschnitt 4.2 zum Kopieren in die Benutzereinstellungen. In `Plugin_SN_Basis`, `Plugin_SN_Plan41`, `Plugin_SN_Verfahrensgebiet` und `Plugin_SN_Widmung` liegt er noch und enthält Pfade eines einzelnen Arbeitsplatzes (OSGeo-Installationspfad, persönliches Benutzerprofil) – nicht als Vorgabe verstehen. (09/2026) ## QGIS-Tests (geplant, siehe `docs/konzept/07_qgis_tests_plan.md`) diff --git a/scripts/test_audit.py b/scripts/test_audit.py new file mode 100644 index 0000000..10b96c9 --- /dev/null +++ b/scripts/test_audit.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +"""Test-Audit: zeigt und pflegt, wann ein Testfall zuletzt fachlich geprüft wurde. + +Der Testkatalog (scripts/testkatalog.py) beantwortet "was prüft die Suite" und "läuft der Test +durch" (Baseline). Er beantwortet NICHT "hat das ein Mensch fachlich bestätigt" – ein Agent kann +einen überzeugenden, aber fachlich falschen Test schreiben, und weder Docstring noch Baseline +zeigen das. Dieses Skript schließt genau diese Lücke: es liest/schreibt +docs/status/testpruefungen.json (Datum + Kurzprüfsumme der Testfunktion je Testfall) und macht so +sichtbar, welche Tests nie geprüft wurden oder sich seit der letzten Prüfung geändert haben. + +Reine Standardbibliothek, kein Import von sn_basis/QGIS nötig, da nur mit ast geparst wird +(genau wie testkatalog.py, dessen Funktionen hier wiederverwendet werden). + +Aufrufe (aus dem Workspace-Root): + python scripts/test_audit.py status # alle Pakete + python scripts/test_audit.py status sn_verfahrensgebiet # nur ein Paket + python scripts/test_audit.py status sn_basis --nur ungeprueft # Filter auf Prüfstatus + python scripts/test_audit.py status --muster grenzpunkt # Filter auf Bezeichner + python scripts/test_audit.py markieren sn_basis TestHallo.test_x # als heute geprüft markieren + python scripts/test_audit.py markieren sn_basis "TestX.*" --trocken # nur anzeigen, nichts schreiben + python scripts/test_audit.py markieren sn_basis TestX.test_x --datum 2026-08-01 # Nacherfassung + +Exit-Code: 0 = in Ordnung, 1 = kein Treffer beim Markieren, 2 = falsche Angabe (unbekanntes Paket, +ungültiges Datum). +""" + +from __future__ import annotations + +import argparse +import datetime +import fnmatch +import json +import sys +from pathlib import Path + +import testkatalog as tk + +ROOT = tk.ROOT + + +def lade_pakete(manifest: dict) -> dict[str, dict]: + return {r["paket"]: r for r in manifest["repos"] if r.get("paket")} + + +def waehle_pakete(gewuenscht: list[str], repos: dict[str, dict]) -> list[str] | None: + """Löst die gewünschten Paketnamen auf; leer bedeutet alle mit tests=true. None bei unbekanntem Namen.""" + testbare = [p for p, r in repos.items() if r.get("tests")] + ziel = gewuenscht or testbare + unbekannt = [p for p in ziel if p not in repos] + if unbekannt: + print(f"Unbekannte Pakete: {unbekannt}. Bekannt: {sorted(repos)}") + return None + return ziel + + +def sammle(paket: str, repos: dict[str, dict]) -> tk.Paketkatalog | None: + repo = repos[paket] + if not repo.get("tests"): + print(f"[{paket}] laut workspace.toml ohne Tests – übersprungen") + return None + katalog = tk.sammle_paket(paket, repo) + if katalog is None: + print(f"[{paket}] kein Ordner {repo['name']}/tests – übersprungen") + return katalog + + +NUR_ZU_PRUEFSTATUS = { + "ungeprueft": "nie geprüft", + "veraltet": "veraltet", + "aktuell": "aktuell geprüft", +} + + +def befehl_status(args: argparse.Namespace) -> int: + manifest = tk.lade_manifest() + repos = lade_pakete(manifest) + pakete = waehle_pakete(args.pakete, repos) + if pakete is None: + return 2 + + rot_je_paket, _ = tk.lies_baseline(args.baseline_datei) + pruefungen, _ = tk.lies_pruefungen(args.pruefungsdatei) + gesucht_status = NUR_ZU_PRUEFSTATUS.get(args.nur) if args.nur else None + + for paket in pakete: + katalog = sammle(paket, repos) + if katalog is None: + continue + tk.setze_status(katalog, rot_je_paket.get(paket, set())) + tk.setze_pruefstatus(katalog, pruefungen) + k = tk.zaehle(katalog.faelle) + print( + f"[{paket}] {k['gesamt']} Testfälle – {k['aktuell_geprueft']} aktuell geprüft, " + f"{k['veraltet_geprueft']} veraltet, {k['nie_geprueft']} nie geprüft" + ) + for datei in katalog.dateien: + for fall in datei.faelle: + if args.muster and args.muster.lower() not in fall.bezeichnung.lower(): + continue + if gesucht_status and fall.pruefstatus != gesucht_status: + continue + print(f" {datei.anzeigepfad}::{fall.bezeichnung} -> {tk.pruef_text(fall)}") + return 0 + + +def schreibe_pruefungen(pfad: Path, pruefungen: dict) -> None: + """Schreibt die Prüf-Historie deterministisch (sortierte Schlüssel, feste Formatierung).""" + pfad.parent.mkdir(parents=True, exist_ok=True) + pfad.write_text( + json.dumps(pruefungen, indent=2, ensure_ascii=False, sort_keys=True) + "\n", + encoding="utf-8", + newline="\n", + ) + + +def befehl_markieren(args: argparse.Namespace) -> int: + try: + datum = datetime.date.fromisoformat(args.datum).isoformat() + except ValueError: + print(f"Ungültiges Datum: {args.datum} (erwartet JJJJ-MM-TT)") + return 2 + + manifest = tk.lade_manifest() + repos = lade_pakete(manifest) + if args.paket not in repos: + print(f"Unbekanntes Paket: {args.paket}. Bekannt: {sorted(repos)}") + return 2 + + katalog = sammle(args.paket, repos) + if katalog is None: + return 2 + + treffer: list[tuple[tk.Testdatei, tk.Testfall]] = [] + gesehen: set[str] = set() + for datei in katalog.dateien: + for fall in datei.faelle: + voll = tk.voller_testpfad(datei, fall) + if voll in gesehen: + continue + if any(fnmatch.fnmatchcase(fall.bezeichnung, muster) for muster in args.bezeichner): + treffer.append((datei, fall)) + gesehen.add(voll) + + if not treffer: + print(f"Kein Testfall in {args.paket} passt zu {args.bezeichner}.") + return 1 + + pruefungen, _ = tk.lies_pruefungen(args.pruefungsdatei) + tk.setze_pruefstatus(katalog, pruefungen) + for datei, fall in treffer: + print(f"{datei.anzeigepfad}::{fall.bezeichnung} (vorher: {tk.pruef_text(fall)})") + + if args.trocken: + print(f"Trockenlauf – nichts geschrieben. {len(treffer)} Treffer.") + return 0 + + for datei, fall in treffer: + pruefungen[tk.voller_testpfad(datei, fall)] = {"datum": datum, "hash": fall.quellhash} + + schreibe_pruefungen(args.pruefungsdatei, pruefungen) + print(f"{len(treffer)} Testfälle als geprüft am {datum} markiert: {args.pruefungsdatei}") + return 0 + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + unter = ap.add_subparsers(dest="befehl", required=True) + + p_status = unter.add_parser("status", help="Prüfstatus je Testfall anzeigen") + p_status.add_argument("pakete", nargs="*", help="Paketnamen (Standard: alle mit tests=true)") + p_status.add_argument("--muster", help="nur Testfälle, deren Bezeichner diesen Text enthält (Teilstring)") + p_status.add_argument("--nur", choices=sorted(NUR_ZU_PRUEFSTATUS), help="nur diesen Prüfstatus anzeigen") + p_status.add_argument("--baseline-datei", type=Path, default=tk.BASELINE_DEFAULT) + p_status.add_argument("--pruefungsdatei", type=Path, default=tk.PRUEFUNGEN_DEFAULT) + p_status.set_defaults(func=befehl_status) + + p_markieren = unter.add_parser("markieren", help="Testfälle als heute geprüft markieren") + p_markieren.add_argument("paket", help="Paketname, z. B. sn_basis") + p_markieren.add_argument( + "bezeichner", nargs="+", help="Klasse.methode, exakt oder als fnmatch-Muster (z. B. 'TestX.*')" + ) + p_markieren.add_argument("--datum", default=datetime.date.today().isoformat(), help="Standard: heute") + p_markieren.add_argument("--trocken", action="store_true", help="nur anzeigen, nichts schreiben") + p_markieren.add_argument("--pruefungsdatei", type=Path, default=tk.PRUEFUNGEN_DEFAULT) + p_markieren.set_defaults(func=befehl_markieren) + + args = ap.parse_args() + return args.func(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/testkatalog.py b/scripts/testkatalog.py index 772fdb5..03b1537 100644 --- a/scripts/testkatalog.py +++ b/scripts/testkatalog.py @@ -16,6 +16,11 @@ dieses Skript mit jedem Python >= 3.11 ohne jede Abhängigkeit, auch ohne QGIS. Der Status je Testfall stammt aus docs/status/testbaseline.json; dort stehen unter .rot Einträge der Form " (..)". +Eine dritte Datenquelle ist docs/status/testpruefungen.json: sie hält je Testfall fest, wann er zuletzt von +einem Menschen fachlich geprüft wurde (Datum plus Kurzprüfsumme der Testfunktion, damit eine Änderung am +Testcode die Prüfung automatisch als veraltet kennzeichnet). Diese Datei wird hier nur gelesen; geschrieben +wird sie von scripts/test_audit.py. + Determinismus: Die erzeugte Datei wird versioniert, darf also bei unverändertem Eingang keine Diffs erzeugen. Deshalb steht im Kopf weder Uhrzeit noch Erzeugungsdatum – auch ein reines Tagesdatum würde die Datei bei jedem Lauf an @@ -60,6 +65,7 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] MANIFEST = ROOT / "workspace.toml" BASELINE_DEFAULT = ROOT / "docs" / "status" / "testbaseline.json" +PRUEFUNGEN_DEFAULT = ROOT / "docs" / "status" / "testpruefungen.json" AUSGABE_DEFAULT = ROOT / "docs" / "tests" / "testkatalog.md" HTML_AUSGABE_DEFAULT = ROOT / "docs" / "tests" / "testkatalog.html" @@ -87,6 +93,9 @@ class Testfall: grund: str = "" erwarteter_fehlschlag: bool = False status: str = "grün" + quellhash: str = "" + pruefstatus: str = "nie geprüft" + pruefdatum: str = "" @property def bezeichnung(self) -> str: @@ -188,6 +197,22 @@ def lies_skip(dekoratoren: list[ast.expr]) -> tuple[bool, str, bool]: return uebersprungen, grund, erwartet +def _funktionsquelle(zeilen: list[str], knoten: ast.FunctionDef | ast.AsyncFunctionDef) -> str: + """Quelltext einer Testmethode inkl. eigener Dekoratoren, Trailing Whitespace entfernt. + + Trailing Whitespace wird bewusst ignoriert, damit reine Whitespace-Nacharbeit keine Prüfung + veraltet macht. Einrückung und sonstiger Inhalt bleiben signifikant. + """ + start = min([knoten.lineno] + [d.lineno for d in knoten.decorator_list]) + ende = knoten.end_lineno or knoten.lineno + return "\n".join(zeile.rstrip() for zeile in zeilen[start - 1:ende]) + + +def _funktionshash(zeilen: list[str], knoten: ast.FunctionDef | ast.AsyncFunctionDef) -> str: + """SHA-256-Kurzprüfsumme (12 Zeichen) einer Testmethode, für den Abgleich in testpruefungen.json.""" + return hashlib.sha256(_funktionsquelle(zeilen, knoten).encode("utf-8")).hexdigest()[:12] + + def ist_testcase(klasse: ast.ClassDef) -> bool: """True für Klassen, die als unittest-TestCase gelten. @@ -209,6 +234,7 @@ def ist_testcase(klasse: ast.ClassDef) -> bool: def lies_testdatei(pfad: Path, paket: str) -> Testdatei: """Parst eine Testdatei per ast (ohne sie zu importieren).""" quelle = pfad.read_text(encoding="utf-8") + zeilen = quelle.splitlines() baum = ast.parse(quelle, filename=str(pfad)) datei = Testdatei( pfad=pfad, @@ -235,6 +261,7 @@ def lies_testdatei(pfad: Path, paket: str) -> Testdatei: uebersprungen=skip or klassen_skip, grund=grund or (klassen_grund if klassen_skip else ""), erwarteter_fehlschlag=erwartet or klassen_erwartet, + quellhash=_funktionshash(zeilen, glied), ) ) if gruppe.faelle: @@ -253,6 +280,11 @@ def sammle_paket(paket: str, repo: dict) -> Paketkatalog | None: return katalog +def voller_testpfad(datei: Testdatei, fall: Testfall) -> str: + """Voller Schlüssel eines Testfalls – identisch zum Format in testbaseline.json/testpruefungen.json.""" + return f"{datei.modulpfad}.{fall.bezeichnung}" + + def lies_baseline(pfad: Path) -> tuple[dict[str, set[str]], str]: """Rote Tests je Paket als Menge '..' plus Kurzprüfsumme.""" if not pfad.exists(): @@ -274,7 +306,7 @@ def lies_baseline(pfad: Path) -> tuple[dict[str, set[str]], str]: def setze_status(katalog: Paketkatalog, rot: set[str]) -> None: for datei in katalog.dateien: for fall in datei.faelle: - voll = f"{datei.modulpfad}.{fall.bezeichnung}" + voll = voller_testpfad(datei, fall) if fall.uebersprungen: fall.status = "übersprungen" elif fall.erwarteter_fehlschlag: @@ -285,6 +317,27 @@ def setze_status(katalog: Paketkatalog, rot: set[str]) -> None: fall.status = "grün" +def lies_pruefungen(pfad: Path) -> tuple[dict[str, dict], str]: + """Prüf-Historie je Testfall plus Kurzprüfsumme der Datei; ({}, "") wenn sie fehlt.""" + if not pfad.exists(): + return {}, "" + rohdaten = pfad.read_bytes() + kurz = hashlib.sha256(rohdaten).hexdigest()[:12] + return json.loads(rohdaten.decode("utf-8")), kurz + + +def setze_pruefstatus(katalog: Paketkatalog, pruefungen: dict[str, dict]) -> None: + for datei in katalog.dateien: + for fall in datei.faelle: + eintrag = pruefungen.get(voller_testpfad(datei, fall)) + if eintrag is None: + fall.pruefstatus, fall.pruefdatum = "nie geprüft", "" + elif eintrag.get("hash") == fall.quellhash: + fall.pruefstatus, fall.pruefdatum = "aktuell geprüft", eintrag.get("datum", "") + else: + fall.pruefstatus, fall.pruefdatum = "veraltet", eintrag.get("datum", "") + + def zaehle(faelle: list[Testfall]) -> dict[str, int]: return { "gesamt": len(faelle), @@ -293,6 +346,9 @@ def zaehle(faelle: list[Testfall]) -> dict[str, int]: "uebersprungen": sum(1 for f in faelle if f.status in ("übersprungen", "erwarteter Fehlschlag")), "erwartet": sum(1 for f in faelle if f.status == "erwarteter Fehlschlag"), "mit_docstring": sum(1 for f in faelle if f.beschreibung), + "nie_geprueft": sum(1 for f in faelle if f.pruefstatus == "nie geprüft"), + "aktuell_geprueft": sum(1 for f in faelle if f.pruefstatus == "aktuell geprüft"), + "veraltet_geprueft": sum(1 for f in faelle if f.pruefstatus == "veraltet"), } @@ -313,10 +369,28 @@ def status_text(fall: Testfall) -> str: return fall.status -def erzeuge_markdown(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kurz: str) -> str: +def pruef_text(fall: Testfall) -> str: + """Anzeigetext für den Prüfstatus (Prüfstand-Spalte 'geprüft').""" + if fall.pruefstatus == "aktuell geprüft": + return f"geprüft am {fall.pruefdatum}" + if fall.pruefstatus == "veraltet": + return f"veraltet seit Änderung – zuletzt geprüft am {fall.pruefdatum}" + return "nie geprüft" + + +def erzeuge_markdown( + kataloge: list[Paketkatalog], + baseline_pfad: Path, + baseline_kurz: str, + pruefungen_pfad: Path, + pruefungen_kurz: str, +) -> str: alle = [f for k in kataloge for f in k.faelle] summe = zaehle(alle) baseline_anzeige = baseline_pfad.relative_to(ROOT).as_posix() if baseline_pfad.is_relative_to(ROOT) else str(baseline_pfad) + pruefungen_anzeige = ( + pruefungen_pfad.relative_to(ROOT).as_posix() if pruefungen_pfad.is_relative_to(ROOT) else str(pruefungen_pfad) + ) z: list[str] = [] z.append("# Testkatalog der sn_*-Plugins") @@ -332,6 +406,12 @@ def erzeuge_markdown(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline z.append(f"Stand der Baseline: `{baseline_anzeige}` (SHA-256 `{baseline_kurz}`)") else: z.append(f"Stand der Baseline: `{baseline_anzeige}` **nicht gefunden** – alle Testfälle gelten als grün.") + if pruefungen_kurz: + z.append(f"Stand des Prüf-Audits: `{pruefungen_anzeige}` (SHA-256 `{pruefungen_kurz}`)") + else: + z.append( + f"Stand des Prüf-Audits: `{pruefungen_anzeige}` **nicht gefunden** – alle Testfälle gelten als nie geprüft." + ) z.append("") z.append( f"Gesamt: {len(kataloge)} Pakete, {sum(len(k.dateien) for k in kataloge)} Testdateien, " @@ -339,22 +419,28 @@ def erzeuge_markdown(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline f"{summe['uebersprungen']} übersprungen." ) z.append(f"Mit Beschreibung (Docstring): {anteil(summe['mit_docstring'], summe['gesamt'])}.") + z.append( + f"Fachlich geprüft: {anteil(summe['aktuell_geprueft'], summe['gesamt'])} aktuell, " + f"{summe['veraltet_geprueft']} veraltet seit Codeänderung, {summe['nie_geprueft']} nie geprüft." + ) z.append("") z.append("## Zusammenfassung") z.append("") - z.append("| Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung |") - z.append("| --- | ---: | ---: | ---: | ---: | ---: | ---: |") + z.append("| Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung | fachlich geprüft |") + z.append("| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |") for katalog in kataloge: k = zaehle(katalog.faelle) z.append( f"| `{katalog.paket}` | {len(katalog.dateien)} | {k['gesamt']} | {k['gruen']} | " - f"{k['rot']} | {k['uebersprungen']} | {anteil(k['mit_docstring'], k['gesamt'])} |" + f"{k['rot']} | {k['uebersprungen']} | {anteil(k['mit_docstring'], k['gesamt'])} | " + f"{anteil(k['aktuell_geprueft'], k['gesamt'])} |" ) z.append( f"| **Summe** | **{sum(len(k.dateien) for k in kataloge)}** | **{summe['gesamt']}** | " f"**{summe['gruen']}** | **{summe['rot']}** | **{summe['uebersprungen']}** | " - f"**{anteil(summe['mit_docstring'], summe['gesamt'])}** |" + f"**{anteil(summe['mit_docstring'], summe['gesamt'])}** | " + f"**{anteil(summe['aktuell_geprueft'], summe['gesamt'])}** |" ) z.append("") if summe["erwartet"]: @@ -368,6 +454,11 @@ def erzeuge_markdown(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline z.append(f"- **rot (Baseline)** – der Testfall schlägt bereits fehl und ist in `{baseline_anzeige}` vermerkt; er darf nicht ignoriert, aber auch nicht als neuer Fehler gewertet werden.") z.append("- **übersprungen** – per `@unittest.skip`/`skipIf`/`skipUnless` abgeschaltet; der Grund steht dabei.") z.append("- Ein Testfall heißt `Testgruppe.test_name`; die Testgruppe fasst zusammengehörige Testfälle einer Datei zusammen.") + z.append( + "- **geprüft** – Prüf-Audit (`scripts/test_audit.py`): **nie geprüft** kein Eintrag in " + f"`{pruefungen_anzeige}`; **geprüft am …** ein Mensch hat den Testfall bestätigt und der Testcode hat sich " + "seither nicht geändert; **veraltet seit Änderung …** der Testcode wurde nach der letzten Prüfung geändert." + ) z.append("") for katalog in kataloge: @@ -399,10 +490,12 @@ def erzeuge_markdown(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline for gruppe in datei.gruppen: z.append(f"- `{gruppe.name}` ({len(gruppe.faelle)} Testfälle): {zelle(gruppe.beschreibung)}") z.append("") - z.append("| Testfall | prüft | Status |") - z.append("| --- | --- | --- |") + z.append("| Testfall | prüft | Status | geprüft |") + z.append("| --- | --- | --- | --- |") for fall in datei.faelle: - z.append(f"| `{fall.bezeichnung}` | {zelle(fall.beschreibung)} | {status_text(fall)} |") + z.append( + f"| `{fall.bezeichnung}` | {zelle(fall.beschreibung)} | {status_text(fall)} | {pruef_text(fall)} |" + ) z.append("") z.append("## Lücken") @@ -440,6 +533,12 @@ STATUS_KLASSE = { "erwarteter Fehlschlag": "skip", } +PRUEF_KLASSE = { + "aktuell geprüft": "ok", + "veraltet": "warn", + "nie geprüft": "skip", +} + def _slug(text: str) -> str: return re.sub(r"[^a-zA-Z0-9]+", "-", text).strip("-").lower() @@ -480,6 +579,10 @@ def _html_karte_fuer_datei(datei: Testdatei) -> str: zaehler[STATUS_KLASSE.get(fall.status, "ok")] += 1 mit_doc = sum(1 for f in faelle if f.beschreibung) doc_pct = round(100 * mit_doc / gesamt) if gesamt else 0 + aktuell_geprueft = sum(1 for f in faelle if f.pruefstatus == "aktuell geprüft") + audit_pct = round(100 * aktuell_geprueft / gesamt) if gesamt else 0 + hat_ungeprueft = any(f.pruefstatus == "nie geprüft" for f in faelle) + hat_veraltet = any(f.pruefstatus == "veraltet" for f in faelle) if not datei.gruppen: koerper = ( @@ -501,6 +604,7 @@ def _html_karte_fuer_datei(datei: Testdatei) -> str: kurz = {"grün": "grün", "rot (Baseline)": "rot", "übersprungen": "übersp.", "erwarteter Fehlschlag": "übersp."} for fall in faelle: klasse = STATUS_KLASSE.get(fall.status, "ok") + pruef_klasse = PRUEF_KLASSE.get(fall.pruefstatus, "skip") pruft = ( f'— (Docstring fehlt)' if not fall.beschreibung @@ -511,10 +615,12 @@ def _html_karte_fuer_datei(datei: Testdatei) -> str: f'{html.escape(fall.klasse)}
' f'{html.escape(fall.name)}' f"{pruft}" - f'{kurz.get(fall.status, fall.status)}' + f'{kurz.get(fall.status, fall.status)}' + f'{html.escape(pruef_text(fall))}' ) tabelle = ( - '' + '
TestfallprüftStatus
' + "" f"{''.join(zeilen)}
TestfallprüftStatusgeprüft
" ) diagramm = ( @@ -536,12 +642,14 @@ def _html_karte_fuer_datei(datei: Testdatei) -> str: '' f'{gesamt} Testfälle{pills}' f'{doc_pct}% beschrieben' + f'{audit_pct}% geprüft' '' ) return ( f'
' + f'data-nodoc="{1 if doc_pct < 50 else 0}" ' + f'data-ungeprueft="{1 if hat_ungeprueft else 0}" data-veraltet="{1 if hat_veraltet else 0}">' f"{header}" f'
{koerper}
' "
" @@ -661,6 +769,7 @@ _HTML_KOPF = """Prüfstand .cpill{ font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-size:11.5px; padding:2px 7px; border-radius:999px; font-weight:600; } .cpill-ok{ background:var(--ok-bg); color:var(--ok); } .cpill-warn{ background:var(--warn-bg); color:var(--warn); } .cpill-skip{ background:var(--skip-bg); color:var(--skip); } .docbadge{ color:var(--muted); border:1px solid var(--line-strong); border-radius:999px; padding:2px 8px; } + .auditbadge{ color:var(--muted); border:1px solid var(--line-strong); border-radius:999px; padding:2px 8px; } .chev{ color:var(--muted); transition:transform .15s ease; } .filecard.open .chev{ transform:rotate(180deg); } .card-body{ max-height:0; overflow:hidden; transition:max-height .22s ease; border-top:0 solid var(--line); } @@ -684,6 +793,7 @@ _HTML_KOPF = """Prüfstand .nodoc{ color:var(--muted); font-style:italic; } .pill{ font-size:11.5px; padding:2px 8px; border-radius:999px; font-weight:600; white-space:nowrap; } .pill-ok{ background:var(--ok-bg); color:var(--ok); } .pill-warn{ background:var(--warn-bg); color:var(--warn); } .pill-skip{ background:var(--skip-bg); color:var(--skip); } + .pill-pr-ok{ background:var(--ok-bg); color:var(--ok); } .pill-pr-warn{ background:var(--warn-bg); color:var(--warn); } .pill-pr-skip{ background:var(--skip-bg); color:var(--skip); } footer{ max-width:1180px; margin:40px auto 30px; color:var(--muted); font-size:12px; border-top:1px solid var(--line); padding-top:14px; } [hidden]{ display:none !important; } @media (max-width:640px){ .pkg-bar{ width:130px; } .controls{ position:static; } } @@ -747,7 +857,13 @@ _HTML_SKRIPT = """ """ -def erzeuge_html(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kurz: str) -> str: +def erzeuge_html( + kataloge: list[Paketkatalog], + baseline_pfad: Path, + baseline_kurz: str, + pruefungen_pfad: Path, + pruefungen_kurz: str, +) -> str: """Erzeugt das HTML-Dashboard 'Prüfstand' – dieselben Daten wie erzeuge_markdown, als interaktive Seite mit Baumdiagramm (Mermaid) je Testdatei. Läuft lokal ohne Server.""" alle = [f for k in kataloge for f in k.faelle] @@ -755,11 +871,19 @@ def erzeuge_html(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kur baseline_anzeige = ( baseline_pfad.relative_to(ROOT).as_posix() if baseline_pfad.is_relative_to(ROOT) else str(baseline_pfad) ) + pruefungen_anzeige = ( + pruefungen_pfad.relative_to(ROOT).as_posix() if pruefungen_pfad.is_relative_to(ROOT) else str(pruefungen_pfad) + ) meta_zeile = ( f'Baseline: {html.escape(baseline_anzeige)} (SHA-256 {baseline_kurz})' if baseline_kurz else f'Baseline {html.escape(baseline_anzeige)} nicht gefunden' ) + meta_zeile_audit = ( + f'Prüf-Audit: {html.escape(pruefungen_anzeige)} (SHA-256 {pruefungen_kurz})' + if pruefungen_kurz + else f'Prüf-Audit {html.escape(pruefungen_anzeige)} nicht gefunden' + ) nav_links = "\n ".join( f'{html.escape(k.paket)} ({len(k.faelle)})' @@ -789,7 +913,9 @@ def erzeuge_html(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kur teile.append( 'Testkatalog der sn_*-Plugins — was die Suite heute prüft, auf einen Blick.' ) - teile.append(f'
Quelle: docs/tests/testkatalog.md
{meta_zeile}
') + teile.append( + f'
Quelle: docs/tests/testkatalog.md
{meta_zeile}
{meta_zeile_audit}
' + ) teile.append('
') teile.append(f'
{summe["gesamt"]}Testfälle
') @@ -797,7 +923,9 @@ def erzeuge_html(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kur teile.append(f'
{summe["rot"]}rot (Baseline)
') teile.append(f'') doc_pct = round(100 * summe["mit_docstring"] / summe["gesamt"]) if summe["gesamt"] else 0 + audit_pct = round(100 * summe["aktuell_geprueft"] / summe["gesamt"]) if summe["gesamt"] else 0 teile.append(f'
{doc_pct}%mit Docstring
') + teile.append(f'
{audit_pct}%aktuell geprüft
') teile.append(f'
{sum(len(k.dateien) for k in kataloge)}Testdateien
') teile.append("
") @@ -812,6 +940,8 @@ def erzeuge_html(kataloge: list[Paketkatalog], baseline_pfad: Path, baseline_kur teile.append('') teile.append('') teile.append('') + teile.append('') + teile.append('') teile.append("") teile.append( '