diff --git a/tests/alltests.json b/tests/alltests.json index a98254e..8b70744 100644 --- a/tests/alltests.json +++ b/tests/alltests.json @@ -1,6 +1,7 @@ [ { "name": "kreisel", "save": "dxf", "module": "KreiselInsert" }, { "name": "foerderer", "save": "dwg", "module": "VarioFoerderer" }, + { "name": "linienzug", "save": "dwg", "module": "VarioFoerderer" }, { "name": "omniflo", "save": "dxf", "module": "OmniModulInsert" }, { "name": "gefaellestrecke", "save": "dwg", "module": "Gefaellestrecke" } ] diff --git a/tests/test_linienzug.lsp b/tests/test_linienzug.lsp index b417ccb..85380a7 100644 --- a/tests/test_linienzug.lsp +++ b/tests/test_linienzug.lsp @@ -8,21 +8,25 @@ ;; Skript ab: die vier Eingabe-Funktionen werden NUR waehrend des Testlaufs ;; durch Mocks ersetzt (mit Save/Restore), danach wieder hergestellt. ;; +;; Die Eingabe-Sequenz (Skript) wird NICHT mehr im Code hartkodiert, sondern +;; aus tests/testdata/linienzug_tests.json geladen. Jedes JSON-Objekt mit +;; "typ" ist ein Eingabe-Schritt in exakter Aufruf-Reihenfolge: +;; {"typ":"point_abs","wert":[x,y,z]} absoluter Punkt (getpoint) +;; {"typ":"point_rel","dL":..,"hz":..} Basispunkt + dL entlang Richtung hz +;; {"typ":"real","wert":..} getreal +;; {"typ":"int","wert":..} getint +;; {"typ":"string","wert":".."} getstring +;; Das erste Objekt (ohne "typ") enthaelt Beschreibung/Erwartung (Metadaten). +;; ;; Voraussetzungen: ;; - SSG_LIB geladen (VarioFoerderer.lsp inkl. vf_linienzug.lsp mit ;; vfl-getpoint, Gefaellestrecke.lsp, ssg_core.lsp) ;; - Umgebungsvariable DXFMAKRO gesetzt ;; -;; Repliziertes Szenario (aus manuellem Test): -;; Start Z=4500, AS rechts -;; -> Neue Linie (Ab, Ziel-Z=1800, Winkel 45 Grad), GF ganz am Einlauf -;; -> Horizontal 900 mm mit Separator VOR + NACH (beide horizontal, 0 Grad) -;; -> Vario-Kurve 90 links aussen -;; -> Horizontal 250 mm (ohne Separatoren) -;; -> Vario-Kurve 90 links aussen -;; -> Option 3 (Kettenende definieren): Ziel-Z=4500, Winkel 45 Grad, ES rechts +;; Speichert (Konvention fuer test_run_all.lsp): +;; - tests/output/linienzug_results.json (via linienzug:export-results) ;; -;; Erwartetes Ergebnis (Ist-Ziel-Report): +;; Erwartetes Ergebnis (Ist-Ziel-Report, siehe Metadaten in JSON): ;; dX ~ 0, dZ ~ 0 (Ziel exakt getroffen), ;; dY ~ 637 mm = seitlicher Fussabdruck des ES_Element_90 (90-Grad-Schwenk; ;; KEIN Baufehler, sondern die Bauform des ES-Elements). @@ -63,7 +67,67 @@ (defun tlz-getint (a) (tlz-pop)) (defun tlz-getreal (a) (tlz-pop)) -(defun c:TEST_LINIENZUG ( / old-vgp old-gs old-gi old-gr err) +;; --- Parsierte JSON-Daten in die Skript-Queue uebersetzen --- +;; Erwartet die von ssg-load-json gelieferte Liste von Alists. +;; Nur Objekte mit "typ" sind Eingabe-Schritte; Objekte ohne "typ" +;; (Metadaten) werden uebersprungen. Die Reihenfolge bleibt erhalten. +;; Rueckgabe: Queue im Format, das die Mock-Funktionen erwarten. +(defun tlz-daten->queue (daten / q typ) + (setq q nil) + (foreach schritt daten + (setq typ (ssg-val schritt "typ")) + (cond + ((= typ "point_abs") + (setq q (cons (cons 'A (ssg-val schritt "wert")) q))) + ((= typ "point_rel") + (setq q (cons (list 'P (ssg-val schritt "dL") (ssg-val schritt "hz")) q))) + ((= typ "real") + (setq q (cons (float (ssg-val schritt "wert")) q))) + ((= typ "int") + (setq q (cons (ssg-val schritt "wert") q))) + ((= typ "string") + (setq q (cons (ssg-val schritt "wert") q))) + ) + ) + (reverse q) +) + +;; --- Metadaten-Objekt (Beschreibung/Erwartung) aus JSON-Daten holen --- +;; Liefert die erste Alist ohne "typ" oder nil. +(defun tlz-daten->meta (daten / meta) + (setq meta nil) + (foreach obj daten + (if (and (null meta) (null (ssg-val obj "typ"))) + (setq meta obj) + ) + ) + meta +) + +;; --- JSON-Export der Linienzug-Testergebnisse (Konvention fuer run-all) --- +(defun linienzug:export-results (tests-out-dir / out-json f) + (if (null *linienzug-test-results*) + (princ "\n Keine Linienzug-Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/linienzug_results.json")) + (setq f (open out-json "w")) + (if f + (progn + (write-line "[" f) + (write-line *linienzug-test-results* f) + (write-line "]" f) + (close f) + (princ (strcat "\n Ergebnisse: " out-json)) + ) + (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) + ) + ) + ) +) + +(defun c:TEST_LINIENZUG ( / json-datei daten meta schritte-anz rest-anz status + old-vgp old-gs old-gi old-gr err) (if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek)) (if (null (car (atoms-family 1 '("VF-LINIENZUG-MODUS")))) (progn @@ -77,50 +141,28 @@ (princ "\n TEST_LINIENZUG - VF-Linienzug Replay-Test") (princ "\n================================================================") + ;; --- Eingabe-Skript aus JSON laden --- + (setq json-datei + (strcat (getenv "DXFMAKRO") "\\tests\\testdata\\linienzug_tests.json")) + (setq daten (ssg-load-json json-datei)) + (if (null daten) + (progn + (alert (strcat "Testdaten nicht gefunden:\n" json-datei)) + (exit) + ) + ) + (setq meta (tlz-daten->meta daten)) + (setq *tlz-q* (tlz-daten->queue daten)) + (setq schritte-anz (length *tlz-q*)) + (princ (strcat "\n Testdaten: " json-datei)) + (princ (strcat "\n Eingabe-Schritte: " (itoa schritte-anz))) + (if meta (princ (strcat "\n Szenario: " (ssg-val meta "beschreibung")))) + (ssg-start "TEST_LINIENZUG" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) - ;; --- Skript der Eingaben in exakter Aufruf-Reihenfolge --- - (setq *tlz-q* - (list - (list 'A 0 0 0) ; getpoint Startpunkt der Kette - 4500.0 ; getreal Hoehe (Z) Startpunkt - "2" ; getstring AS-Seite (rechts) - "1" ; getstring Naechstes Element (Neue Linie) - (list 'P 5500 0) ; getpoint Endpunkt Linie (frei, +X, dL=5500) - 1800.0 ; getreal Hoehe (Z) Linienendpunkt - 1 ; getint Winkelwahl (45 Grad) - "2" ; getstring GF-Verteilung (alles am Einlauf) - "2" ; getstring Ist Endpunkt? (Nein) - "1" ; getstring Naechstes im VF (Horizontal) - (list 'P 900 0) ; getpoint Horizontal-Endpunkt (dL=900, hz=0) - "1" ; getstring Separator VOR? (Ja) - "1" ; getstring Separator NACH? (Ja) - "2" ; getstring Ist Endpunkt? (Nein) - "2" ; getstring Naechstes (Vario-Kurve) - 1 ; getint Kurve-Winkel (90) - "1" ; getstring Kurve-Seite (links) - "1" ; getstring Kurve-Variante (aussen) - "2" ; getstring Ist Endpunkt? (Nein) - "1" ; getstring Naechstes (Horizontal) - (list 'P 250 90) ; getpoint Horizontal-Endpunkt (dL=250, hz=90) - "2" ; getstring Separator VOR? (Nein) - "2" ; getstring Separator NACH? (Nein) - "2" ; getstring Ist Endpunkt? (Nein) - "2" ; getstring Naechstes (Vario-Kurve) - 1 ; getint Kurve-Winkel (90) - "1" ; getstring Kurve-Seite (links) - "1" ; getstring Kurve-Variante (aussen) - "3" ; getstring Ist Endpunkt? (Option 3 - Kettenende) - (list 'P 6215 180) ; getpoint Option-3-Endpunkt (dL=6215, hz=180) - 4500.0 ; getreal Hoehe (Z) Kettenende (ES) - 2 ; getint Option-3-Winkelwahl (45 Grad) - "2" ; getstring ES-Seite (rechts) - ) - ) - ;; --- Eingabe-Funktionen sichern und durch Mocks ersetzen --- ;; Punkte ueber den Produktions-Wrapper vfl-getpoint (feste 2-Arity), ;; getstring/getint/getreal (alle 1-argumentig) direkt. @@ -136,21 +178,40 @@ ;; --- Eingabe-Funktionen wiederherstellen (IMMER) --- (setq vfl-getpoint old-vgp getstring old-gs getint old-gi getreal old-gr) + (setq rest-anz (length *tlz-q*)) + (princ "\n================================================================") (if (vl-catch-all-error-p err) - (princ (strcat "\n TEST_LINIENZUG: FEHLER -> " - (vl-catch-all-error-message err))) (progn + (setq status "FEHLER") + (princ (strcat "\n TEST_LINIENZUG: FEHLER -> " + (vl-catch-all-error-message err)))) + (progn + (setq status (if (= rest-anz 0) "OK" "ABWEICHUNG")) (princ "\n TEST_LINIENZUG: Kette gebaut.") - (if *tlz-q* - (princ (strcat "\n WARNUNG: " (itoa (length *tlz-q*)) + (if (> rest-anz 0) + (princ (strcat "\n WARNUNG: " (itoa rest-anz) " Skript-Eintraege NICHT verbraucht (Ablauf weicht ab).")) (princ "\n Alle Skript-Eingaben verbraucht (Ablauf wie erwartet).")) - (princ "\n Erwartung Ist-Ziel: dX~0, dZ~0, dY~637 mm (ES_90-Seitenversatz).") + (if meta + (princ (strcat "\n Erwartung Ist-Ziel: dX~" + (itoa (ssg-val meta "erwartung_dx_mm")) ", dZ~" + (itoa (ssg-val meta "erwartung_dz_mm")) ", dY~" + (itoa (ssg-val meta "erwartung_dy_mm")) " mm (" + (ssg-val meta "erwartung_hinweis") ")."))) ) ) (princ "\n================================================================") + ;; --- Ergebnis fuer run-all als JSON-String ablegen --- + (setq *linienzug-test-results* + (strcat " {\n" + " \"test_id\": \"LZ_Standard\",\n" + " \"status\": \"" status "\",\n" + " \"schritte_gesamt\": " (itoa schritte-anz) ",\n" + " \"schritte_offen\": " (itoa rest-anz) "\n" + " }")) + (ssg-end) (princ) ) diff --git a/tests/testdata/linienzug_tests.json b/tests/testdata/linienzug_tests.json new file mode 100644 index 0000000..2acc209 --- /dev/null +++ b/tests/testdata/linienzug_tests.json @@ -0,0 +1,178 @@ +[ + { + "beschreibung": "Standard-Linienzug (Modus 1): Start Z4500 AS rechts -> Neue Linie Ab Z1800 45deg (GF am Einlauf) -> Horizontal 900 mit Separator VOR+NACH -> Vario-Kurve 90 links aussen -> Horizontal 250 -> Vario-Kurve 90 links aussen -> Kettenende (Option 3) Z4500 45deg ES rechts", + "erwartung_dx_mm": 0, + "erwartung_dy_mm": 637, + "erwartung_dz_mm": 0, + "erwartung_hinweis": "dY~637 = seitlicher Fussabdruck ES_Element_90 (Bauform, kein Baufehler)" + }, + { + "typ": "point_abs", + "wert": [0, 0, 0], + "kommentar": "getpoint Startpunkt der Kette" + }, + { + "typ": "real", + "wert": 4500.0, + "kommentar": "getreal Hoehe (Z) Startpunkt" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring AS-Seite (rechts)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Naechstes Element (Neue Linie)" + }, + { + "typ": "point_rel", + "dL": 5500, + "hz": 0, + "kommentar": "getpoint Endpunkt Linie (frei, +X, dL=5500)" + }, + { + "typ": "real", + "wert": 1800.0, + "kommentar": "getreal Hoehe (Z) Linienendpunkt" + }, + { + "typ": "int", + "wert": 1, + "kommentar": "getint Winkelwahl (45 Grad)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring GF-Verteilung (alles am Einlauf)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist Endpunkt? (Nein)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Naechstes im VF (Horizontal)" + }, + { + "typ": "point_rel", + "dL": 900, + "hz": 0, + "kommentar": "getpoint Horizontal-Endpunkt (dL=900, hz=0)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Separator VOR? (Ja)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Separator NACH? (Ja)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist Endpunkt? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes (Vario-Kurve)" + }, + { + "typ": "int", + "wert": 1, + "kommentar": "getint Kurve-Winkel (90)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Kurve-Seite (links)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Kurve-Variante (aussen)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist Endpunkt? (Nein)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Naechstes (Horizontal)" + }, + { + "typ": "point_rel", + "dL": 250, + "hz": 90, + "kommentar": "getpoint Horizontal-Endpunkt (dL=250, hz=90)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Separator VOR? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Separator NACH? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist Endpunkt? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes (Vario-Kurve)" + }, + { + "typ": "int", + "wert": 1, + "kommentar": "getint Kurve-Winkel (90)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Kurve-Seite (links)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring Kurve-Variante (aussen)" + }, + { + "typ": "string", + "wert": "3", + "kommentar": "getstring Ist Endpunkt? (Option 3 - Kettenende)" + }, + { + "typ": "point_rel", + "dL": 6215, + "hz": 180, + "kommentar": "getpoint Option-3-Endpunkt (dL=6215, hz=180)" + }, + { + "typ": "real", + "wert": 4500.0, + "kommentar": "getreal Hoehe (Z) Kettenende (ES)" + }, + { + "typ": "int", + "wert": 2, + "kommentar": "getint Option-3-Winkelwahl (45 Grad)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring ES-Seite (rechts)" + } +]