bd053d76d3
- kreisel-insert-script und kreisel-connect-script in KreiselInsert.lsp fuer nicht-interaktives Einfuegen (Tests, Automatisierung) - kreisel_tests.json von verschachteltem auf flaches JSON-Array umgestellt (kompatibel mit omni:load-json) - test_kreisel.py an neues JSON-Format angepasst (direkte Felder statt nested expect/attributes) - conftest.py: Leere kreisel_results.json wird jetzt korrekt uebersprungen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
138 lines
6.4 KiB
Python
138 lines
6.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
test_kreisel.py - Validiert ILS Kreisel Testergebnisse.
|
|
|
|
Prueft:
|
|
1. Attributwerte aus results.json gegen Testdefinitionen
|
|
2. DXF-Geometrie mit ezdxf (Block-Existenz, Radien, Linien)
|
|
3. Referenz-Vergleich gegen abgenommene DXF
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
# ============================================================
|
|
# Attribut-Pruefung (results.json vs. testdata)
|
|
# ============================================================
|
|
|
|
class TestKreiselAttributes:
|
|
"""Prueft ob Attribute korrekt gesetzt wurden."""
|
|
|
|
def test_all_tests_executed(self, kreisel_testdata, kreisel_results):
|
|
"""Alle definierten Testfaelle muessen ausgefuehrt worden sein."""
|
|
expected_ids = {t["id"] for t in kreisel_testdata}
|
|
result_ids = {r["test_id"] for r in kreisel_results}
|
|
missing = expected_ids - result_ids
|
|
assert not missing, f"Nicht ausgefuehrte Tests: {missing}"
|
|
|
|
def test_all_executed_successfully(self, kreisel_results):
|
|
"""Alle Ergebnisse muessen Status 'executed' haben."""
|
|
for result in kreisel_results:
|
|
assert result["status"] == "executed", \
|
|
f'{result["test_id"]}: Status={result["status"]}'
|
|
|
|
def test_attributes_match(self, kreisel_testdata, kreisel_results):
|
|
"""Erwartete Attribute muessen mit tatsaechlichen uebereinstimmen."""
|
|
results_by_id = {r["test_id"]: r for r in kreisel_results}
|
|
for test in kreisel_testdata:
|
|
result = results_by_id.get(test["id"])
|
|
if not result:
|
|
continue
|
|
if "expect_kreiselart" in test:
|
|
actual = result["actual_attributes"].get("KREISELART")
|
|
assert actual == test["expect_kreiselart"], \
|
|
f'{test["id"]}: KREISELART erwartet="{test["expect_kreiselart"]}", ist="{actual}"'
|
|
if "expect_hoehe" in test:
|
|
actual = result["actual_attributes"].get("HOEHE")
|
|
assert actual == test["expect_hoehe"], \
|
|
f'{test["id"]}: HOEHE erwartet="{test["expect_hoehe"]}", ist="{actual}"'
|
|
|
|
def test_block_prefix(self, kreisel_testdata, kreisel_results):
|
|
"""Block-Namen muessen mit erwartetem Praefix beginnen."""
|
|
results_by_id = {r["test_id"]: r for r in kreisel_results}
|
|
for test in kreisel_testdata:
|
|
result = results_by_id.get(test["id"])
|
|
if not result:
|
|
continue
|
|
prefix = test.get("expect_block_prefix", "KREISEL_")
|
|
assert result["block_name"].startswith(prefix), \
|
|
f'{test["id"]}: Block "{result["block_name"]}" beginnt nicht mit "{prefix}"'
|
|
|
|
|
|
# ============================================================
|
|
# DXF Geometrie-Pruefung (ezdxf)
|
|
# ============================================================
|
|
|
|
class TestKreiselGeometry:
|
|
"""Prueft DXF-Geometrie mit ezdxf."""
|
|
|
|
def test_blocks_in_modelspace(self, kreisel_dxf, kreisel_results):
|
|
"""Alle erzeugten Bloecke muessen im Modelspace vorhanden sein."""
|
|
msp = kreisel_dxf.modelspace()
|
|
inserts = [e for e in msp if e.dxftype() == "INSERT"]
|
|
insert_handles = {e.dxf.handle for e in inserts}
|
|
for result in kreisel_results:
|
|
assert result["block_handle"] in insert_handles, \
|
|
f'{result["test_id"]}: Block-Handle {result["block_handle"]} nicht im Modelspace'
|
|
|
|
def test_kr_block_count(self, kreisel_dxf, kreisel_testdata):
|
|
"""Anzahl KR_-Bloecke muss Testfall-Anzahl entsprechen."""
|
|
msp = kreisel_dxf.modelspace()
|
|
kr_inserts = [e for e in msp if e.dxftype() == "INSERT"
|
|
and e.dxf.name.startswith("KR_")]
|
|
expected_count = len(kreisel_testdata)
|
|
assert len(kr_inserts) >= expected_count, \
|
|
f"Erwartet mind. {expected_count} KR_-Bloecke, gefunden: {len(kr_inserts)}"
|
|
|
|
def test_circle_radius(self, kreisel_dxf):
|
|
"""AN8/SP8 Kreise in KR_-Bloecken muessen Radius 400mm haben."""
|
|
for block in kreisel_dxf.blocks:
|
|
if not block.name.startswith("KR_"):
|
|
continue
|
|
circles = [e for e in block if e.dxftype() == "CIRCLE"]
|
|
for c in circles:
|
|
assert abs(c.dxf.radius - 400.0) < 0.1, \
|
|
f'Block {block.name}: Kreis-Radius={c.dxf.radius}, erwartet=400.0'
|
|
|
|
def test_insert_positions(self, kreisel_dxf, kreisel_results):
|
|
"""Insertionspunkte muessen mit results.json uebereinstimmen."""
|
|
msp = kreisel_dxf.modelspace()
|
|
inserts_by_handle = {e.dxf.handle: e for e in msp if e.dxftype() == "INSERT"}
|
|
for result in kreisel_results:
|
|
insert = inserts_by_handle.get(result["block_handle"])
|
|
if not insert:
|
|
continue
|
|
expected = result["insert_point"]
|
|
actual = insert.dxf.insert
|
|
assert abs(actual.x - expected[0]) < 1.0, \
|
|
f'{result["test_id"]}: X={actual.x}, erwartet={expected[0]}'
|
|
assert abs(actual.y - expected[1]) < 1.0, \
|
|
f'{result["test_id"]}: Y={actual.y}, erwartet={expected[1]}'
|
|
|
|
|
|
# ============================================================
|
|
# Referenz-Vergleich
|
|
# ============================================================
|
|
|
|
class TestKreiselReference:
|
|
"""Vergleicht Ergebnis gegen abgenommene Referenz-DXF."""
|
|
|
|
def test_block_count_matches_reference(self, kreisel_dxf, kreisel_ref_dxf):
|
|
"""Anzahl KR_-Bloecke muss mit Referenz uebereinstimmen."""
|
|
output_kr = sum(1 for e in kreisel_dxf.modelspace()
|
|
if e.dxftype() == "INSERT" and e.dxf.name.startswith("KR_"))
|
|
ref_kr = sum(1 for e in kreisel_ref_dxf.modelspace()
|
|
if e.dxftype() == "INSERT" and e.dxf.name.startswith("KR_"))
|
|
assert output_kr == ref_kr, \
|
|
f"Block-Anzahl: output={output_kr}, referenz={ref_kr}"
|
|
|
|
def test_block_types_match_reference(self, kreisel_dxf, kreisel_ref_dxf):
|
|
"""Block-Typen muessen mit Referenz uebereinstimmen."""
|
|
output_names = sorted(e.dxf.name for e in kreisel_dxf.modelspace()
|
|
if e.dxftype() == "INSERT" and e.dxf.name.startswith("KR_"))
|
|
ref_names = sorted(e.dxf.name for e in kreisel_ref_dxf.modelspace()
|
|
if e.dxftype() == "INSERT" and e.dxf.name.startswith("KR_"))
|
|
assert output_names == ref_names, \
|
|
f"Block-Typen unterschiedlich:\n output: {output_names}\n referenz: {ref_names}"
|