diff --git a/bin/run_tests.bat b/bin/run_tests.bat index 5d7c522..93d63bc 100644 --- a/bin/run_tests.bat +++ b/bin/run_tests.bat @@ -18,6 +18,13 @@ REM ================================================================ REM Umgebung setzen call "%~dp0setenv.bat" +REM Virtuelle Umgebung aktivieren +if exist "%DXFMAKRO%\.venv\Scripts\activate.bat" ( + call "%DXFMAKRO%\.venv\Scripts\activate.bat" +) else ( + echo WARNUNG: .venv nicht gefunden - pytest muss im PATH sein! +) + set DO_CREATE=0 set DO_CHECK=0 set CREATE_ARG= diff --git a/tests/README.md b/tests/README.md index 6cef833..f22820b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -10,13 +10,22 @@ Die Tests folgen einer **zweistufigen Architektur**: ``` BricsCAD Kommandozeile | | - | TEST_KREISEL | - | TEST_OMNIFLO_EXPORT | + | SSG_RUN_ALL_TESTS | + | (TEST_KREISEL, | + | TEST_FOERDERER, | + | TEST_KSEINAUS, | + | TEST_OMNIFLO) | | | | v v | tests/output/ | kreisel_results.json | kreisel_tests.dxf | + foerderer_results.json | + foerderer_tests.dxf | + kseinaus_results.json | + kseinaus_tests.dxf | + omniflo_results.json | + omniflo_tests.dxf | omniflo_export.csv | | bin\run_tests.bat --runall @@ -44,17 +53,26 @@ tests/ conftest.py # Gemeinsame pytest-Fixtures (Pfade, JSON/DXF-Laden) create_testbase.py # Erzeugt Basis-DXF (optional, wird nicht mehr benoetigt) requirements.txt # Python-Abhaengigkeiten (ezdxf, pytest) + test_run_all.lsp # Fuehrt alle Tests aus: C:SSG_RUN_ALL_TESTS test_kreisel.lsp # LISP-Testrunner: C:TEST_KREISEL test_kreisel.py # pytest-Validierung der Kreisel-Ergebnisse - test_omniflo.lsp # LISP-Testrunner: C:TEST_OMNIFLO_EXPORT + test_foerderer.lsp # LISP-Testrunner: C:TEST_FOERDERER + test_kseinaus.lsp # LISP-Testrunner: C:TEST_KSEINAUS + test_omniflo.lsp # LISP-Testrunner: C:TEST_OMNIFLO test_omniflo.py # pytest-Validierung der Omniflo-Ergebnisse testdata/ kreisel_tests.json # Testfall-Definitionen fuer Kreisel omniflo_tests.json # Testfall-Definitionen fuer Omniflo output/ # Ergebnisse aus BricsCAD (nicht in Git) - kreisel_results.json - kreisel_tests.dxf - omniflo_export.csv + kreisel_results.json # JSON-Ergebnisse pro Testmodul + kreisel_tests.dxf # DXF-Zeichnung pro Testmodul + foerderer_results.json + foerderer_tests.dxf + kseinaus_results.json + kseinaus_tests.dxf + omniflo_results.json + omniflo_tests.dxf + omniflo_export.csv # CSV-Export (Omniflo-spezifisch) reference/ # Abgenommene Referenzdaten (in Git) kreisel_ref.dxf ... @@ -70,22 +88,30 @@ BricsCAD starten (ueber `bin\start_briscad.bat`) und Module laden: (load (strcat (getenv "DXFMAKRO") "/Lisp/ssg_load.lsp")) ``` -Dann den gewuenschten Testrunner laden und ausfuehren: +Dann alle Tests auf einmal ausfuehren: ```lisp -;; Kreisel-Test -(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) -TEST_KREISEL - -;; Omniflo-Test -(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) -TEST_OMNIFLO_EXPORT +;; Alle Tests ausfuehren (empfohlen) +(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) +SSG_RUN_ALL_TESTS ``` -Die Testrunner: -- Lesen Testfaelle aus `testdata/*.json` -- Fuegen Bloecke per Script-Funktionen ein (ohne User-Interaktion) -- Speichern Ergebnisse nach `output/` +Oder einen einzelnen Test: + +```lisp +;; Einzeltest (z.B. Kreisel) +(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) +TEST_KREISEL +;; Ergebnisse manuell exportieren: +(kreisel:export-results (strcat (getenv "DXFMAKRO") "/tests/output")) +``` + +`SSG_RUN_ALL_TESTS` fuehrt fuer jedes Modul in `*test-module*` folgendes aus: +- Zeichnung leeren (ERASE + PURGE) +- Testdatei laden und Befehl ausfuehren +- JSON-Export aufrufen (`:export-results`) +- DXF speichern (`_tests.dxf`) +- Bei Fehler: weiter mit naechstem Test (vl-catch-all-apply) ### 2. Python-Validierung ausfuehren @@ -167,6 +193,19 @@ Fuer ein neues Modul eine neue `.lsp`-Datei erstellen nach dem Muster: ```lisp ;; test_.lsp +;; Konvention: Basisname bestimmt Befehl, DXF und Export-Funktion + +;; Export-Funktion (wird von test_run_all.lsp aufgerufen) +(defun :export-results (tests-out-dir / out-json f first) + (if (null *-test-results*) + (princ "\n Keine -Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/_results.json")) + ;; ... JSON-Array schreiben ... + ) + ) +) (defun c:TEST_ (/ ...) (ssg-start "TEST_" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) @@ -183,17 +222,19 @@ Fuer ein neues Modul eine neue `.lsp`-Datei erstellen nach dem Muster: ;; ... Script-Funktion aufrufen, Ergebnis pruefen ... ) - ;; 3. Ergebnisse als JSON speichern - (setq out-json (strcat (getenv "DXFMAKRO") "/tests/output/_results.json")) - ;; ... JSON schreiben ... - - ;; 4. DXF speichern - (command "_.SAVEAS" "DXF" out-dxf) + ;; 3. Ergebnisse in globaler Variable speichern + (setq *-test-results* (reverse results-list)) (ssg-end) ) ``` +Dann den Basisnamen in `*test-module*` (in `test_run_all.lsp`) eintragen: + +```lisp +(setq *test-module* '("kreisel" "foerderer" "kseinaus" "omniflo" "")) +``` + Wichtig: - `omni:load-json` erwartet ein **flaches JSON-Array** mit flachen Objekten (kein Nesting) - `omni:val` liest Werte aus den geladenen Eintraegen diff --git a/tests/alltests.json b/tests/alltests.json new file mode 100644 index 0000000..e355e42 --- /dev/null +++ b/tests/alltests.json @@ -0,0 +1,6 @@ +[ + { "name": "kreisel", "save": "dxf" }, + { "name": "foerderer", "save": "dwg" }, + { "name": "kseinaus", "save": null }, + { "name": "omniflo", "save": "dxf" } +] diff --git a/tests/test_foerderer.lsp b/tests/test_foerderer.lsp index 5951d57..7b489e1 100644 --- a/tests/test_foerderer.lsp +++ b/tests/test_foerderer.lsp @@ -39,6 +39,34 @@ ) +;; --- JSON-Export der Foerderer-Testergebnisse --- +(defun foerderer:export-results (tests-out-dir / out-json f first) + (if (null *foerderer-test-results*) + (princ "\n Keine Foerderer-Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/foerderer_results.json")) + (setq f (open out-json "w")) + (if f + (progn + (write-line "[" f) + (setq first T) + (foreach r *foerderer-test-results* + (if (not first) (write-line "," f)) + (write-line r f) + (setq first nil) + ) + (write-line "]" f) + (close f) + (princ (strcat "\n Ergebnisse: " out-json)) + ) + (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) + ) + ) + ) +) + + ;; ============================================================ ;; C:TEST_FOERDERER - Hauptbefehl ;; ============================================================ @@ -46,8 +74,7 @@ best-winkel L_GF L_VF y-offset hoehen-liste idx anz-gebaut anz-nicht-gebaut - results-list result-json first - tests-out-dir out-json out-dxf f + results-list test-id) ;; Bibliothek initialisieren (laedt Block-Library und extrahiert Masse) @@ -182,36 +209,8 @@ (itoa anz-nicht-gebaut) " NICHT_GEBAUT")) (princ "\n================================================================") - ;; ========================================================== - ;; Ergebnisse speichern - ;; ========================================================== - (setq tests-out-dir (strcat (getenv "DXFMAKRO") "/tests/output")) - (vl-mkdir tests-out-dir) - - ;; JSON schreiben - (setq out-json (strcat tests-out-dir "/foerderer_results.json")) - (setq f (open out-json "w")) - (if f - (progn - (write-line "[" f) - (setq results-list (reverse results-list)) - (setq first T) - (foreach r results-list - (if (not first) (write-line "," f)) - (write-line r f) - (setq first nil) - ) - (write-line "]" f) - (close f) - (princ (strcat "\n Ergebnisse: " out-json)) - ) - (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) - ) - - ;; DXF speichern - (setq out-dxf (strcat tests-out-dir "/foerderer_tests.dxf")) - (command "_.SAVEAS" "" out-dxf) - (princ (strcat "\n DXF gespeichert: " out-dxf)) + ;; Ergebnisse in globaler Variable speichern + (setq *foerderer-test-results* (reverse results-list)) (ssg-end) (princ "\n================================================================") diff --git a/tests/test_kreisel.lsp b/tests/test_kreisel.lsp index 2062fc7..cb6f7d2 100644 --- a/tests/test_kreisel.lsp +++ b/tests/test_kreisel.lsp @@ -142,12 +142,40 @@ ) +;; --- JSON-Export der Kreisel-Testergebnisse --- +(defun kreisel:export-results (tests-out-dir / out-json f first) + (if (null *kreisel-test-results*) + (princ "\n Keine Kreisel-Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/kreisel_results.json")) + (setq f (open out-json "w")) + (if f + (progn + (write-line "[" f) + (setq first T) + (foreach r *kreisel-test-results* + (if (not first) (write-line "," f)) + (write-line r f) + (setq first nil) + ) + (write-line "]" f) + (close f) + (princ (strcat "\n Ergebnisse: " out-json)) + ) + (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) + ) + ) + ) +) + + ;; ============================================================ ;; C:TEST_KREISEL - Hauptbefehl ;; ============================================================ -(defun c:TEST_KREISEL (/ tests-json-pfad testfaelle tests-out-dir - out-dxf out-json f eintrag func - result-json results-list first +(defun c:TEST_KREISEL (/ tests-json-pfad testfaelle + eintrag func + result-json results-list anzahl-ok anzahl-fehler) (ssg-start "TEST_KREISEL" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) @@ -214,34 +242,8 @@ (itoa anzahl-fehler) " Fehler")) (princ "\n================================================================") - ;; Ergebnisse speichern - (setq tests-out-dir (strcat (getenv "DXFMAKRO") "/tests/output")) - (vl-mkdir tests-out-dir) - - ;; JSON-Ergebnisse schreiben - (setq out-json (strcat tests-out-dir "/kreisel_results.json")) - (setq f (open out-json "w")) - (if f - (progn - (write-line "[" f) - (setq results-list (reverse results-list)) - (setq first T) - (foreach r results-list - (if (not first) (write-line "," f)) - (write-line r f) - (setq first nil) - ) - (write-line "]" f) - (close f) - (princ (strcat "\n Ergebnisse: " out-json)) - ) - (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) - ) - - ;; DXF speichern - (setq out-dxf (strcat tests-out-dir "/kreisel_tests.dxf")) - (command "_.SAVEAS" "" out-dxf) - (princ (strcat "\n DXF gespeichert: " out-dxf)) + ;; Ergebnisse in globaler Variable speichern + (setq *kreisel-test-results* (reverse results-list)) (ssg-end) (princ "\n================================================================") diff --git a/tests/test_kreisel.py b/tests/test_kreisel.py index 55653c2..a501e64 100644 --- a/tests/test_kreisel.py +++ b/tests/test_kreisel.py @@ -80,7 +80,7 @@ class TestKreiselGeometry: """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_")] + and e.dxf.name.startswith("KREISEL_")] expected_count = len(kreisel_testdata) assert len(kr_inserts) >= expected_count, \ f"Erwartet mind. {expected_count} KR_-Bloecke, gefunden: {len(kr_inserts)}" @@ -88,7 +88,7 @@ class TestKreiselGeometry: 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_"): + if not block.name.startswith("KREISEL_"): continue circles = [e for e in block if e.dxftype() == "CIRCLE"] for c in circles: diff --git a/tests/test_ks.lsp b/tests/test_kseinaus.lsp similarity index 79% rename from tests/test_ks.lsp rename to tests/test_kseinaus.lsp index a00db6e..aa0fecf 100644 --- a/tests/test_ks.lsp +++ b/tests/test_kseinaus.lsp @@ -1,5 +1,5 @@ ;; ============================================================ -;; test_ks.lsp - Automatischer Integrationstest fuer KS_EIN/KS_AUS +;; test_kseinaus.lsp - Automatischer Integrationstest fuer KS_EIN/KS_AUS ;; ;; Fuegt alle Vario-Bloecke in 3 Gruppen ein, jeweils 2 Reihen: ;; Gruppe 1: Stationaere Elemente (AUS, EIN, Separator, Umlenk, Motor) @@ -12,21 +12,21 @@ ;; Luecke von 400mm zwischen den Reihen ;; ;; Speichert: -;; - tests/output/ks_results.json (Ergebnisse) -;; - tests/output/ks_tests.dxf (Zeichnung) +;; - tests/output/kseinaus_results.json (Ergebnisse) +;; - tests/output/kseinaus_tests.dxf (Zeichnung) ;; ;; Voraussetzungen: ;; - SSG_LIB geladen (VarioFoerderer.lsp, ssg_core.lsp) ;; - Umgebungsvariable DXFMAKRO gesetzt ;; ;; Aufruf in BricsCAD: -;; (load (strcat (getenv "DXFMAKRO") "/tests/test_ks.lsp")) +;; (load (strcat (getenv "DXFMAKRO") "/tests/test_kseinaus.lsp")) ;; TEST_KSEINAUS ;; ============================================================ ;; --- Ergebnis eines Testfalls als JSON-String erzeugen --- -(defun ks:test-result-json (test-id block-name gruppe ks-type status / +(defun kseinaus:test-result-json (test-id block-name gruppe ks-type status / json) (setq json (strcat " {\n" " \"test_id\": \"" test-id "\",\n" @@ -41,7 +41,7 @@ ;; --- Eine Reihe Bloecke einfuegen und Ergebnisse sammeln --- ;; Rueckgabe: (naechste-y-pos . results-list) -(defun ks:test-reihe (namen x-start y-start z-offset y-abstand y-luecke +(defun kseinaus:test-reihe (namen x-start y-start z-offset y-abstand y-luecke gruppe results-in / bname block-obj ks-data ks-ein ks-aus insert-pt offset-vec y-pos idx @@ -74,13 +74,13 @@ (vlax-3D-point offset-vec)) (princ (strcat "\n " (itoa idx) ". " bname " OK")) (setq results-out (cons - (ks:test-result-json test-id bname gruppe "KS_EIN" "OK") + (kseinaus:test-result-json test-id bname gruppe "KS_EIN" "OK") results-out)) ) (progn (princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_EIN fehlt!")) (setq results-out (cons - (ks:test-result-json test-id bname gruppe "KS_EIN" "KS_FEHLT") + (kseinaus:test-result-json test-id bname gruppe "KS_EIN" "KS_FEHLT") results-out)) ) ) @@ -114,13 +114,13 @@ (vlax-3D-point offset-vec)) (princ (strcat "\n " (itoa idx) ". " bname " OK")) (setq results-out (cons - (ks:test-result-json test-id bname gruppe "KS_AUS" "OK") + (kseinaus:test-result-json test-id bname gruppe "KS_AUS" "OK") results-out)) ) (progn (princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_AUS fehlt!")) (setq results-out (cons - (ks:test-result-json test-id bname gruppe "KS_AUS" "KS_FEHLT") + (kseinaus:test-result-json test-id bname gruppe "KS_AUS" "KS_FEHLT") results-out)) ) ) @@ -132,14 +132,41 @@ ) +;; --- JSON-Export der KS-Testergebnisse --- +(defun kseinaus:export-results (tests-out-dir / out-json f first) + (if (null *kseinaus-test-results*) + (princ "\n Keine KS-Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/kseinaus_results.json")) + (setq f (open out-json "w")) + (if f + (progn + (write-line "[" f) + (setq first T) + (foreach r *kseinaus-test-results* + (if (not first) (write-line "," f)) + (write-line r f) + (setq first nil) + ) + (write-line "]" f) + (close f) + (princ (strcat "\n Ergebnisse: " out-json)) + ) + (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) + ) + ) + ) +) + + ;; ============================================================ ;; C:TEST_KSEINAUS - Hauptbefehl ;; ============================================================ (defun c:TEST_KSEINAUS ( / stationen boegen-auf-liste boegen-ab-liste bname y-pos y-abstand y-luecke z-bogen results-list reihe-result - anz-ok anz-fehlt - tests-out-dir out-json out-dxf f first) + anz-ok anz-fehlt) ;; Bibliothek initialisieren (if (not *lib-initialized*) @@ -189,21 +216,21 @@ ;; Gruppe 1: Stationaere Elemente bei X=0, Z=0 (princ "\n\n GRUPPE 1: Stationaere Elemente (Z=0)") - (setq reihe-result (ks:test-reihe stationen 0 0 0 y-abstand y-luecke + (setq reihe-result (kseinaus:test-reihe stationen 0 0 0 y-abstand y-luecke "Stationen" results-list)) (setq y-pos (car reihe-result)) (setq results-list (cdr reihe-result)) ;; Gruppe 2: Boegen aufwaerts bei X=3000, Z=z-bogen (princ (strcat "\n\n GRUPPE 2: Boegen aufwaerts (Z=" (rtos z-bogen 2 0) ")")) - (setq reihe-result (ks:test-reihe boegen-auf-liste 3000 0 z-bogen y-abstand y-luecke + (setq reihe-result (kseinaus:test-reihe boegen-auf-liste 3000 0 z-bogen y-abstand y-luecke "Boegen_Auf" results-list)) (setq y-pos (car reihe-result)) (setq results-list (cdr reihe-result)) ;; Gruppe 3: Boegen abwaerts bei X=6000, Z=z-bogen (princ (strcat "\n\n GRUPPE 3: Boegen abwaerts (Z=" (rtos z-bogen 2 0) ")")) - (setq reihe-result (ks:test-reihe boegen-ab-liste 6000 0 z-bogen y-abstand y-luecke + (setq reihe-result (kseinaus:test-reihe boegen-ab-liste 6000 0 z-bogen y-abstand y-luecke "Boegen_Ab" results-list)) (setq y-pos (car reihe-result)) (setq results-list (cdr reihe-result)) @@ -223,36 +250,8 @@ (itoa anz-fehlt) " KS fehlt")) (princ "\n================================================================") - ;; ========================================================== - ;; Ergebnisse speichern - ;; ========================================================== - (setq tests-out-dir (strcat (getenv "DXFMAKRO") "/tests/output")) - (vl-mkdir tests-out-dir) - - ;; JSON schreiben - (setq out-json (strcat tests-out-dir "/ks_results.json")) - (setq f (open out-json "w")) - (if f - (progn - (write-line "[" f) - (setq results-list (reverse results-list)) - (setq first T) - (foreach r results-list - (if (not first) (write-line "," f)) - (write-line r f) - (setq first nil) - ) - (write-line "]" f) - (close f) - (princ (strcat "\n Ergebnisse: " out-json)) - ) - (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) - ) - - ;; DXF speichern - (setq out-dxf (strcat tests-out-dir "/ks_tests.dxf")) - (command "_.SAVEAS" "" out-dxf) - (princ (strcat "\n DXF gespeichert: " out-dxf)) + ;; Ergebnisse in globaler Variable speichern + (setq *kseinaus-test-results* (reverse results-list)) (ssg-end) (princ "\n================================================================") diff --git a/tests/test_omniflo.lsp b/tests/test_omniflo.lsp index 25f6e48..c5c0d6b 100644 --- a/tests/test_omniflo.lsp +++ b/tests/test_omniflo.lsp @@ -12,7 +12,7 @@ ;; ;; Aufruf in BricsCAD: ;; (load "tests/test_omniflo.lsp") -;; TEST_OMNIFLO_EXPORT +;; TEST_OMNIFLO ;; ============================================================ @@ -58,23 +58,65 @@ ) +;; --- Ergebnis eines Omniflo-Testfalls als JSON-String erzeugen --- +(defun omniflo:test-result-json (test-id sivasnr description hoehe status / + json) + (setq json (strcat " {\n" + " \"test_id\": \"" test-id "\",\n" + " \"sivasnr\": \"" (if sivasnr sivasnr "") "\",\n" + " \"description\": \"" (if description description "") "\",\n" + " \"hoehe\": \"" (if hoehe hoehe "") "\",\n" + " \"status\": \"" status "\"\n" + " }")) + json +) + + +;; --- JSON-Export der Omniflo-Testergebnisse --- +(defun omniflo:export-results (tests-out-dir / out-json f first) + (if (null *omniflo-test-results*) + (princ "\n Keine Omniflo-Ergebnisse vorhanden.") + (progn + (vl-mkdir tests-out-dir) + (setq out-json (strcat tests-out-dir "/omniflo_results.json")) + (setq f (open out-json "w")) + (if f + (progn + (write-line "[" f) + (setq first T) + (foreach r *omniflo-test-results* + (if (not first) (write-line "," f)) + (write-line r f) + (setq first nil) + ) + (write-line "]" f) + (close f) + (princ (strcat "\n Ergebnisse: " out-json)) + ) + (princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")) + ) + ) + ) +) + + ;; ============================================================ -;; C:TEST_OMNIFLO_EXPORT +;; C:TEST_OMNIFLO ;; ;; Liest omniflo_tests.json, fuegt alle Testbloecke ein, ;; exportiert CSV nach tests/output/. ;; ============================================================ -(defun c:TEST_OMNIFLO_EXPORT (/ tests-json-pfad testfaelle +(defun c:TEST_OMNIFLO (/ tests-json-pfad testfaelle x-pos x-schritt idx eintrag sivasnr hoehe-str drehung-str - insert-pt anzahl-ok anzahl-fehler - tests-out-dir old-results) + description insert-pt anzahl-ok anzahl-fehler + results-list tests-out-dir old-results) (if (not *lib-initialized*) (init-bibliothek) ) - (ssg-start "TEST_OMNIFLO_EXPORT" + (ssg-start "TEST_OMNIFLO" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) @@ -101,7 +143,7 @@ ) (progn (princ "\n================================================================") - (princ "\n TEST_OMNIFLO_EXPORT") + (princ "\n TEST_OMNIFLO") (princ (strcat "\n " (itoa (length testfaelle)) " Testfaelle geladen")) (princ "\n================================================================") @@ -110,6 +152,7 @@ (setq x-schritt 200.0) (setq anzahl-ok 0) (setq anzahl-fehler 0) + (setq results-list nil) (setq idx 0) (foreach eintrag testfaelle @@ -125,16 +168,29 @@ (if (numberp drehung-str) (setq drehung-str (rtos drehung-str 2 1)) ) + (setq description (omni:val eintrag "description")) (setq insert-pt (list x-pos 0.0 (atof hoehe-str))) (princ (strcat "\n " (itoa idx) ". " - (or (omni:val eintrag "description") sivasnr) + (if description description (if sivasnr sivasnr "?")) " -> (" (rtos x-pos 2 0) ", 0, " hoehe-str ")")) (if (omni:test-insert sivasnr insert-pt hoehe-str drehung-str) - (setq anzahl-ok (1+ anzahl-ok)) - (setq anzahl-fehler (1+ anzahl-fehler)) + (progn + (setq anzahl-ok (1+ anzahl-ok)) + (setq results-list (cons + (omniflo:test-result-json (strcat "OMNI_" (itoa idx)) + sivasnr description hoehe-str "OK") + results-list)) + ) + (progn + (setq anzahl-fehler (1+ anzahl-fehler)) + (setq results-list (cons + (omniflo:test-result-json (strcat "OMNI_" (itoa idx)) + sivasnr description hoehe-str "FEHLER") + results-list)) + ) ) (setq x-pos (+ x-pos x-schritt)) @@ -146,6 +202,9 @@ " OK, " (itoa anzahl-fehler) " Fehler")) (princ "\n================================================================") + ;; Ergebnisse in globaler Variable speichern + (setq *omniflo-test-results* (reverse results-list)) + ;; CSV-Export nach tests/output/ (setq tests-out-dir (strcat (getenv "DXFMAKRO") "/tests/output")) @@ -162,7 +221,7 @@ (ssg-end) (princ "\n================================================================") - (princ "\n TEST_OMNIFLO_EXPORT abgeschlossen.") + (princ "\n TEST_OMNIFLO abgeschlossen.") (princ (strcat "\n CSV: " tests-out-dir "/omniflo_export.csv")) (princ "\n================================================================") (princ) diff --git a/tests/test_run_all.lsp b/tests/test_run_all.lsp index a669c92..a7da176 100644 --- a/tests/test_run_all.lsp +++ b/tests/test_run_all.lsp @@ -1,13 +1,17 @@ ;; ============================================================ ;; test_run_all.lsp - Fuehrt alle LISP-Tests nacheinander aus ;; -;; Laedt und startet: -;; 1. TEST_KREISEL -;; 2. TEST_FOERDERER -;; 3. TEST_KSEINAUS -;; 4. TEST_OMNIFLO_EXPORT +;; Laedt und startet alle in tests/alltests.json registrierten Tests. +;; Konvention: Aus Basisname leiten sich ab: +;; Datei: test_.lsp +;; Befehl: TEST_ +;; Export: :export-results ;; -;; Ergebnisse werden jeweils in tests/output/ gespeichert. +;; Ergebnisse werden in tests/output/ gespeichert: +;; JSON: immer (_results.json, via :export-results) +;; DXF: wenn "save": "dxf" in alltests.json +;; DWG: wenn "save": "dwg" in alltests.json +;; keins: wenn "save" fehlt, null oder leer ;; ;; Voraussetzungen: ;; - SSG_LIB geladen @@ -18,49 +22,179 @@ ;; SSG_RUN_ALL_TESTS ;; ============================================================ -(defun c:SSG_RUN_ALL_TESTS ( / tests-pfad test-dateien test-befehle - datei befehl idx anz) - (setq tests-pfad (strcat (getenv "DXFMAKRO") "/tests")) +;; --- Hilfsfunktion: String-Wert aus JSON-Objekt-Zeile lesen --- +;; Sucht "key": "value" in obj-str und gibt value zurueck. +;; Rueckgabe: String (nicht leer) oder nil (key fehlt, null, leer). +(defun alltests:get-str (obj-str key / pat pos val-start val-end val) + (setq pat (strcat "\"" key "\": \"")) + (setq pos (vl-string-search pat obj-str)) + (if pos + (progn + (setq val-start (+ pos (strlen pat))) ;; 0-basiert + (setq val-end (vl-string-search "\"" obj-str val-start)) + (if val-end + (progn + (setq val (substr obj-str (1+ val-start) (- val-end val-start))) + (if (> (strlen val) 0) val nil) + ) + ) + ) + ) +) - ;; Test-Dateien und zugehoerige Befehle - (setq test-dateien (list - (strcat tests-pfad "/test_kreisel.lsp") - (strcat tests-pfad "/test_foerderer.lsp") - (strcat tests-pfad "/test_ks.lsp") - (strcat tests-pfad "/test_omniflo.lsp") - )) - (setq test-befehle (list - "TEST_KREISEL" - "TEST_FOERDERER" - "TEST_KSEINAUS" - "TEST_OMNIFLO_EXPORT" - )) - (setq anz (length test-dateien)) +;; --- Testliste aus tests/alltests.json laden --- +;; Erwartet ein JSON-Array, je Zeile ein Objekt: { "name": "...", "save": "..." } +;; "save" kann "dxf", "dwg", null oder fehlen (= kein Speichern). +;; Rueckgabe: Liste von Assoc-Listen (("name" . "kreisel") ("save" . "dxf")) +(defun alltests:load (tests-pfad / json-datei f zeile ergebnis name save-fmt) + (setq json-datei (strcat tests-pfad "/alltests.json")) + (if (not (findfile json-datei)) + (progn + (princ (strcat "\n FEHLER: " json-datei " nicht gefunden!")) + nil + ) + (progn + (setq f (open json-datei "r")) + (if (null f) + (progn + (princ (strcat "\n FEHLER: Kann " json-datei " nicht oeffnen!")) + nil + ) + (progn + (setq ergebnis nil) + (while (setq zeile (read-line f)) + ;; Jede Zeile mit "name" ist ein Test-Eintrag (ein Objekt pro Zeile) + (if (vl-string-search "\"name\"" zeile) + (progn + (setq name (alltests:get-str zeile "name")) + (setq save-fmt (alltests:get-str zeile "save")) + (if name + (setq ergebnis (cons + (list (cons "name" name) (cons "save" save-fmt)) + ergebnis)) + ) + ) + ) + ) + (close f) + (reverse ergebnis) + ) + ) + ) + ) +) + + +;; --- Konventionsbasierte Namen aus Basisname ableiten --- +;; Gibt Assoc-Liste zurueck: datei, befehl, export-fn +(defun test-module-names (name tests-pfad) + (list + (cons "datei" (strcat tests-pfad "/test_" name ".lsp")) + (cons "befehl" (strcat "TEST_" (strcase name))) + (cons "export-fn" (read (strcat name ":export-results"))) + ) +) + + +(defun c:SSG_RUN_ALL_TESTS ( / tests-pfad tests-out-dir + idx anz entry name save-fmt + namen befehl datei export-fn + out-path test-result) + + (setq tests-pfad (strcat (getenv "DXFMAKRO") "/tests")) + (setq tests-out-dir (strcat tests-pfad "/output")) + (vl-mkdir tests-out-dir) + + ;; Testliste aus alltests.json laden + (setq *test-module* (alltests:load tests-pfad)) + (if (null *test-module*) + (progn + (princ "\n FEHLER: Keine Test-Module geladen. Abbruch.") + (exit) + ) + ) + + (setq anz (length *test-module*)) (setq idx 0) (princ "\n") (princ "\n================================================================") (princ "\n SSG_RUN_ALL_TESTS") - (princ (strcat "\n " (itoa anz) " Testmodule")) + (princ (strcat "\n " (itoa anz) " Testmodule (aus alltests.json)")) (princ "\n================================================================") ;; Tests laden und ausfuehren - (mapcar - '(lambda (datei befehl) - (setq idx (1+ idx)) - (princ (strcat "\n\n>>> " (itoa idx) "/" (itoa anz) ": " befehl " <<<")) - (if (findfile datei) - (progn - (load datei) - (eval (list (read (strcat "c:" befehl)))) - ) - (princ (strcat "\n WARNUNG: " datei " nicht gefunden - uebersprungen")) - ) + ;; Vor jedem Test werden alle Entities geloescht, damit jeder + ;; Testlauf eine eigene saubere Zeichnung erzeugt. + (foreach entry *test-module* + (setq idx (1+ idx)) + (setq name (cdr (assoc "name" entry))) + (setq save-fmt (cdr (assoc "save" entry))) + + ;; Namen aus Konvention ableiten + (setq namen (test-module-names name tests-pfad)) + (setq datei (cdr (assoc "datei" namen))) + (setq befehl (cdr (assoc "befehl" namen))) + (setq export-fn (cdr (assoc "export-fn" namen))) + + (princ (strcat "\n\n>>> " (itoa idx) "/" (itoa anz) ": " befehl " <<<")) + (if save-fmt + (princ (strcat " [save: " save-fmt "]")) + (princ " [kein Speichern]") + ) + + ;; Zeichnung leeren fuer sauberen Testlauf + (if (ssget "_X") + (command "_.ERASE" "_ALL" "") + ) + ;; PURGE mehrfach, da verschachtelte Block-Referenzen + ;; erst nach mehreren Durchlaeufen entfernt werden + (repeat 5 + (command "_.PURGE" "_ALL" "" "_N") + ) + ;; Block-Library-Flag zuruecksetzen + (setq *lib-initialized* nil) + + (if (findfile datei) + (progn + (load datei) + ;; Test mit Fehlerbehandlung ausfuehren + (setq test-result + (vl-catch-all-apply + '(lambda () + (eval (list (read (strcat "c:" befehl)))) + ) + nil + ) + ) + (if (vl-catch-all-error-p test-result) + (princ (strcat "\n FEHLER in " befehl ": " + (vl-catch-all-error-message test-result))) + ) + + ;; JSON-Export (immer) + (apply export-fn (list tests-out-dir)) + + ;; Datei speichern je nach save-fmt aus alltests.json + (setq out-path (strcat tests-out-dir "/" name "_tests")) + (cond + ((and save-fmt (= (strcase save-fmt) "DXF")) + (command "_.DXFOUT" out-path 6) + (princ (strcat "\n DXF gespeichert: " out-path ".dxf")) + ) + ((and save-fmt (= (strcase save-fmt) "DWG")) + (command "_.-SAVEAS" "2013" (strcat out-path ".dwg")) + (princ (strcat "\n DWG gespeichert: " out-path ".dwg")) + ) + (T + (princ "\n (kein Speichern der Zeichnung)") + ) + ) + ) + (princ (strcat "\n WARNUNG: " datei " nicht gefunden - uebersprungen")) ) - test-dateien - test-befehle ) (princ "\n\n================================================================") diff --git a/tests/testdata/kreisel_tests.json b/tests/testdata/kreisel_tests.json index bc8407f..4842ee7 100644 --- a/tests/testdata/kreisel_tests.json +++ b/tests/testdata/kreisel_tests.json @@ -1,50 +1,37 @@ [ { - "id": "KR_Insert_Horiz_ObenUnten", + "id": "KR_Kreuz_Q1_0Grad", "function": "insert", "x": 500, - "y": 5000, + "y": 500, "z": 2500, - "abstand": 4200, - "rotation": 270.0, + "abstand": 2000, + "rotation": 0.0, "typ": "STANDARD", "expect_block_prefix": "KREISEL_", "expect_hoehe": "2500", "expect_kreiselart": "STANDARD" }, { - "id": "KR_Insert_Horiz_UntenOben", + "id": "KR_Kreuz_Q2_90Grad", "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, + "x": -500, "y": 500, "z": 2500, - "abstand": 4200, - "rotation": 0.0, - "typ": "PIN", + "abstand": 3000, + "rotation": 90.0, + "typ": "STANDARD", "expect_block_prefix": "KREISEL_", "expect_hoehe": "2500", - "expect_kreiselart": "PIN" + "expect_kreiselart": "STANDARD" }, { - "id": "KR_Insert_Vert_RechtsLinks", + "id": "KR_Kreuz_Q3_180Grad", "function": "insert", - "x": 5000, - "y": 1500, + "x": -500, + "y": -500, "z": 2500, - "abstand": 4200, + "abstand": 4000, "rotation": 180.0, "typ": "STANDARD", "expect_block_prefix": "KREISEL_", @@ -52,58 +39,68 @@ "expect_kreiselart": "STANDARD" }, { - "id": "KR_Insert_Schraeg", + "id": "KR_Kreuz_Q4_270Grad", "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, + "x": 500, + "y": -500, + "z": 2500, + "abstand": 5000, + "rotation": 270.0, "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", + "id": "KR_Schraeg_Q1_30Grad", + "function": "insert", + "x": 3000, + "y": 3000, + "z": 3000, + "abstand": 3000, + "rotation": 30.0, + "typ": "STANDARD", "expect_block_prefix": "KREISEL_", "expect_hoehe": "3000", + "expect_kreiselart": "STANDARD" + }, + { + "id": "KR_Pin_Q1_0Grad", + "function": "insert", + "x": 500, + "y": 6000, + "z": 1500, + "abstand": 3000, + "rotation": 0.0, + "typ": "PIN", + "expect_block_prefix": "KREISEL_", + "expect_hoehe": "1500", "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", + "id": "KR_Pin_Q1_90Grad", + "function": "insert", + "x": -500, + "y": 6500, + "z": 1500, + "abstand": 4000, + "rotation": 90.0, + "typ": "PIN", "expect_block_prefix": "KREISEL_", - "expect_hoehe": "2000", - "expect_kreiselart": "STANDARD" + "expect_hoehe": "1500", + "expect_kreiselart": "PIN" + }, + { + "id": "KR_Pin_Q1_30Grad_Schraeg", + "function": "insert", + "x": 3000, + "y": 8000, + "z": 1500, + "abstand": 3000, + "rotation": 30.0, + "typ": "PIN", + "expect_block_prefix": "KREISEL_", + "expect_hoehe": "1500", + "expect_kreiselart": "PIN" } ]