Files
plant2dxf/lib/Elemente/VarioFoerderer_tests.py
T

285 lines
9.5 KiB
Python

# -*- coding: utf-8 -*-
"""
Unit-Tests für VarioFoerderer (Refactored)
Diese Tests können direkt in der Library-Methode verwendet werden
oder als separate Test-Datei ausgeführt werden.
"""
import unittest
import math
from unittest.mock import Mock, MagicMock
from .VarioFoerderer import (
VarioFoerderer,
Foerderrichtung,
MotorUmlenkConfig,
BogenDeltas,
OffsetResult,
_parse_delta_attribute,
_calculate_offset_with_rotation,
_is_es_as_element,
horizontale_ausrichtung,
)
class TestMotorUmlenkConfig(unittest.TestCase):
"""Tests für MotorUmlenkConfig Dataclass"""
def test_motor_offset_berechnung(self):
"""Test: Motor-Offset-Berechnung"""
config = MotorUmlenkConfig(
winkel_motor=45.0,
winkel_umlenk=30.0,
umlenk_laenge=(100.0, 50.0),
motor_laenge=(80.0, 40.0),
vario_abstand=25.0
)
# Motor-Offsets
expected_motor_x = 100.0 * math.cos(math.radians(45.0))
expected_motor_z = 100.0 * math.sin(math.radians(45.0))
self.assertAlmostEqual(config.motor_offset_x, expected_motor_x, places=5)
self.assertAlmostEqual(config.motor_offset_z, expected_motor_z, places=5)
def test_umlenk_offset_berechnung(self):
"""Test: Umlenk-Offset-Berechnung"""
config = MotorUmlenkConfig(
winkel_motor=45.0,
winkel_umlenk=30.0,
umlenk_laenge=(100.0, 50.0),
motor_laenge=(80.0, 40.0),
vario_abstand=25.0
)
# Umlenk-Offsets
expected_umlenk_x = 80.0 * math.cos(math.radians(30.0))
expected_umlenk_z = 80.0 * math.sin(math.radians(30.0))
self.assertAlmostEqual(config.umlenk_offset_x, expected_umlenk_x, places=5)
self.assertAlmostEqual(config.umlenk_offset_z, expected_umlenk_z, places=5)
class TestBogenDeltas(unittest.TestCase):
"""Tests für BogenDeltas Dataclass"""
def test_normalize_negative_values(self):
"""Test: Normalisierung negativer Werte"""
deltas = BogenDeltas(
SP_0=[-10.0, -20.0, 5.0],
SP_1=[15.0, -25.0, 10.0],
VP_0=[-5.0, 8.0, -3.0],
VP_1=[12.0, -15.0, 7.0]
)
deltas.normalize_negative_values()
# X und Y (Index 0 und 1) sollen positiv sein, Z (Index 2) unverändert
self.assertEqual(deltas.SP_0, [10.0, 20.0, 5.0])
self.assertEqual(deltas.SP_1, [15.0, 25.0, 10.0])
self.assertEqual(deltas.VP_0, [5.0, 8.0, -3.0])
self.assertEqual(deltas.VP_1, [12.0, 15.0, 7.0])
class TestVarioFoerderer(unittest.TestCase):
"""Tests für VarioFoerderer Modell"""
def test_from_merkmale(self):
"""Test: VarioFoerderer aus Merkmale-Dict erstellen"""
merkmale = {
"Höhe Anfang": "1.5",
"Höhe Ende": "2.0",
"Länge in Meter": "5.0",
"Winkel": "6",
"Motorstation_hinten": True,
"Spannstation_vorn": False,
"Drehung": "-90",
"Förderrichtung": "Auf",
"Anzahl der Scanner": "2",
"Anzahl der Separatoren": "3",
}
foerderer = VarioFoerderer.from_merkmale("TEST-001", 100.0, 200.0, merkmale)
self.assertEqual(foerderer.teileid, "TEST-001")
self.assertEqual(foerderer.x, 100.0)
self.assertEqual(foerderer.y, 200.0)
self.assertEqual(foerderer.h0, 1500.0) # 1.5 * 1000
self.assertEqual(foerderer.h1, 2000.0) # 2.0 * 1000
self.assertEqual(foerderer.laenge, 5000.0) # 5.0 * 1000
self.assertEqual(foerderer.winkel, 6.0)
self.assertTrue(foerderer.hat_motor)
self.assertFalse(foerderer.hat_umlenk)
self.assertEqual(foerderer.drehung, -90.0)
self.assertEqual(foerderer.foerderer_richtung, "Auf")
self.assertEqual(foerderer.anzahl_scanner, 2)
self.assertEqual(foerderer.anzahl_separatoren, 3)
def test_hight_zwischen(self):
"""Test: Berechnung der mittleren Höhe"""
merkmale = {
"Höhe Anfang": "1.0",
"Höhe Ende": "3.0",
"Länge in Meter": "1.0",
"Winkel": "3",
"Motorstation_hinten": False,
"Spannstation_vorn": False,
"Drehung": "0",
"Förderrichtung": "Auf",
"Anzahl der Scanner": "0",
"Anzahl der Separatoren": "0",
}
foerderer = VarioFoerderer.from_merkmale("TEST-002", 0, 0, merkmale)
expected_height = (1000.0 + 3000.0) / 2 # (h0 + h1) / 2
self.assertEqual(foerderer.hight_zwischen, expected_height)
class TestHilfsfunktionen(unittest.TestCase):
"""Tests für generische Hilfsfunktionen"""
def test_parse_delta_attribute(self):
"""Test: Delta-Attribut parsen"""
attrib_dict = {
"DELTA_SP_0": "10.5;20.3;-5.7",
"DELTA_VP_1": "15.2,25.8,-8.1"
}
result_sp = _parse_delta_attribute(attrib_dict, "DELTA_SP_0")
result_vp = _parse_delta_attribute(attrib_dict, "DELTA_VP_1")
self.assertEqual(result_sp, [10.5, 20.3, -5.7])
self.assertEqual(result_vp, [15.2, 25.8, -8.1])
def test_calculate_offset_with_rotation(self):
"""Test: Offset-Berechnung mit Rotation"""
SP = [10.0, 5.0, 8.0]
VP = [2.0, 5.0, 3.0]
winkel = 45.0
result = _calculate_offset_with_rotation(SP, VP, winkel)
# Erwartete Werte berechnen
rad = math.radians(45.0)
expected_x = (SP[0] - VP[0]) * math.cos(rad) + (SP[2] - VP[2]) * math.sin(rad)
expected_y = VP[1]
expected_z = -(SP[0] - VP[0]) * math.sin(rad) + (SP[2] - VP[2]) * math.cos(rad)
self.assertAlmostEqual(result[0], expected_x, places=5)
self.assertAlmostEqual(result[1], expected_y, places=5)
self.assertAlmostEqual(result[2], expected_z, places=5)
def test_is_es_as_element_true(self):
"""Test: ES/AS-Element erkennen"""
entity = Mock()
entity.dxftype.return_value = "INSERT"
entity.dxf.name = "200000146_ES-Element_90_rechts_modified"
self.assertTrue(_is_es_as_element(entity))
def test_is_es_as_element_false(self):
"""Test: Kein ES/AS-Element"""
entity = Mock()
entity.dxftype.return_value = "INSERT"
entity.dxf.name = "Vario_Bogen_auf_12°"
self.assertFalse(_is_es_as_element(entity))
def test_is_es_as_element_not_insert(self):
"""Test: Kein INSERT-Entity"""
entity = Mock()
entity.dxftype.return_value = "LINE"
self.assertFalse(_is_es_as_element(entity))
class TestHorizontaleAusrichtung(unittest.TestCase):
"""Tests für horizontale_ausrichtung Funktion"""
def test_horizontal_rotation_0(self):
"""Test: Horizontale Ausrichtung bei Rotation 0°"""
merkmale = {
"Höhe Anfang": "1.0",
"Höhe Ende": "1.0",
"Länge in Meter": "1.0",
"Winkel": "3",
"Motorstation_hinten": False,
"Spannstation_vorn": False,
"Drehung": "0",
"Förderrichtung": "Horizontal",
"Anzahl der Scanner": "0",
"Anzahl der Separatoren": "0",
}
foerderer = VarioFoerderer.from_merkmale("TEST", 100.0, 200.0, merkmale)
# Förderer ist über Kreisel (y > y_kreisel)
result = horizontale_ausrichtung(foerderer, 100.0, 100.0)
self.assertEqual(result, "unten_drehung_0_or_-90")
# Förderer ist unter Kreisel (y < y_kreisel)
result = horizontale_ausrichtung(foerderer, 100.0, 300.0)
self.assertEqual(result, "oben_drehung_0_or_-90")
def test_nicht_horizontal(self):
"""Test: Nicht-horizontale Förderer geben 'None' zurück"""
merkmale = {
"Höhe Anfang": "1.0",
"Höhe Ende": "2.0",
"Länge in Meter": "1.0",
"Winkel": "6",
"Motorstation_hinten": False,
"Spannstation_vorn": False,
"Drehung": "0",
"Förderrichtung": "Auf",
"Anzahl der Scanner": "0",
"Anzahl der Separatoren": "0",
}
foerderer = VarioFoerderer.from_merkmale("TEST", 100.0, 200.0, merkmale)
result = horizontale_ausrichtung(foerderer, 100.0, 100.0)
self.assertEqual(result, "None")
class TestFoerderrichtungEnum(unittest.TestCase):
"""Tests für Foerderrichtung Enum"""
def test_enum_werte(self):
"""Test: Enum-Werte sind korrekt"""
self.assertEqual(Foerderrichtung.AUF.value, "Auf")
self.assertEqual(Foerderrichtung.AB.value, "Ab")
self.assertEqual(Foerderrichtung.HORIZONTAL.value, "Horizontal")
def test_enum_vergleich(self):
"""Test: Enum-Vergleich funktioniert"""
richtung = "Auf"
self.assertEqual(richtung, Foerderrichtung.AUF.value)
# ============================================================================
# Test-Runner
# ============================================================================
def run_tests():
"""Führt alle Unit-Tests aus"""
loader = unittest.TestLoader()
suite = loader.loadTestsFromModule(__import__(__name__))
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
print("\n" + "="*70)
print(f"Tests durchgeführt: {result.testsRun}")
print(f"Erfolgreich: {result.testsRun - len(result.failures) - len(result.errors)}")
print(f"Fehlgeschlagen: {len(result.failures)}")
print(f"Errors: {len(result.errors)}")
print("="*70)
return result.wasSuccessful()
if __name__ == "__main__":
success = run_tests()
exit(0 if success else 1)