Kreisel Script-Funktionen und flaches JSON-Testformat

- 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>
This commit is contained in:
2026-06-18 16:05:40 +02:00
parent fc38d4740f
commit bd053d76d3
5 changed files with 181 additions and 137 deletions
+5 -2
View File
@@ -78,8 +78,11 @@ def kreisel_results():
"""Laedt die Kreisel-Ergebnisse aus output/kreisel_results.json."""
path = os.path.join(_output_dir(), "kreisel_results.json")
if not os.path.exists(path):
pytest.skip("kreisel_results.json nicht vorhanden - TESTRUN in BricsCAD ausfuehren")
return _load_json(path)
pytest.skip("kreisel_results.json nicht vorhanden - TEST_KREISEL in BricsCAD ausfuehren")
data = _load_json(path)
if not data:
pytest.skip("kreisel_results.json ist leer - TEST_KREISEL in BricsCAD ausfuehren")
return data
@pytest.fixture
+1 -1
View File
@@ -240,7 +240,7 @@
;; DXF speichern
(setq out-dxf (strcat tests-out-dir "/kreisel_tests.dxf"))
(command "_.SAVEAS" "DXF" out-dxf)
(command "_.SAVEAS" "" out-dxf)
(princ (strcat "\n DXF gespeichert: " out-dxf))
(ssg-end)
+13 -9
View File
@@ -21,7 +21,7 @@ class TestKreiselAttributes:
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["tests"]}
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}"
@@ -35,23 +35,27 @@ class TestKreiselAttributes:
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["tests"]:
for test in kreisel_testdata:
result = results_by_id.get(test["id"])
if not result:
continue
for attr, expected in test["expect"]["attributes"].items():
actual = result["actual_attributes"].get(attr)
assert actual == expected, \
f'{test["id"]}: {attr} erwartet="{expected}", ist="{actual}"'
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["tests"]:
for test in kreisel_testdata:
result = results_by_id.get(test["id"])
if not result:
continue
prefix = test["expect"]["block_prefix"]
prefix = test.get("expect_block_prefix", "KREISEL_")
assert result["block_name"].startswith(prefix), \
f'{test["id"]}: Block "{result["block_name"]}" beginnt nicht mit "{prefix}"'
@@ -77,7 +81,7 @@ class TestKreiselGeometry:
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["tests"])
expected_count = len(kreisel_testdata)
assert len(kr_inserts) >= expected_count, \
f"Erwartet mind. {expected_count} KR_-Bloecke, gefunden: {len(kr_inserts)}"
+109 -125
View File
@@ -1,125 +1,109 @@
{
"module": "Kreisel",
"version": "1.0",
"description": "ILS Kreisel Testfaelle - alle Richtungen und Kreiselarten",
"base_dxf": "kreisel_testbase.dxf",
"output_dxf": "kreisel_tests.dxf",
"output_results": "kreisel_results.json",
"tests": [
{
"id": "KR_Horiz_ObenUnten",
"function": "draw-module",
"description": "Horizontaler Kreisel, oben nach unten, STANDARD",
"params": {
"basepoint": [500.0, 5000.0, 2500.0],
"abstand": 4200.0,
"rotation": 270.0,
"attribs": {
"KREISELART": "STANDARD",
"NAME": "TEST_H_ObenUnten"
}
},
"expect": {
"attributes": {
"KREISELART": "STANDARD",
"DREHUNG": "270.0",
"ABSTAND": "4200"
},
"block_prefix": "KR_",
"min_entities": 6
}
},
{
"id": "KR_Horiz_UntenOben",
"function": "draw-module",
"description": "Horizontaler Kreisel, unten nach oben, PIN",
"params": {
"basepoint": [1500.0, 0.0, 2500.0],
"abstand": 4200.0,
"rotation": 90.0,
"attribs": {
"KREISELART": "PIN",
"NAME": "TEST_H_UntenOben"
}
},
"expect": {
"attributes": {
"KREISELART": "PIN",
"DREHUNG": "90.0",
"ABSTAND": "4200"
},
"block_prefix": "KR_",
"min_entities": 6
}
},
{
"id": "KR_Vert_LinksRechts",
"function": "draw-module",
"description": "Vertikaler Kreisel, links nach rechts, PIN",
"params": {
"basepoint": [0.0, 500.0, 2500.0],
"abstand": 4200.0,
"rotation": 0.0,
"attribs": {
"KREISELART": "PIN",
"NAME": "TEST_V_LinksRechts"
}
},
"expect": {
"attributes": {
"KREISELART": "PIN",
"DREHUNG": "0.0",
"ABSTAND": "4200"
},
"block_prefix": "KR_",
"min_entities": 6
}
},
{
"id": "KR_Vert_RechtsLinks",
"function": "draw-module",
"description": "Vertikaler Kreisel, rechts nach links, STANDARD",
"params": {
"basepoint": [5000.0, 1500.0, 2500.0],
"abstand": 4200.0,
"rotation": 180.0,
"attribs": {
"KREISELART": "STANDARD",
"NAME": "TEST_V_RechtsLinks"
}
},
"expect": {
"attributes": {
"KREISELART": "STANDARD",
"DREHUNG": "180.0",
"ABSTAND": "4200"
},
"block_prefix": "KR_",
"min_entities": 6
}
},
{
"id": "KR_Insert_Schraeg",
"function": "draw-module",
"description": "Kreisel mit 10 Grad Drehung, 6000mm Abstand, PIN",
"params": {
"basepoint": [3000.0, 3000.0, 2000.0],
"abstand": 6000.0,
"rotation": 10.0,
"attribs": {
"KREISELART": "PIN",
"NAME": "TEST_Insert"
}
},
"expect": {
"attributes": {
"KREISELART": "PIN",
"DREHUNG": "10.0",
"ABSTAND": "6000"
},
"block_prefix": "KR_",
"min_entities": 6
}
}
]
}
[
{
"id": "KR_Insert_Horiz_ObenUnten",
"function": "insert",
"x": 500,
"y": 5000,
"z": 2500,
"abstand": 4200,
"rotation": 270.0,
"typ": "STANDARD",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2500",
"expect_kreiselart": "STANDARD"
},
{
"id": "KR_Insert_Horiz_UntenOben",
"function": "insert",
"x": 1500,
"y": 0,
"z": 2500,
"abstand": 4200,
"rotation": 90.0,
"typ": "PIN",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2500",
"expect_kreiselart": "PIN"
},
{
"id": "KR_Insert_Vert_LinksRechts",
"function": "insert",
"x": 0,
"y": 500,
"z": 2500,
"abstand": 4200,
"rotation": 0.0,
"typ": "PIN",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2500",
"expect_kreiselart": "PIN"
},
{
"id": "KR_Insert_Vert_RechtsLinks",
"function": "insert",
"x": 5000,
"y": 1500,
"z": 2500,
"abstand": 4200,
"rotation": 180.0,
"typ": "STANDARD",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2500",
"expect_kreiselart": "STANDARD"
},
{
"id": "KR_Insert_Schraeg",
"function": "insert",
"x": 3000,
"y": 3000,
"z": 2000,
"abstand": 6000,
"rotation": 10.0,
"typ": "PIN",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2000",
"expect_kreiselart": "PIN"
},
{
"id": "KR_Connect_Horizontal",
"function": "connect",
"start_x": 0,
"start_y": 10000,
"start_z": 2500,
"end_x": 5800,
"end_y": 10000,
"end_z": 2500,
"typ": "STANDARD",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2500",
"expect_kreiselart": "STANDARD"
},
{
"id": "KR_Connect_Vertikal",
"function": "connect",
"start_x": 8000,
"start_y": 0,
"start_z": 3000,
"end_x": 8000,
"end_y": 6000,
"end_z": 3000,
"typ": "PIN",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "3000",
"expect_kreiselart": "PIN"
},
{
"id": "KR_Connect_Schraeg_45",
"function": "connect",
"start_x": 10000,
"start_y": 0,
"start_z": 2000,
"end_x": 14000,
"end_y": 4000,
"end_z": 2000,
"typ": "STANDARD",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2000",
"expect_kreiselart": "STANDARD"
}
]