147 lines
6.5 KiB
Python
147 lines
6.5 KiB
Python
"""Tests für die Flurstückssuche im Layer „Flurstücke“ (#56)."""
|
|||
|
|
|
||
|
|
import types
|
||
|
|
import unittest
|
||
|
|
from unittest.mock import patch
|
||
|
|
|
||
|
|
from sn_verfahrensgebiet.functions import flurstueck_suche as fs
|
||
|
|
|
||
|
|
|
||
|
|
class _Feature(dict):
|
||
|
|
def __init__(self, fid, **attribute):
|
||
|
|
super().__init__(attribute)
|
||
|
|
self._fid = fid
|
||
|
|
|
||
|
|
def id(self):
|
||
|
|
return self._fid
|
||
|
|
|
||
|
|
|
||
|
|
class _Layer:
|
||
|
|
def __init__(self, name, features, felder=("flurstueckskennzeichen",)):
|
||
|
|
self._name = name
|
||
|
|
self._features = features
|
||
|
|
self._felder = list(felder)
|
||
|
|
|
||
|
|
def name(self):
|
||
|
|
return self._name
|
||
|
|
|
||
|
|
def fields(self):
|
||
|
|
return types.SimpleNamespace(
|
||
|
|
indexFromName=lambda n: self._felder.index(n) if n in self._felder else -1
|
||
|
|
)
|
||
|
|
|
||
|
|
def getFeatures(self):
|
||
|
|
return iter(self._features)
|
||
|
|
|
||
|
|
|
||
|
|
def _flurstuecke():
|
||
|
|
return _Layer("Flurstücke", [
|
||
|
|
_Feature(1, flurstueckskennzeichen="140268___00562____00"),
|
||
|
|
_Feature(2, flurstueckskennzeichen="140268___00562000100"),
|
||
|
|
_Feature(3, flurstueckskennzeichen="140268___00012000300"),
|
||
|
|
_Feature(4, flurstueckskennzeichen="140269___00562____00"),
|
||
|
|
_Feature(5, flurstueckskennzeichen="140268___00012000a00"),
|
||
|
|
_Feature(6, flurstueckskennzeichen=None),
|
||
|
|
])
|
||
|
|
|
||
|
|
|
||
|
|
def _gemarkungen():
|
||
|
|
return _Layer("Gemarkungen", [
|
||
|
|
_Feature(1, schluessel="140640268", ave_name="Beispielhausen"),
|
||
|
|
_Feature(2, schluessel="140640269", ave_name="Musterdorf"),
|
||
|
|
_Feature(3, schluessel="140650270", ave_name="Musterdorf"),
|
||
|
|
], felder=("schluessel", "ave_name"))
|
||
|
|
|
||
|
|
|
||
|
|
def _projekt(*layer):
|
||
|
|
nach_name = {lyr.name(): lyr for lyr in layer}
|
||
|
|
projekt = types.SimpleNamespace(
|
||
|
|
mapLayersByName=lambda name: [nach_name[name]] if name in nach_name else []
|
||
|
|
)
|
||
|
|
return types.SimpleNamespace(instance=lambda: projekt)
|
||
|
|
|
||
|
|
|
||
|
|
class TestEingabe(unittest.TestCase):
|
||
|
|
|
||
|
|
def test_flurstuecksnummer_mit_und_ohne_nenner(self):
|
||
|
|
"""Prüft, dass Zähler und Nenner getrennt und führende Nullen entfernt werden."""
|
||
|
|
self.assertEqual(fs.zerlege_flurstuecksnummer("562"), ("562", ""))
|
||
|
|
self.assertEqual(fs.zerlege_flurstuecksnummer(" 0012 / 03 "), ("12", "3"))
|
||
|
|
self.assertEqual(fs.zerlege_flurstuecksnummer("12/A"), ("12", "a"))
|
||
|
|
|
||
|
|
def test_ungueltige_flurstuecksnummer(self):
|
||
|
|
"""Prüft, dass leere oder unzulässige Flurstücksnummern abgelehnt werden."""
|
||
|
|
for text in ("", "abc", "12/", "12/3/4", "12-3"):
|
||
|
|
with self.subTest(text=text):
|
||
|
|
with self.assertRaises(fs.FlurstueckSucheFehler):
|
||
|
|
fs.zerlege_flurstuecksnummer(text)
|
||
|
|
|
||
|
|
def test_kennzeichen_zerlegen(self):
|
||
|
|
"""Prüft, dass Gemarkung, Zähler und Nenner aus dem ALKIS-Kennzeichen gelesen werden."""
|
||
|
|
self.assertEqual(fs.zerlege_kennzeichen("140268___00562____00"), ("0268", "562", ""))
|
||
|
|
self.assertEqual(fs.zerlege_kennzeichen("140268___00012000300"), ("0268", "12", "3"))
|
||
|
|
self.assertEqual(fs.zerlege_kennzeichen("140268___00012000a00"), ("0268", "12", "a"))
|
||
|
|
self.assertIsNone(fs.zerlege_kennzeichen("1402"))
|
||
|
|
self.assertIsNone(fs.zerlege_kennzeichen(None))
|
||
|
|
|
||
|
|
def test_gemarkungsnummer_aus_ziffern(self):
|
||
|
|
"""Prüft, dass Ziffern als Gemarkungsnummer gelten, auch ohne führende Nullen oder als langer Schlüssel."""
|
||
|
|
self.assertEqual(fs.gemarkungsnummern("268"), ["0268"])
|
||
|
|
self.assertEqual(fs.gemarkungsnummern("140268"), ["0268"])
|
||
|
|
|
||
|
|
def test_gemarkungsname_ueber_gemarkungslayer(self):
|
||
|
|
"""Prüft, dass ein Gemarkungsname ohne Rücksicht auf Großschreibung in alle passenden Nummern übersetzt wird."""
|
||
|
|
self.assertEqual(fs.gemarkungsnummern("beispielhausen", _gemarkungen()), ["0268"])
|
||
|
|
self.assertEqual(fs.gemarkungsnummern("Musterdorf", _gemarkungen()), ["0269", "0270"])
|
||
|
|
|
||
|
|
def test_gemarkungsname_ohne_layer_oder_unbekannt(self):
|
||
|
|
"""Prüft, dass ein Name ohne Gemarkungslayer oder ohne Treffer eine verständliche Meldung ergibt."""
|
||
|
|
with self.assertRaisesRegex(fs.FlurstueckSucheFehler, "Gemarkungsnummer"):
|
||
|
|
fs.gemarkungsnummern("Beispielhausen", None)
|
||
|
|
with self.assertRaisesRegex(fs.FlurstueckSucheFehler, "keine Gemarkung"):
|
||
|
|
fs.gemarkungsnummern("Nirgendwo", _gemarkungen())
|
||
|
|
with self.assertRaises(fs.FlurstueckSucheFehler):
|
||
|
|
fs.gemarkungsnummern(" ")
|
||
|
|
|
||
|
|
|
||
|
|
class TestSuche(unittest.TestCase):
|
||
|
|
|
||
|
|
def test_mit_nenner_genau_ein_treffer(self):
|
||
|
|
"""Prüft, dass mit Nenner nur das passende Flurstück der Gemarkung gefunden wird."""
|
||
|
|
self.assertEqual(fs.finde_flurstuecke(_flurstuecke(), ["0268"], "12", "3"), [3])
|
||
|
|
self.assertEqual(fs.finde_flurstuecke(_flurstuecke(), ["0268"], "12", "a"), [5])
|
||
|
|
|
||
|
|
def test_ohne_nenner_alle_mit_diesem_zaehler(self):
|
||
|
|
"""Prüft, dass ohne Nenner alle Flurstücke mit dem Zähler gefunden werden, aber nur in der gesuchten Gemarkung."""
|
||
|
|
self.assertEqual(fs.finde_flurstuecke(_flurstuecke(), ["0268"], "562", ""), [1, 2])
|
||
|
|
self.assertEqual(fs.finde_flurstuecke(_flurstuecke(), ["0268", "0269"], "562", ""), [1, 2, 4])
|
||
|
|
|
||
|
|
def test_kein_treffer(self):
|
||
|
|
"""Prüft, dass ein nicht vorhandenes Flurstück eine leere Trefferliste ergibt."""
|
||
|
|
self.assertEqual(fs.finde_flurstuecke(_flurstuecke(), ["0268"], "999", ""), [])
|
||
|
|
|
||
|
|
def test_layer_ohne_kennzeichenfeld(self):
|
||
|
|
"""Prüft, dass ein Flurstückslayer ohne Feld „flurstueckskennzeichen“ gemeldet wird."""
|
||
|
|
layer = _Layer("Flurstücke", [], felder=("gml_id",))
|
||
|
|
with self.assertRaisesRegex(fs.FlurstueckSucheFehler, "flurstueckskennzeichen"):
|
||
|
|
fs.finde_flurstuecke(layer, ["0268"], "562", "")
|
||
|
|
|
||
|
|
def test_fehlender_flurstueckslayer_bricht_ab(self):
|
||
|
|
"""Prüft, dass die Suche ohne Layer „Flurstücke“ mit dem Hinweis abbricht, zuerst Verfahrensgebiet und Flurstücke zu laden."""
|
||
|
|
with patch.object(fs, "QgsProject", _projekt(_gemarkungen())):
|
||
|
|
with self.assertRaises(fs.KeinFlurstueckslayer) as kontext:
|
||
|
|
fs.flurstueck_suchen("0268", "562")
|
||
|
|
self.assertIn("Flurstücke aus ALKIS laden", str(kontext.exception))
|
||
|
|
|
||
|
|
def test_suche_im_projekt_mit_gemarkungsname(self):
|
||
|
|
"""Prüft, dass die Suche im Projekt den Gemarkungsnamen auflöst und Layer samt Treffern liefert."""
|
||
|
|
flurstuecke = _flurstuecke()
|
||
|
|
with patch.object(fs, "QgsProject", _projekt(flurstuecke, _gemarkungen())):
|
||
|
|
ergebnis = fs.flurstueck_suchen("Beispielhausen", "12/3")
|
||
|
|
self.assertIs(ergebnis.layer, flurstuecke)
|
||
|
|
self.assertEqual(ergebnis.feature_ids, [3])
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main()
|