;; ============================================================ ;; test_omniflo_strecke.lsp - Integrationstest Omniflo-Streckenzug ;; ;; Baut aus tests/testdata/omniflo_strecke_tests.json einen verketteten ;; Streckenzug auf: ;; 4 Geraden -> 180-Grad-Kurve (4x 45-Grad-Bogen) -> 4 Geraden ;; ;; Jedes Element traegt bereits seine absolute Platzierung (x, y, drehung) ;; sowie Endpunkt (x_ende, y_ende). Die Elemente sind lueckenlos verkettet ;; (Ende[i] = Anfang[i+1]), sodass eine durchgehende U-foermige Strecke ;; entsteht. ;; ;; - Boegen (type "bogen"): DXF aus DXFM_OMNIFLO an (x,y) mit Drehung ;; einfuegen (wie test_omniflo.lsp). ;; - Geraden (type "gerade"): echter Aluprofil-Block ueber den skript- ;; faehigen Kern omni:make-gerade (aus OmniModulInsert.lsp). Fehlt die ;; Quell-.dwg (kein AP110.dwg im Blockpfad), werden Ersatz-Attribute ;; verwendet, sodass dennoch ein Compound-Block (Linie + ATTDEFs) statt ;; einer nackten Linie entsteht. ;; ;; Ergebnisse -> tests/output/omniflo_strecke_results.json ;; (via omniflo_strecke:export-results, aufgerufen von SSG_RUN_ALL_TESTS ;; oder manuell). ;; ;; Voraussetzungen: ;; - SSG_LIB geladen (ssg_core.lsp, OmniModulInsert.lsp) ;; - Umgebungsvariablen DXFMAKRO, DXFM_OMNIFLO gesetzt ;; ;; Aufruf in BricsCAD: ;; (load "tests/test_omniflo_strecke.lsp") ;; TEST_OMNIFLO_STRECKE ;; ;; Debug: Detail-Ausgaben (pro Element, Diagnosen) laufen ueber die ;; ssg_dbg-Routinen und landen NICHT im BricsCAD-Fenster, sondern in einer ;; .dbg-Datei. Per Default ist das aus (keine Datei). Zum Einschalten vor ;; dem Testlauf: ;; (setq *omniflo-strecke-dbg* T) ;; Die Datei "omniflo_strecke.dbg" entsteht dann im DXFM_LOG-Verzeichnis. ;; Voraussetzung: ssg_dbg.lsp ist geladen (Teil von SSG_LIB). ;; ============================================================ ;; Debug-Schalter fuer diesen Test (Default: aus). Ein bereits gesetztes T ;; wird beim erneuten Laden der Datei NICHT ueberschrieben. (if (null *omniflo-strecke-dbg*) (setq *omniflo-strecke-dbg* nil)) ;; --- Bogen-DXF non-interaktiv an gegebenem Punkt einfuegen --- (defun omnistr:insert-bogen (sivasnr-str insert-pt hoehe-str drehung-str / dxf-pfad omniflo-pfad blockEnt angleDeg) (dbgf "omnistr:insert-bogen") (dbgmsg (strcat "sivasnr=" (if sivasnr-str sivasnr-str "nil") " drehung=" (if drehung-str drehung-str "nil"))) (setq omniflo-pfad (getenv "DXFM_OMNIFLO")) (dbgreturn (if (null omniflo-pfad) (progn ;; Konfigurationsfehler: bleibt bewusst im Fenster sichtbar (princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: DXFM_OMNIFLO nicht gesetzt!") nil ) (progn (setq dxf-pfad (strcat omniflo-pfad "/" sivasnr-str ".dxf")) (if (not (findfile dxf-pfad)) (progn (dbgmsg (strcat "WARNUNG: DXF nicht gefunden: " dxf-pfad)) nil ) (progn (setq angleDeg (if drehung-str (atof drehung-str) 0.0)) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (command "_.INSERT" dxf-pfad insert-pt "" "" angleDeg) (setq blockEnt (entlast)) (if (and blockEnt (= (cdr (assoc 0 (entget blockEnt))) "INSERT")) (ssg-attrib-set-on blockEnt (list (cons "HOEHE" (if hoehe-str hoehe-str "2000")) (cons "DREHUNG" (if drehung-str drehung-str "0")))) ) blockEnt ) ) ) ) ) ) ;; --- Gerade non-interaktiv als echten Aluprofil-Block erzeugen --- ;; Nutzt den skriptfaehigen Kern omni:make-gerade aus OmniModulInsert.lsp. ;; profil = Profiltyp (z.B. "AP110") ;; pt-anf = Anfangspunkt, pt-end = Endpunkt (bestimmen Laenge + Drehung) ;; hoehe-str / drehung-str = Attributwerte HOEHE/DREHUNG ;; Rueckgabe: Block-Entity oder nil. (defun omnistr:build-gerade (profil pt-anf pt-end hoehe-str drehung-str / srcAttribs textHeight textGap blockEnt) (dbgf "omnistr:build-gerade") (dbgmsg (strcat "profil=" (if profil profil "nil") " hoehe=" (if hoehe-str hoehe-str "nil") " drehung=" (if drehung-str drehung-str "nil"))) (dbgreturn (if (null (car (atoms-family 1 '("OMNI:MAKE-GERADE")))) (progn ;; Precondition-Fehler (Modul nicht geladen): bleibt im Fenster sichtbar (princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: omni:make-gerade nicht geladen (OmniModulInsert.lsp)!") nil ) (progn (setq textHeight (ssg-cfg-or "omniflo" "text_height" 100.0)) (setq textGap (ssg-cfg-or "omniflo" "text_gap" 20.0)) ;; Quell-Attribute lesen; falls keine .dwg vorhanden, Ersatz erzeugen (setq srcAttribs (omni:read-src-attribs profil)) (if (null srcAttribs) (progn (dbgmsg (strcat "keine Quell-.dwg fuer " profil " - Ersatz-Attribute")) (setq srcAttribs (list (cons "PROFILTYP" profil) (cons "HOEHE" (if hoehe-str hoehe-str "2000")) (cons "ID" ""))) ) ) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (setq blockEnt (omni:make-gerade profil pt-anf pt-end srcAttribs textHeight textGap nil)) (if (and blockEnt (= (cdr (assoc 0 (entget blockEnt))) "INSERT")) (ssg-attrib-set-on blockEnt (list (cons "HOEHE" (if hoehe-str hoehe-str "2000")) (cons "DREHUNG" (if drehung-str drehung-str "0")))) ) blockEnt ) ) ) ) ;; --- Ergebnis eines Streckenelements als JSON-String erzeugen --- (defun omnistr:test-result-json (test-id seq typ description status / ) (strcat " {\n" " \"test_id\": \"" test-id "\",\n" " \"seq\": " (itoa seq) ",\n" " \"type\": \"" (if typ typ "") "\",\n" " \"description\": \"" (if description description "") "\",\n" " \"status\": \"" status "\"\n" " }") ) ;; --- JSON-Export der Streckenzug-Testergebnisse --- (defun omniflo_strecke:export-results (tests-out-dir / out-json f first) (if (null *omniflo-strecke-test-results*) (princ "\n Keine Streckenzug-Ergebnisse vorhanden.") (progn (vl-mkdir tests-out-dir) (setq out-json (strcat tests-out-dir "/omniflo_strecke_results.json")) (setq f (open out-json "w")) (if f (progn (write-line "[" f) (setq first T) (foreach r *omniflo-strecke-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_STRECKE ;; ;; Liest omniflo_strecke_tests.json und baut den Streckenzug auf. ;; ============================================================ (defun c:TEST_OMNIFLO_STRECKE (/ tests-json-pfad elemente idx eintrag typ sivasnr profil hoehe-str drehung-str description x-val y-val xe-val ye-val seq insert-pt pt-end anzahl-ok anzahl-fehler results-list ergebnis) (ssg-start "TEST_OMNIFLO_STRECKE" '(("OSMODE") ("ATTREQ") ("ATTDIA") ("CLAYER"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) ;; Debug-Datei nur bei aktivem Schalter anlegen (siehe Kopf der Datei) (if *omniflo-strecke-dbg* (dbgopen "omniflo_strecke.dbg" "DXFM_LOG")) (dbgf "TEST_OMNIFLO_STRECKE") (setq tests-json-pfad (strcat (getenv "DXFMAKRO") "/tests/testdata/omniflo_strecke_tests.json")) (if (not (findfile tests-json-pfad)) (progn (princ (strcat "\n[TEST_OMNIFLO_STRECKE] FEHLER: Testdaten nicht gefunden: " tests-json-pfad)) (dbgmsg (strcat "ABBRUCH: Testdaten nicht gefunden: " tests-json-pfad)) (ssg-end) (if *omniflo-strecke-dbg* (progn (dbgreturn nil) (dbgclose))) (princ) ) (progn (setq elemente (ssg-load-json tests-json-pfad)) (if (null elemente) (progn (princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: Testdaten konnten nicht geladen werden.") (dbgmsg "ABBRUCH: Testdaten konnten nicht geladen werden.") (ssg-end) (if *omniflo-strecke-dbg* (progn (dbgreturn nil) (dbgclose))) (princ) ) (progn (princ "\n================================================================") (princ "\n TEST_OMNIFLO_STRECKE") (princ (strcat "\n " (itoa (length elemente)) " Streckenelemente geladen")) (princ "\n================================================================") (setq anzahl-ok 0 anzahl-fehler 0 results-list nil idx 0) (foreach eintrag elemente (setq idx (1+ idx)) (setq seq (ssg-val eintrag "seq")) (if (null seq) (setq seq idx)) (if (not (numberp seq)) (setq seq (atoi (vl-princ-to-string seq)))) (setq typ (ssg-val eintrag "type")) (setq description (ssg-val eintrag "description")) (setq hoehe-str (ssg-val eintrag "hoehe")) (if (null hoehe-str) (setq hoehe-str "2000")) (if (numberp hoehe-str) (setq hoehe-str (rtos hoehe-str 2 0))) (setq drehung-str (ssg-val eintrag "drehung")) (if (null drehung-str) (setq drehung-str "0")) (if (numberp drehung-str) (setq drehung-str (rtos drehung-str 2 4))) ;; Anfangs- und Endpunkt lesen (setq x-val (ssg-val eintrag "x") y-val (ssg-val eintrag "y") xe-val (ssg-val eintrag "x_ende") ye-val (ssg-val eintrag "y_ende")) (if (null x-val) (setq x-val 0.0)) (if (null y-val) (setq y-val 0.0)) (if (null xe-val) (setq xe-val x-val)) (if (null ye-val) (setq ye-val y-val)) (if (not (numberp x-val)) (setq x-val (atof x-val))) (if (not (numberp y-val)) (setq y-val (atof y-val))) (if (not (numberp xe-val)) (setq xe-val (atof xe-val))) (if (not (numberp ye-val)) (setq ye-val (atof ye-val))) (setq insert-pt (list x-val y-val (atof hoehe-str))) (setq pt-end (list xe-val ye-val (atof hoehe-str))) (dbgmsg (strcat (itoa seq) ". " (if typ typ "?") ": " (if description description "") " -> (" (rtos x-val 2 0) ", " (rtos y-val 2 0) ") @ " drehung-str)) ;; Element aufbauen je nach Typ (setq ergebnis (cond ((= typ "bogen") (setq sivasnr (ssg-val eintrag "sivasnr")) (omnistr:insert-bogen sivasnr insert-pt hoehe-str drehung-str)) ((= typ "gerade") (setq profil (ssg-val eintrag "profil")) (if (null profil) (setq profil "AP110")) (omnistr:build-gerade profil insert-pt pt-end hoehe-str drehung-str)) (T (dbgmsg (strcat "WARNUNG: unbekannter Typ '" (if typ typ "nil") "'")) nil) ) ) (dbgmsg (strcat " -> " (if ergebnis "OK ent=" "FEHLER") (if ergebnis (vl-princ-to-string ergebnis) ""))) (if ergebnis (progn (setq anzahl-ok (1+ anzahl-ok)) (setq results-list (cons (omnistr:test-result-json (strcat "STRECKE_" (itoa seq)) seq typ description "OK") results-list)) ) (progn (setq anzahl-fehler (1+ anzahl-fehler)) (setq results-list (cons (omnistr:test-result-json (strcat "STRECKE_" (itoa seq)) seq typ description "FEHLER") results-list)) ) ) ) (princ "\n================================================================") (princ (strcat "\n Aufgebaut: " (itoa anzahl-ok) " OK, " (itoa anzahl-fehler) " Fehler")) (princ "\n================================================================") (dbgmsg (strcat "Aufgebaut: " (itoa anzahl-ok) " OK, " (itoa anzahl-fehler) " Fehler")) (setq *omniflo-strecke-test-results* (reverse results-list)) (ssg-end) (dbgreturn (list anzahl-ok anzahl-fehler)) (if *omniflo-strecke-dbg* (dbgclose)) (princ "\n TEST_OMNIFLO_STRECKE abgeschlossen.") (princ) ) ) ) ) )