Files
Plugin_SN_Basis/tests/test_basemap_stilvorlagen.py
T
DanielandClaude Opus 5.5 f9241a11f9 Basemap-Bereich im Druck-Tab mit lokalen Stilvorlagen (#88)
Einklappbarer Bereich „Basemap“: Auswertebereich (Verfahrensgebiet/Druckbereich),
Basemap-Legende beim Erstellen an/aus, „Basemap-Legende aktualisieren“ für
bestehende Vorlagen und Stilvorlagen des Basemap-Layers. Stilvorlagen liegen lokal im
QGIS-Profil (QML plus Begleitdatei mit Legendenauswahl), mehrere Varianten, eine als
Standard markierbar; geladen wird nur auf Knopfdruck nach Rückfrage, fremde Varianten
(andere Style-Namen) erst nach zweiter Bestätigung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:57:10 +02:00

129 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Tests für modules/basemap_stilvorlagen.py – lokale Stilvorlagen des Basemap-Layers (Basis #88).
Gespeichert wird in einem temporären Ordner; der Layer schreibt statt einer echten QML-Datei
eine kleine Textdatei. Laden und Speichern am echten Vektorkachel-Layer ist im QGIS-Test geprüft.
"""
import os
import shutil
import tempfile
import unittest
from sn_basis.modules.basemap_stilvorlagen import STANDARD_SCHLUESSEL, BasemapStilvorlagen
class _Einstellungen:
"""Ersatz für QSettings – die Tests dürfen keine echten Benutzereinstellungen verändern."""
def __init__(self): self.daten = {}
def value(self, k, standard=""): return self.daten.get(k, standard)
def setValue(self, k, v): self.daten[k] = v
def remove(self, k): self.daten.pop(k, None)
class _Stil:
def __init__(self, name): self._name = name
def styleName(self): return self._name
class _Layer:
def __init__(self, stile=("Kontur_Kreisstr", "Decker_Kreisstr"), speichern_ok=True):
self.stile = list(stile)
self.geladen = None
self.neu_gezeichnet = False
self._speichern_ok = speichern_ok
def name(self): return "Basemap.de - Farbe"
def renderer(self): return type("R", (), {"styles": lambda s: [_Stil(n) for n in self.stile]})()
def saveNamedStyle(self, pfad, kategorien):
if not self._speichern_ok:
return "kein Schreibrecht", False
with open(pfad, "w", encoding="utf-8") as datei:
datei.write("<qgis/>")
return "", True
def loadNamedStyle(self, pfad, kategorien):
self.geladen = pfad
return "", True
def triggerRepaint(self): self.neu_gezeichnet = True
class TestStilvorlagen(unittest.TestCase):
def setUp(self):
self.ordner = tempfile.mkdtemp()
self.einstellungen = _Einstellungen()
self.vorlagen = BasemapStilvorlagen(os.path.join(self.ordner, "stile"), self.einstellungen)
def tearDown(self):
shutil.rmtree(self.ordner, ignore_errors=True)
def test_speichern_und_auflisten(self):
"""Prüft, dass eine gespeicherte Vorlage mit Anzeigenamen, QML-Datei und Begleitdatei aufgelistet wird."""
self.vorlagen.speichern(_Layer(), "Ohne Hausnummern", {"ausgeblendet": ["wald"], "eingeblendet": []})
liste = self.vorlagen.liste()
self.assertEqual([v.anzeigename for v in liste], ["Ohne Hausnummern"])
self.assertEqual(liste[0].name, "Ohne_Hausnummern")
self.assertTrue(os.path.exists(liste[0].pfad))
self.assertEqual(self.vorlagen.legendenauswahl("Ohne_Hausnummern")["ausgeblendet"], ["wald"])
def test_mehrere_varianten_alphabetisch(self):
"""Prüft, dass mehrere Varianten nebeneinander bestehen und alphabetisch nach Anzeigename sortiert werden."""
for name in ("Zeichnung", "Abstimmung", "mit Gebäuden"):
self.vorlagen.speichern(_Layer(), name)
self.assertEqual([v.anzeigename for v in self.vorlagen.liste()], ["Abstimmung", "mit Gebäuden", "Zeichnung"])
def test_leerer_name_oder_fehler_beim_schreiben(self):
"""Prüft, dass ein leerer Name und ein Schreibfehler von QGIS als ValueError gemeldet werden."""
with self.assertRaises(ValueError):
self.vorlagen.speichern(_Layer(), " ")
with self.assertRaises(ValueError):
self.vorlagen.speichern(_Layer(speichern_ok=False), "Test")
def test_laden_setzt_stil_und_zeichnet_neu(self):
"""Prüft, dass das Laden die QML-Datei der Vorlage in den Layer lädt und neu zeichnen lässt."""
self.vorlagen.speichern(_Layer(), "Standard LNO")
layer = _Layer()
self.vorlagen.laden(layer, "Standard_LNO")
self.assertTrue(layer.geladen.endswith("Standard_LNO.qml"))
self.assertTrue(layer.neu_gezeichnet)
with self.assertRaises(ValueError):
self.vorlagen.laden(layer, "gibt_es_nicht")
def test_passung_meldet_fremde_styles(self):
"""Prüft, dass Style-Namen der Vorlage gemeldet werden, die der Ziel-Layer nicht kennt."""
self.vorlagen.speichern(_Layer(stile=("A", "B", "C")), "Grau")
self.assertEqual(self.vorlagen.pruefe_passung(_Layer(stile=("A",)), "Grau"), ["B", "C"])
self.assertEqual(self.vorlagen.pruefe_passung(_Layer(stile=("A", "B", "C")), "Grau"), [])
def test_standard_setzen_und_beim_loeschen_entfernen(self):
"""Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt."""
self.vorlagen.speichern(_Layer(), "Standard LNO")
self.vorlagen.setze_standard("Standard_LNO")
self.assertTrue(self.vorlagen.liste()[0].standard)
self.vorlagen.loeschen("Standard_LNO")
self.assertEqual(self.vorlagen.liste(), [])
self.assertEqual(self.vorlagen.standard(), "")
self.assertNotIn(STANDARD_SCHLUESSEL, self.einstellungen.daten)
with self.assertRaises(ValueError):
self.vorlagen.setze_standard("Standard_LNO")
def test_fehlende_begleitdatei_wird_toleriert(self):
"""Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird."""
os.makedirs(self.vorlagen.ordner, exist_ok=True)
with open(os.path.join(self.vorlagen.ordner, "Alt.qml"), "w", encoding="utf-8") as datei:
datei.write("<qgis/>")
self.assertEqual([v.anzeigename for v in self.vorlagen.liste()], ["Alt"])
self.assertIsNone(self.vorlagen.legendenauswahl("Alt"))
self.assertEqual(self.vorlagen.pruefe_passung(_Layer(), "Alt"), [])
def test_ohne_ordner_leere_liste(self):
"""Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt."""
self.assertEqual(self.vorlagen.liste(), [])
if __name__ == "__main__":
unittest.main()