2026-09-17 16:11:58 +02:00
# sn_basis/test/test_sys_wrapper.py
"""sn_basis/tests/test_sys_wrapper.py
Unit-Tests für sn_basis.functions.sys_wrapper.get_plugin_root().
"""
import os
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import patch
from sn_basis.functions import sys_wrapper
def _verknuepfung_anlegen ( ziel : Path , quelle : Path ) -> None :
"""Legt eine Verzeichnisverknüpfung an (Symlink, unter Windows notfalls Junction).
Entspricht exakt der Logik in scripts/link_qgis_profile.py, mit der Klone
ins QGIS-Profil verknüpft werden (dort ohne Admin-Rechte per Junction).
"""
try :
os . symlink ( quelle , ziel , target_is_directory = True )
except ( OSError , NotImplementedError ):
if os . name == "nt" :
import _winapi
_winapi . CreateJunction ( str ( quelle ), str ( ziel ))
else :
raise
class TestGetPluginRoot ( unittest . TestCase ):
def test_get_plugin_root_folgt_keiner_verzeichnisverknuepfung ( self ):
"""Prüft, dass get_plugin_root() bei einem über eine Verzeichnisverknüpfung (wie von link_qgis_profile.py angelegt) erreichten Modul den verlinkten Pfad liefert, statt zum echten Zielverzeichnis aufzulösen (Verfahrensgebiet #50)."""
with TemporaryDirectory () as tmp :
tmp_path = Path ( tmp )
echtes_ziel = tmp_path / "echt" / "sn_basis" / "functions"
echtes_ziel . mkdir ( parents = True )
verlinkter_ordner = tmp_path / "verlinkt"
verlinkter_ordner . mkdir ()
verlinkte_sn_basis = verlinkter_ordner / "sn_basis"
_verknuepfung_anlegen ( verlinkte_sn_basis , echtes_ziel . parent )
fake_file = verlinkte_sn_basis / "functions" / "sys_wrapper.py"
with patch . object ( sys_wrapper , "__file__" , str ( fake_file )):
ergebnis = sys_wrapper . get_plugin_root ()
self . assertEqual ( ergebnis , verlinkter_ordner )
2026-09-18 11:20:10 +02:00
class JoinPathTests ( unittest . TestCase ):
def test_verbindet_mehrere_pfadbestandteile ( self ):
"""Prüft, dass join_path mehrere Bestandteile OS-sicher zu einem Path zusammenfügt."""
ergebnis = sys_wrapper . join_path ( "a" , "b" , "c.txt" )
self . assertEqual ( ergebnis , Path ( "a" ) / "b" / "c.txt" )
class EnsureDirTests ( unittest . TestCase ):
def test_legt_fehlendes_verzeichnis_inklusive_eltern_an ( self ):
"""Prüft, dass ensure_dir ein fehlendes Verzeichnis samt Elternverzeichnissen anlegt."""
with TemporaryDirectory () as tmp :
ziel = Path ( tmp ) / "a" / "b" / "c"
ergebnis = sys_wrapper . ensure_dir ( ziel )
self . assertTrue ( ziel . is_dir ())
self . assertEqual ( ergebnis , ziel )
def test_vorhandenes_verzeichnis_wirft_keinen_fehler ( self ):
"""Prüft, dass ensure_dir bei einem bereits vorhandenen Verzeichnis keinen Fehler wirft."""
with TemporaryDirectory () as tmp :
sys_wrapper . ensure_dir ( Path ( tmp )) # darf nicht scheitern
class GetattrSafeTests ( unittest . TestCase ):
def test_liefert_vorhandenes_attribut ( self ):
"""Prüft, dass getattr_safe ein vorhandenes Attribut liefert."""
class _Beispiel :
wert = 42
self . assertEqual ( sys_wrapper . getattr_safe ( _Beispiel (), "wert" ), 42 )
def test_liefert_default_bei_fehlendem_attribut ( self ):
"""Prüft, dass getattr_safe bei fehlendem Attribut den Default-Wert liefert."""
class _Beispiel :
pass
self . assertEqual ( sys_wrapper . getattr_safe ( _Beispiel (), "fehlt" , "ersatz" ), "ersatz" )
self . assertIsNone ( sys_wrapper . getattr_safe ( _Beispiel (), "fehlt" ))
2026-09-17 16:11:58 +02:00
if __name__ == "__main__" :
unittest . main ()