This commit is contained in:
2026-06-18 15:21:10 +02:00
13 changed files with 1235 additions and 562 deletions
+29
View File
@@ -0,0 +1,29 @@
;; ============================================================
;; tests.lsp - Test- und Hilfsfunktionen
;;
;; Export-Funktionen wurden nach export.lsp ausgelagert.
;; ============================================================
(defun c:CALLPYTHON ( / log-pfad py-skript return-datei cmd fh zeile)
(setq log-pfad (getenv "DXFM_LOG"))
(setq py-skript (strcat (getenv "DXFM_LIB") "\\testpycall.py"))
(setq return-datei (strcat log-pfad "\\testpycall_return.txt"))
(if (findfile py-skript)
(progn
(setq cmd (strcat "python \"" py-skript "\" \"" log-pfad "\""))
(command "_.SHELL" cmd)
(if (findfile return-datei)
(progn
(setq fh (open return-datei "r"))
(setq zeile (read-line fh))
(close fh)
(princ (strcat "\n[SSG_LIB] Python Rueckgabe: " zeile))
)
(princ "\n[SSG_LIB] WARNUNG: Keine Rueckgabe von Python erhalten.")
)
)
(princ (strcat "\n[SSG_LIB] FEHLER: " py-skript " nicht gefunden!"))
)
(princ)
)
-466
View File
@@ -1,466 +0,0 @@
;; ============================================================
;; tests.lsp - Test- und Hilfsfunktionen
;;
;; Export-Funktionen wurden nach export.lsp ausgelagert.
;; ============================================================
(defun c:CALLPYTHON ( / log-pfad py-skript return-datei cmd fh zeile)
(setq log-pfad (getenv "DXFM_LOG"))
(setq py-skript (strcat (getenv "DXFM_LIB") "\\testpycall.py"))
(setq return-datei (strcat log-pfad "\\testpycall_return.txt"))
(if (findfile py-skript)
(progn
(setq cmd (strcat "python \"" py-skript "\" \"" log-pfad "\""))
(command "_.SHELL" cmd)
(if (findfile return-datei)
(progn
(setq fh (open return-datei "r"))
(setq zeile (read-line fh))
(close fh)
(princ (strcat "\n[SSG_LIB] Python Rueckgabe: " zeile))
)
(princ "\n[SSG_LIB] WARNUNG: Keine Rueckgabe von Python erhalten.")
)
)
(princ (strcat "\n[SSG_LIB] FEHLER: " py-skript " nicht gefunden!"))
)
(princ)
)
;; ============================================================
;; TEST_FOERDERER - Automatischer Test ohne Benutzereingabe
;; Erzeugt 12 Variofoerderer (6x Auf, 6x Ab) mit deltaL=7000
;; und verschiedenen Hoehenstufen. Tabellarische Zusammenfassung.
;; ============================================================
(defun c:TEST_FOERDERER ( / deltaL deltaH richtung ergebnis
best-winkel L_GF L_VF dateiname
y-offset hoehen-liste idx
anz-gebaut anz-nicht-gebaut
result-pfad erfolgsquote
zusammenfassung-liste
nr deltaH_val status winkel L_GF_val L_VF_val)
;; Bibliothek initialisieren (laedt Block-Library und extrahiert Masse)
(if (not *lib-initialized*)
(init-bibliothek)
)
(ssg-start "TEST_FOERDERER" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq deltaL 7000)
(setq hoehen-liste '(0 1000 2000 3000 4000 5000))
(setq y-offset 0)
(setq idx 0)
(setq zusammenfassung-liste '())
(setq anz-gebaut 0)
(setq anz-nicht-gebaut 0)
(princ "\n")
(princ "\n================================================================")
(princ "\n FOERDERTEST - PRODUKTIONSPROTOKOLL")
(princ "\n================================================================")
(princ (strcat "\n Distanz dL = " (rtos deltaL 2 0) " mm"))
(princ "\n Hoehenstufen: 0, 1000, 2000, 3000, 4000, 5000 mm")
(princ "\n Richtungen: Auf + Ab")
(princ "\n================================================================")
(princ "\n Nr. Richtung dH (mm) Status Winkel L_GF (mm) L_VF (mm)")
(princ "\n================================================================")
;; ==========================================================
;; TEIL 1: Aufwaerts-Tests (6 Foerderer)
;; ==========================================================
(foreach deltaH hoehen-liste
(setq idx (1+ idx))
(setq richtung "Auf")
(setq ergebnis (berechne-alle-winkel deltaL deltaH richtung))
(setq best-winkel (car ergebnis))
(setq L_GF (cadr ergebnis))
(setq L_VF (caddr ergebnis))
(if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0))
(progn
(setq anz-gebaut (1+ anz-gebaut))
(princ (strcat "\n "
(itoa idx) " "
(if (< idx 10) " " "")
"Auf "
(rtos deltaH 4 0) " "
"GEBAUT "
(itoa best-winkel) " Grad "
(rtos L_GF 2 1) " "
(rtos L_VF 2 1)))
(foerderanlage-einfuegen deltaL deltaH richtung best-winkel
(/ L_GF 2.0) (/ L_GF 2.0) L_VF
(list 0 y-offset 0))
(setq zusammenfassung-liste (cons
(list idx richtung deltaH "GEBAUT" best-winkel L_GF L_VF)
zusammenfassung-liste))
)
(progn
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n "
(itoa idx) " "
(if (< idx 10) " " "")
"Auf "
(rtos deltaH 4 0) " "
"NICHT "
"--- "
"--- "
"---"))
(cond
((and (<= L_GF 0) (<= L_VF 0))
(princ "\n -> Grund: L_GF und L_VF sind negativ (Strecke zu kurz)"))
((<= L_GF 0)
(princ "\n -> Grund: L_GF ist negativ (Gefaellestrecke zu kurz)"))
((<= L_VF 0)
(princ "\n -> Grund: L_VF ist negativ (keine passende Steigung moeglich)"))
((null best-winkel)
(princ "\n -> Grund: Kein passender Winkel (Hoehendifferenz zu gross/klein)"))
(t
(princ "\n -> Grund: Unbekannter Fehler in der Berechnung"))
)
(setq zusammenfassung-liste (cons
(list idx richtung deltaH "NICHT_GEBAUT" nil nil nil)
zusammenfassung-liste))
)
)
(setq y-offset (- y-offset 200))
)
;; ==========================================================
;; TEIL 2: Abwaerts-Tests (6 Foerderer)
;; ==========================================================
(foreach deltaH hoehen-liste
(setq idx (1+ idx))
(setq richtung "Ab")
(if (< deltaH 1)
(progn
;; deltaH = 0 bei Abwaerts ist prinzipiell unmoeglich
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n "
(itoa idx) " "
(if (< idx 10) " " "")
"Ab "
(rtos deltaH 4 0) " "
"NICHT "
"--- "
"--- "
"---"))
(princ "\n -> Grund: Bei Richtung 'Ab' mit dH=0 ist aus geometrischen Gruenden")
(princ "\n keine Foerderanlage moeglich (immer negative Netto-Hoehe)")
(setq zusammenfassung-liste (cons
(list idx richtung deltaH "GEOMETRISCH_UNMOEGLICH" nil nil nil)
zusammenfassung-liste))
)
(progn
(setq ergebnis (berechne-alle-winkel deltaL deltaH richtung))
(setq best-winkel (car ergebnis))
(setq L_GF (cadr ergebnis))
(setq L_VF (caddr ergebnis))
(if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0))
(progn
(setq anz-gebaut (1+ anz-gebaut))
(princ (strcat "\n "
(itoa idx) " "
(if (< idx 10) " " "")
"Ab "
(rtos deltaH 4 0) " "
"GEBAUT "
(itoa best-winkel) " Grad "
(rtos L_GF 2 1) " "
(rtos L_VF 2 1)))
(foerderanlage-einfuegen deltaL deltaH richtung best-winkel
(/ L_GF 2.0) (/ L_GF 2.0) L_VF
(list 0 y-offset 0))
(setq zusammenfassung-liste (cons
(list idx richtung deltaH "GEBAUT" best-winkel L_GF L_VF)
zusammenfassung-liste))
)
(progn
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n "
(itoa idx) " "
(if (< idx 10) " " "")
"Ab "
(rtos deltaH 4 0) " "
"NICHT "
"--- "
"--- "
"---"))
(cond
((and (<= L_GF 0) (<= L_VF 0))
(princ "\n -> Grund: L_GF und L_VF sind negativ (Strecke zu kurz)"))
((<= L_GF 0)
(princ "\n -> Grund: L_GF ist negativ (Gefaellestrecke zu kurz)"))
((<= L_VF 0)
(princ "\n -> Grund: L_VF ist negativ (Hoehendifferenz zu klein fuer diesen Weg)"))
((null best-winkel)
(princ "\n -> Grund: Kein passender Winkel (Hoehendifferenz zu gross)"))
(t
(princ "\n -> Grund: Unbekannter Fehler in der Berechnung"))
)
(setq zusammenfassung-liste (cons
(list idx richtung deltaH "NICHT_GEBAUT" nil nil nil)
zusammenfassung-liste))
)
)
)
)
(setq y-offset (- y-offset 200))
)
;; ==========================================================
;; TEIL 3: ZUSAMMENFASSUNG
;; ==========================================================
(princ "\n\n================================================================================")
(princ "\n ZUSAMMENFASSUNG")
(princ (strcat "\n dL = " (rtos deltaL 2 0) " mm"))
(princ "\n================================================================================")
(foreach item (reverse zusammenfassung-liste)
(setq nr (car item))
(setq richtung (cadr item))
(setq deltaH_val (caddr item))
(setq status (cadddr item))
(setq winkel (car (cddddr item)))
(setq L_GF_val (cadr (cddddr item)))
(setq L_VF_val (caddr (cddddr item)))
(cond
((= status "GEBAUT")
(princ (strcat "\n "
(itoa nr) ". " richtung
(if (= richtung "Auf") " " " ")
(rtos deltaH_val 2 0) " mm "
(itoa winkel) " Grad "
(rtos L_GF_val 2 2) " mm "
(rtos L_VF_val 2 2) " mm GEBAUT")))
((= status "GEOMETRISCH_UNMOEGLICH")
(princ (strcat "\n "
(itoa nr) ". " richtung
(if (= richtung "Auf") " " " ")
(rtos deltaH_val 2 0) " mm "
"--- "
"--- mm "
"--- mm GEOMETRISCH UNMOEGLICH")))
(t
(princ (strcat "\n "
(itoa nr) ". " richtung
(if (= richtung "Auf") " " " ")
(rtos deltaH_val 2 0) " mm "
"--- "
"--- mm "
"--- mm NICHT GEBAUT")))
)
)
(princ "\n\n================================================================================")
(princ (strcat "\n Erfolgreich gebaut: " (itoa anz-gebaut) " von " (itoa idx)))
(princ (strcat "\n Erfolgsquote: " (rtos (/ (* anz-gebaut 100.0) idx) 2 1) "%"))
(princ "\n================================================================================")
(princ "\n\n Erklaerung:")
(princ "\n ----------")
(princ "\n GEBAUT:")
(princ "\n - Auf, dH=0 -> L_VF > 0 kompensiert 3 Grad-Gefaellestrecken")
(princ "\n - Auf, dH>0 -> Normalfall")
(princ "\n - Ab, dH>=1000 -> Normalfall")
(princ "\n")
(princ "\n NICHT GEBAUT:")
(princ "\n - Ab, dH=0 -> Geometrisch unmoeglich (Netto-Hoehe immer negativ)")
(princ "\n - Auf, dH=5000 -> 48 Grad Steigung reicht nicht aus (L_VF negativ)")
(princ "\n - Ab, dH=5000 -> 48 Grad Gefaelle reicht nicht aus")
(princ "\n================================================================================")
(ssg-end)
;; Datei speichern
(if (getenv "DXFM_RESULTS")
(setq result-pfad (getenv "DXFM_RESULTS"))
(setq result-pfad (strcat (getenv "DXFM_BLOCKS") "/../results"))
)
(setq dateiname (strcat result-pfad
"/"
(menucmd "M=$(edtime,$(getvar,date),YYYYMODD-HHmm)")
".dxf"))
(princ (strcat "\n\nSpeichere als: " dateiname))
(command "_.DXFOUT" dateiname "V" "2018" "16")
(princ "\n\n>>> FOERDERTEST abgeschlossen (12 Foerderer)! <<<")
(princ)
)
;; ============================================================
;; TEST_KSEINAUS - KS_EIN/KS_AUS Ausrichtungstest
;;
;; Fuegt alle Vario-Bloecke in 3 Gruppen ein, jeweils 2 Reihen:
;; Gruppe 1: Stationaere Elemente (AUS, EIN, Separator, Umlenk, Motor)
;; Gruppe 2: Alle Boegen aufwaerts (in Z verschoben)
;; Gruppe 3: Alle Boegen abwaerts (in Z verschoben)
;;
;; Pro Gruppe:
;; Reihe A: nach KS_EIN ausgerichtet (KS_EIN X/Y = Referenz-X/Y)
;; Reihe B: nach KS_AUS ausgerichtet (KS_AUS X/Y = Referenz-X/Y)
;; Luecke von 400mm zwischen den Reihen
;; ============================================================
;; Hilfsfunktion: Eine Liste von Bloecken in 2 Reihen aufreihen
;; x-start: X-Position der Gruppe
;; y-start: Y-Startposition (wird zurueckgegeben als naechster freier Y)
;; z-offset: Z-Verschiebung (fuer Boegen)
;; Rueckgabe: naechste freie Y-Position
(defun ks-test-reihe (namen x-start y-start z-offset y-abstand y-luecke /
bname block-obj ks-data ks-ein ks-aus
insert-pt offset-vec y-pos idx)
;; --- Reihe A: nach KS_EIN ---
(princ "\n Reihe KS_EIN:")
(setq y-pos y-start)
(setq idx 0)
(foreach bname namen
(setq idx (1+ idx))
(setq insert-pt (list x-start y-pos z-offset))
(setq block-obj (vla-InsertBlock modelspace
(vlax-3D-point insert-pt)
bname 1.0 1.0 1.0 0))
(setq ks-data (extract-ks-from-block block-obj))
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
(if ks-ein
(progn
(setq offset-vec (list (- x-start (car (car ks-ein)))
(- y-pos (cadr (car ks-ein)))
(- z-offset (caddr (car ks-ein)))))
(vla-Move block-obj
(vlax-3D-point '(0 0 0))
(vlax-3D-point offset-vec))
(princ (strcat "\n " (itoa idx) ". " bname " OK"))
)
(princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_EIN fehlt!"))
)
(setq y-pos (- y-pos y-abstand))
)
;; --- Luecke ---
(setq y-pos (- y-pos y-luecke))
;; --- Reihe B: nach KS_AUS ---
(princ "\n Reihe KS_AUS:")
(setq idx 0)
(foreach bname namen
(setq idx (1+ idx))
(setq insert-pt (list x-start y-pos z-offset))
(setq block-obj (vla-InsertBlock modelspace
(vlax-3D-point insert-pt)
bname 1.0 1.0 1.0 0))
(setq ks-data (extract-ks-from-block block-obj))
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
(if ks-aus
(progn
(setq offset-vec (list (- x-start (car (car ks-aus)))
(- y-pos (cadr (car ks-aus)))
(- z-offset (caddr (car ks-aus)))))
(vla-Move block-obj
(vlax-3D-point '(0 0 0))
(vlax-3D-point offset-vec))
(princ (strcat "\n " (itoa idx) ". " bname " OK"))
)
(princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_AUS fehlt!"))
)
(setq y-pos (- y-pos y-abstand))
)
;; Naechste freie Y-Position zurueckgeben
y-pos
)
(defun c:TEST_KSEINAUS ( / stationen boegen-auf-liste boegen-ab-liste
bname y-pos y-abstand y-luecke z-bogen)
;; Bibliothek initialisieren
(if (not *lib-initialized*)
(init-bibliothek)
)
(ssg-start "TEST_KSEINAUS" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq y-abstand 200)
(setq y-luecke 400)
(setq z-bogen 2500)
;; Gruppe 1: Stationaere Elemente
(setq stationen (list
"_3D_AS_90_links"
"Staustrecke_Separator_SP_300_mm"
"Vario_Umlenkstation_500mm"
"Vario_Motorstation_500mm"
"_3D_ES_90_links"
))
;; Gruppe 2+3: Boegen sammeln
(setq boegen-auf-liste '())
(setq boegen-ab-liste '())
(foreach w '(3 6 9 12 15 18 21 27 33 39 45 51)
(setq bname (strcat "Vario_Bogen_auf_" (itoa w) grad-zeichen))
(if (tblsearch "BLOCK" bname)
(setq boegen-auf-liste (append boegen-auf-liste (list bname)))
)
(setq bname (strcat "Vario_Bogen_ab_" (itoa w) grad-zeichen))
(if (tblsearch "BLOCK" bname)
(setq boegen-ab-liste (append boegen-ab-liste (list bname)))
)
)
(princ "\n================================================================")
(princ "\n TEST_KSEINAUS - KS-Ausrichtungstest")
(princ (strcat "\n Stationen: " (itoa (length stationen))))
(princ (strcat "\n Boegen auf: " (itoa (length boegen-auf-liste))))
(princ (strcat "\n Boegen ab: " (itoa (length boegen-ab-liste))))
(princ (strcat "\n Z-Offset Boegen: " (rtos z-bogen 2 0) " mm"))
(princ "\n================================================================")
;; Gruppe 1: Stationaere Elemente bei X=0, Z=0
(princ "\n\n GRUPPE 1: Stationaere Elemente (Z=0)")
(setq y-pos (ks-test-reihe stationen 0 0 0 y-abstand y-luecke))
;; Gruppe 2: Boegen aufwaerts bei X=3000, Z=z-bogen
(princ "\n\n GRUPPE 2: Boegen aufwaerts (Z=" )
(princ (strcat (rtos z-bogen 2 0) ")"))
(setq y-pos (ks-test-reihe boegen-auf-liste 3000 0 z-bogen y-abstand y-luecke))
;; Gruppe 3: Boegen abwaerts bei X=6000, Z=z-bogen
(princ "\n\n GRUPPE 3: Boegen abwaerts (Z=")
(princ (strcat (rtos z-bogen 2 0) ")"))
(setq y-pos (ks-test-reihe boegen-ab-liste 6000 0 z-bogen y-abstand y-luecke))
(ssg-end)
(princ "\n\n================================================================")
(princ "\n TEST_KSEINAUS abgeschlossen")
(princ "\n X=0: Stationen (KS_EIN + KS_AUS)")
(princ "\n X=3000: Boegen auf (KS_EIN + KS_AUS)")
(princ "\n X=6000: Boegen ab (KS_EIN + KS_AUS)")
(princ "\n================================================================")
(princ)
)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -119,7 +119,7 @@
(ssg-ensure "EtageVarioFoerderer")
(ssg-ensure "Gefaellestrecke")
(ssg-ensure "export")
(ssg-ensure "tests")
(ssg-ensure "external_call")
(ssg-ensure "OmniModulInsert")
(ssg-ensure "SSG_LIB_Commands")
+102 -95
View File
@@ -4,125 +4,132 @@
[SSG_LIB]
[->ILS]
[->Kreisel-Module]
[Einfuegen]^C^CKreiselInsert
[Verbinden]^C^CKreiselConnect
[Bearbeiten]^C^CKreiselEdit
[<-Eckrad]^C^CILS_Eckrad
[Einfuegen]^C^C(ssg-ensure "KreiselInsert") KreiselInsert
[Verbinden]^C^C(ssg-ensure "KreiselInsert") KreiselConnect
[Bearbeiten]^C^C(ssg-ensure "KreiselInsert") KreiselEdit
[<-Eckrad]^C^C(ssg-ensure "KreiselInsert") ILS_Eckrad
[->Zusatzmodul]
[BTMT-Beladung]^C^CILS_BTMT_Beladung
[<-BTMT-Entladung]^C^CILS_BTMT_Entladung
[BTMT-Beladung]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Beladung
[<-BTMT-Entladung]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Entladung
[->Foerderer]
[ETF Etagenfoerderer]^C^CILS_ETF_Etagenfoerderer
[Durch TEF angetriebene Strecke]^C^CILS_TEF_Strecke
[ETF Etagenfoerderer]^C^CI(ssg-ensure "SSG_LIB_Commands") LS_ETF_Etagenfoerderer
[Durch TEF angetriebene Strecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_TEF_Strecke
[VarioFoerderer]^C^CVarioFoerderer
[EtageVarioFoerderer]^C^CETAGEVARIOFOERDERER
[--]
[90 Kurve links angetrieben Aussen]^C^CILS_K90LA
[90 Kurve rechts angetrieben Aussen]^C^CILS_K90RA
[60 Kurve links angetrieben Aussen]^C^CILS_K60LA
[60 Kurve rechts angetrieben Aussen]^C^CILS_K60RA
[30 Kurve links angetrieben Aussen]^C^CILS_K30LA
[30 Kurve rechts angetrieben Aussen]^C^CILS_K30RA
[90 Kurve links angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K90LA
[90 Kurve rechts angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K90RA
[60 Kurve links angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K60LA
[60 Kurve rechts angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K60RA
[30 Kurve links angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K30LA
[30 Kurve rechts angetrieben Aussen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K30RA
[--]
[90 Kurve links angetrieben Innen]^C^CILS_K90LI
[90 Kurve rechts angetrieben Innen]^C^CILS_K90RI
[60 Kurve links angetrieben Innen]^C^CILS_K60LI
[60 Kurve rechts angetrieben Innen]^C^CILS_K60RI
[30 Kurve links angetrieben Innen]^C^CILS_K30LI
[<-30 Kurve rechts angetrieben Innen]^C^CILS_K30RI
[90 Kurve links angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K90LI
[90 Kurve rechts angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K90RI
[60 Kurve links angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K60LI
[60 Kurve rechts angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K60RI
[30 Kurve links angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K30LI
[<-30 Kurve rechts angetrieben Innen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_K30RI
[->Gefaellestrecke]
[Gefaellestrecke]^C^CILS_Gefaellestrecke
[Gefaellestrecke]^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE
[--]
[90 Kurve links Gefaellestrecke]^C^CILS_GK90L
[90 Kurve rechts Gefaellestrecke]^C^CILS_GK90R
[60 Kurve links Gefaellestrecke]^C^CILS_GK60L
[60 Kurve rechts Gefaellestrecke]^C^CILS_GK60R
[30 Kurve links Gefaellestrecke]^C^CILS_GK30L
[<-30 Kurve rechts Gefaellestrecke]^C^CILS_GK30R
[90 Kurve links Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK90L
[90 Kurve rechts Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK90R
[60 Kurve links Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK60L
[60 Kurve rechts Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK60R
[30 Kurve links Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK30L
[<-30 Kurve rechts Gefaellestrecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_GK30R
[<-ILS Schliessen]^C^C
[->Omniflo]
[->Boegen]
[90]^C^COMNI_APB_630_90
[67.5]^C^COMNI_APB_550_675
[45]^C^COMNI_APB_630_45
[22.5]^C^COMNI_APB_550_225
[<-180 ]^C^COMNI_APB_650_180
[90]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_90
[67.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_675
[45]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_45
[22.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_225
[<-180 ]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_650_180
[->Aluprofil Gerade]
[AP 60]^C^COMNI_AP60
[AP 110]^C^COMNI_AP110
[<-APG 110]^C^COMNI_APG110
[AP 60]^C^C(ssg-ensure "OmniModulInsert") OMNI_AP60
[AP 110]^C^C(ssg-ensure "OmniModulInsert") OMNI_AP110
[<-APG 110]^C^C(ssg-ensure "OmniModulInsert") OMNI_APG110
[->Weiche 90 Grad]
[Einfach 90 700/700 links M]^C^COMNI_W90_Einfach
[Doppel 90 700/700 M]^C^COMNI_W90_Doppel
[<-Dreiwege 90 700/700 M]^C^COMNI_W90_Dreiwege
[Einfach 90 700/700 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Einfach
[Doppel 90 700/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel
[<-Dreiwege 90 700/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege
[->Weiche 45 Grad]
[Einfach 45 350/700 links M]^C^COMNI_W45_Einfach
[Doppel 45 350/700 M]^C^COMNI_W45_Doppel
[<-Dreiwege 45 350/700 M]^C^COMNI_W45_Dreiwege
[Einfach 45 350/700 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach
[Doppel 45 350/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel
[<-Dreiwege 45 350/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege
[->Weichen Parallel]
[Einfach Parallel 200/750 links M]^C^COMNI_WP_Einfach
[Doppel Parallel 200/750 M]^C^COMNI_WP_Doppel
[<-Dreiwege Parallel 200/750 M]^C^COMNI_WP_Dreiwege
[Einfach Parallel 200/750 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach
[Doppel Parallel 200/750 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel
[<-Dreiwege Parallel 200/750 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege
[->Weichenkoerper]
[Einfach 22.5 links M]^C^COMNI_WK_Einfach
[Doppel 22.5 M]^C^COMNI_WK_Doppel
[<-Dreiwege 22.5 M]^C^COMNI_WK_Dreiwege
[Einfach 22.5 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach
[Doppel 22.5 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel
[<-Dreiwege 22.5 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege
[->Weichenkombinationen]
[Delta 1400/700 M]^C^COMNI_WKomb_Delta
[<-Star 1400/1400 M]^C^COMNI_WKomb_Star
[Delta 1400/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta
[<-Star 1400/1400 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Star
[->TEF Elemente]
[Umlenkspannst. rechts fuer TEF links]^C^COMNI_TEF_UmlenkR
[Umlenkspannst. links fuer TEF rechts]^C^COMNI_TEF_UmlenkL
[Antriebst. links fuer TEF links]^C^COMNI_TEF_AntriebL
[Antriebst. rechts fuer TEF rechts]^C^COMNI_TEF_AntriebR
[<-TEF Gerade]^C^COMNI_TEF_Gerade
[KettenFoerderer]^C^COMNI_KettenFoerderer
[Umlenkspannst. rechts fuer TEF links]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkR
[Umlenkspannst. links fuer TEF rechts]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkL
[Antriebst. links fuer TEF links]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebL
[Antriebst. rechts fuer TEF rechts]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebR
[<-TEF Gerade]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_Gerade
[KettenFoerderer]^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer
[->Verbinder]
[TV W-W kpl]^C^COMNI_TV_W_W
[TV W-AP110 kpl]^C^COMNI_TV_W_AP110
[TV W-AP60 oben kpl.]^C^COMNI_TV_W_AP60
[TV W-AP110-W kpl]^C^COMNI_TV_W_AP110_W
[TV W-AP oben kpl]^C^COMNI_TV_W_AP
[TV 80]^C^COMNI_TV_80
[TV 50]^C^COMNI_TV_50
[Endplatte Al-Profil AP schraubbar]^C^COMNI_TV_ENDPLATTE
[Anschlag AP-Ende fuer Spulenzug]^C^COMNI_TV_ANSCHLAG
[TV-A fuer AP110/AP60 kpl]^C^COMNI_TV_A_AP110_AP60
[TV-A fuer AP60/ST]^C^COMNI_TV_A_AP60_ST
[TV-A fuer AP110/ST kpl]^C^COMNI_TV_A_AP110_ST
[TV-SW II fuer SW-SW]^C^COMNI_TV_SW_II_SW_SW
[TV-SW III fuer SW-AP110-SW]^C^COMNI_TV_SW_III_AP110_SW
[TV-SW III fuer SW-AP110]^C^COMNI_TV_SW_III_AP110
[TV-SW IV fuer Anschluss SW-AP60]^C^COMNI_TV_SW_IV_AP60
[TV-SW IV fuer SW-ST]^C^COMNI_TV_SW_IV_ST
[<-Muffe]^C^COMNI_TV_MUFFE
[TV W-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W
[TV W-AP110 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110
[TV W-AP60 oben kpl.]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60
[TV W-AP110-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110_W
[TV W-AP oben kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP
[TV 80]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_80
[TV 50]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_50
[Endplatte Al-Profil AP schraubbar]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ENDPLATTE
[Anschlag AP-Ende fuer Spulenzug]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG
[TV-A fuer AP110/AP60 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60
[TV-A fuer AP60/ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST
[TV-A fuer AP110/ST kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST
[TV-SW II fuer SW-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW
[TV-SW III fuer SW-AP110-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW
[TV-SW III fuer SW-AP110]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110
[TV-SW IV fuer Anschluss SW-AP60]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60
[TV-SW IV fuer SW-ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST
[<-Muffe]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_MUFFE
[->Boegen fuer Weichen]
[APB 110 R400/45 140 nur fuer Delta]^C^COMNI_APBW_R400_45_140
[APB 110 R550/45 194 nur fuer Delta]^C^COMNI_APBW_R550_45_194
[APBW 110 R550/22,5 360x248,5]^C^COMNI_APBW_R550_225_360
[APBW 110 R550/22,5 410x298,5]^C^COMNI_APBW_R550_225_410A
[APBW 110 R550/22,5 410x78,5]^C^COMNI_APBW_R550_225_410B
[APBW 110 R550/22,5 410x98,5]^C^COMNI_APBW_R550_225_410C
[APBW 110 R550/67,5 360x598,5]^C^COMNI_APBW_R550_675_360
[APBW 110 R400/67,5 260x398,5]^C^COMNI_APBW_R400_675_260
[APBW 110 R550/45 77x160]^C^COMNI_APBW_R550_45_77
[APBW 110 R550/67,5 125x83,5]^C^COMNI_APBW_R550_675_125
[APBW 110 R750/90 200x290]^C^COMNI_APBW_R750_90_200
[APBW 110 R650/90 300x190]^C^COMNI_APBW_R650_90_300
[APBW 110 R550/67,5 208x347]^C^COMNI_APBW_R550_675_208
[<-APBW 110 R550/67,5 58x497]^C^COMNI_APBW_R550_675_58
[<-Element bearbeiten]^C^COMNI_EDIT
[APB 110 R400/45 140 nur fuer Delta]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_45_140
[APB 110 R550/45 194 nur fuer Delta]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_194
[APBW 110 R550/22,5 360x248,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_360
[APBW 110 R550/22,5 410x298,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410A
[APBW 110 R550/22,5 410x78,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410B
[APBW 110 R550/22,5 410x98,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410C
[APBW 110 R550/67,5 360x598,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_360
[APBW 110 R400/67,5 260x398,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_675_260
[APBW 110 R550/45 77x160]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_77
[APBW 110 R550/67,5 125x83,5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_125
[APBW 110 R750/90 200x290]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R750_90_200
[APBW 110 R650/90 300x190]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R650_90_300
[APBW 110 R550/67,5 208x347]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_208
[<-APBW 110 R550/67,5 58x497]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_58
[<-Element bearbeiten]^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT
[->External]
[Call Python]^C^CCALLPYTHON
[Export Sivas]^C^CEXPORTSIVAS
[<-Export CSV]^C^CEXPORTCSV
[Call Python]^C^C(ssg-ensure "export") CALLPYTHON
[Export Sivas]^C^C(ssg-ensure "export") EXPORTSIVAS
[<-Export CSV]^C^C(ssg-ensure "export") EXPORTCSV
[->Tests]
[Alle Tests ausfuehren]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) SSG_RUN_ALL_TESTS
[--]
[Kreisel]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) TEST_KREISEL
[Foerderer]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) TEST_FOERDERER
[KS EIN/AUS]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_ks.lsp")) TEST_KSEINAUS
[<-Omniflo Export]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) TEST_OMNIFLO_EXPORT
***DOUBLECLICK
[INSERT]^C^CSSG_BLOCKEDIT
[INSERT]^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
***POP501
[SSG_LIB Edit Context]
[Kreisel bearbeiten]KreiselEdit
[Omniflo Element bearbeiten]OMNI_EDIT
[Kreisel bearbeiten](ssg-ensure "KreiselInsert") KreiselEdit
[Omniflo Element bearbeiten](ssg-ensure "OmniModulInsert") OMNI_EDIT
[--]
[SSG Bearbeiten (Auto)]SSG_BLOCKEDIT
[SSG Bearbeiten (Auto)](ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
+294
View File
@@ -0,0 +1,294 @@
# Tests - SSG_LIB Testarchitektur
## Uebersicht
Die Tests folgen einer **zweistufigen Architektur**:
1. **LISP-Testrunner** (`.lsp`) — laufen in BricsCAD, erzeugen Ergebnisdateien
2. **Python-Validierung** (`.py`) — pruefen die Ergebnisse mit pytest + ezdxf
```
BricsCAD Kommandozeile
| |
| TEST_KREISEL |
| TEST_OMNIFLO_EXPORT |
| | |
v v |
tests/output/ |
kreisel_results.json |
kreisel_tests.dxf |
omniflo_export.csv |
|
bin\run_tests.bat --runall
|
pytest -v
|
test_kreisel.py
test_omniflo.py
```
## Ablauf fuer den Anwender
1. **BricsCAD starten** (ueber `bin\start_briscad.bat`) und die LISP-Testrunner ausfuehren (siehe Abschnitt "LISP-Tests in BricsCAD ausfuehren"). Die Testrunner erzeugen Bloecke in der Zeichnung und speichern Ergebnisse nach `tests/output/`.
2. **Optische Kontrolle** in BricsCAD — pruefen ob die erzeugten Bloecke korrekt aussehen (Positionen, Drehungen, Beschriftungen). Die Zeichnung bleibt offen und kann visuell inspiziert werden.
3. **Kommandozeile**: Ergebnisse validieren oder als neue Referenz speichern:
- `bin\run_tests.bat --runall` — pytest prueft die Ergebnisse aus `output/` gegen Testdefinitionen und Referenzdaten
- `bin\run_tests.bat --set-as-reference` — nach erfolgreicher Pruefung die aktuellen Ergebnisse als neue Referenz uebernehmen (kopiert `output/` nach `reference/`)
## Verzeichnisstruktur
```
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_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_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
reference/ # Abgenommene Referenzdaten (in Git)
kreisel_ref.dxf
...
```
## Workflow
### 1. LISP-Tests in BricsCAD ausfuehren
BricsCAD starten (ueber `bin\start_briscad.bat`) und Module laden:
```lisp
(load (strcat (getenv "DXFMAKRO") "/Lisp/ssg_load.lsp"))
```
Dann den gewuenschten Testrunner laden und 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
```
Die Testrunner:
- Lesen Testfaelle aus `testdata/*.json`
- Fuegen Bloecke per Script-Funktionen ein (ohne User-Interaktion)
- Speichern Ergebnisse nach `output/`
### 2. Python-Validierung ausfuehren
```cmd
bin\run_tests.bat --runall
```
Oder fuer ein einzelnes Testmodul:
```cmd
bin\run_tests.bat --runall test_kreisel.py
```
Die Python-Tests pruefen:
- **Attribut-Werte** gegen die Testdefinitionen (JSON)
- **DXF-Geometrie** mit ezdxf (Bloecke, Positionen, Radien)
- **Referenz-Vergleich** gegen abgenommene Referenz-DXF
- **CSV-Export** (Omniflo: Spalten, Merkmale, Datentypen)
Tests, deren Eingabedaten fehlen (z.B. kein BricsCAD-Lauf), werden automatisch uebersprungen (`pytest.skip`).
### 3. Referenz erstellen/aktualisieren
Nach einem erfolgreichen Testlauf die Ergebnisse als Referenz speichern:
```cmd
bin\run_tests.bat --set-as-reference
```
Kopiert alle Dateien aus `output/` nach `reference/`. Nur bei bestandenen Tests verwenden.
## Neuen Test erstellen
### Schritt 1: Testdaten definieren (JSON)
Neue Testfaelle in `testdata/<modul>_tests.json` eintragen. Das Format ist ein **flaches JSON-Array** (kompatibel mit `omni:load-json`).
**Kreisel-Beispiel** (`kreisel_tests.json`):
```json
[
{
"id": "KR_Insert_Neu",
"function": "insert",
"x": 5000, "y": 5000, "z": 2000,
"abstand": 5000,
"rotation": 0.0,
"typ": "STANDARD",
"expect_block_prefix": "KREISEL_",
"expect_hoehe": "2000",
"expect_kreiselart": "STANDARD"
}
]
```
Felder:
- `id` — Eindeutiger Name des Testfalls
- `function``"insert"` oder `"connect"`
- Eingabeparameter (`x`, `y`, `z`, `abstand`, `rotation`, `typ` fuer Insert; `start_x/y/z`, `end_x/y/z`, `typ` fuer Connect)
- `expect_*` — Erwartete Ergebniswerte (fuer Python-Validierung)
**Omniflo-Beispiel** (`omniflo_tests.json`):
```json
[
{
"sivasnr": "834372001",
"type": "bogen",
"description": "Bogen 90 Grad R200",
"hoehe": 2000,
"drehung": 0
}
]
```
### Schritt 2: LISP-Testrunner erweitern (falls neues Modul)
Fuer ein neues Modul eine neue `.lsp`-Datei erstellen nach dem Muster:
```lisp
;; test_<modul>.lsp
(defun c:TEST_<MODUL> (/ ...)
(ssg-start "TEST_<MODUL>" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
;; 1. Testdaten laden
(setq testfaelle (omni:load-json
(strcat (getenv "DXFMAKRO") "/tests/testdata/<modul>_tests.json")))
;; 2. Testfaelle ausfuehren, Ergebnisse sammeln
(foreach eintrag testfaelle
;; ... Script-Funktion aufrufen, Ergebnis pruefen ...
)
;; 3. Ergebnisse als JSON speichern
(setq out-json (strcat (getenv "DXFMAKRO") "/tests/output/<modul>_results.json"))
;; ... JSON schreiben ...
;; 4. DXF speichern
(command "_.SAVEAS" "DXF" out-dxf)
(ssg-end)
)
```
Wichtig:
- `omni:load-json` erwartet ein **flaches JSON-Array** mit flachen Objekten (kein Nesting)
- `omni:val` liest Werte aus den geladenen Eintraegen
- Script-Funktionen (z.B. `kreisel-insert-script`) muessen **ohne User-Interaktion** funktionieren
### Schritt 3: Python-Validierung erstellen
Neue `test_<modul>.py` erstellen:
```python
import pytest
class TestModulAttributes:
"""Prueft Attribute gegen Testdefinitionen."""
def test_all_executed(self, <modul>_results):
"""Alle Testfaelle muessen ausgefuehrt worden sein."""
# ...
def test_attribute_values(self, <modul>_testdata, <modul>_results):
"""Attributwerte muessen mit Erwartungen uebereinstimmen."""
# ...
class TestModulGeometry:
"""Prueft DXF-Geometrie mit ezdxf."""
def test_blocks_exist(self, <modul>_dxf):
"""Bloecke muessen im Modelspace vorhanden sein."""
# ...
class TestModulReference:
"""Vergleicht gegen Referenz."""
def test_matches_reference(self, <modul>_dxf, <modul>_ref_dxf):
# ...
```
### Schritt 4: Fixtures in conftest.py ergaenzen
Neue Fixtures fuer Testdaten, Ergebnisse und DXF in `conftest.py` hinzufuegen:
```python
@pytest.fixture
def <modul>_testdata():
path = os.path.join(_testdata_dir(), "<modul>_tests.json")
return _load_json(path)
@pytest.fixture
def <modul>_results():
path = os.path.join(_output_dir(), "<modul>_results.json")
if not os.path.exists(path):
pytest.skip("<modul>_results.json nicht vorhanden")
return _load_json(path)
@pytest.fixture
def <modul>_dxf():
path = os.path.join(_output_dir(), "<modul>_tests.dxf")
if not os.path.exists(path):
pytest.skip("<modul>_tests.dxf nicht vorhanden")
return ezdxf.readfile(path)
@pytest.fixture
def <modul>_ref_dxf():
path = os.path.join(_reference_dir(), "<modul>_ref.dxf")
if not os.path.exists(path):
pytest.skip("Referenz nicht vorhanden")
return ezdxf.readfile(path)
```
## Testklassen
### test_kreisel.py
| Klasse | Prueft |
|---|---|
| `TestKreiselAttributes` | Attribute (KREISELART, HOEHE), Block-Prefixe, Status |
| `TestKreiselGeometry` | DXF-Bloecke, Positionen, Kreis-Radien (400mm) |
| `TestKreiselReference` | Block-Anzahl und -Typen gegen Referenz-DXF |
### test_omniflo.py
| Klasse | Prueft |
|---|---|
| `TestOmnifloExportUnit` | Mock-Export: Merkmale, Datentypen, Vollstaendigkeit (ohne BricsCAD) |
| `TestOmnifloExportCSV` | CSV aus BricsCAD: Header, Spalten, JSON-Merkmale |
## Umgebungsvariablen
Werden von `bin\setenv.bat` gesetzt. Fuer Tests relevant:
| Variable | Beschreibung |
|---|---|
| `DXFMAKRO` | Projektwurzel |
| `DXFM_TESTS` | tests/-Verzeichnis |
| `DXFM_TESTDATA` | testdata/-Verzeichnis |
| `DXFM_TESTOUT` | output/-Verzeichnis |
| `DXFM_TESTREF` | reference/-Verzeichnis |
| `DXFM_OMNIFLO` | Pfad zu Omniflo-DXF-Dateien |
+221
View File
@@ -0,0 +1,221 @@
;; ============================================================
;; test_foerderer.lsp - Automatischer Integrationstest fuer VarioFoerderer
;;
;; Erzeugt 12 Variofoerderer (6x Auf, 6x Ab) mit deltaL=7000
;; und verschiedenen Hoehenstufen. Speichert:
;; - tests/output/foerderer_results.json (Ergebnisse)
;; - tests/output/foerderer_tests.dxf (Zeichnung)
;;
;; Voraussetzungen:
;; - SSG_LIB geladen (VarioFoerderer.lsp, ssg_core.lsp)
;; - Umgebungsvariable DXFMAKRO gesetzt
;;
;; Aufruf in BricsCAD:
;; (load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp"))
;; TEST_FOERDERER
;; ============================================================
;; --- Ergebnis eines Testfalls als JSON-String erzeugen ---
(defun foerderer:test-result-json (test-id richtung deltaL deltaH status
winkel L_GF L_VF /
json)
(setq json (strcat " {\n"
" \"test_id\": \"" test-id "\",\n"
" \"richtung\": \"" richtung "\",\n"
" \"deltaL\": " (rtos deltaL 2 0) ",\n"
" \"deltaH\": " (rtos deltaH 2 0) ",\n"
" \"status\": \"" status "\""))
(if winkel
(setq json (strcat json ",\n"
" \"winkel\": " (itoa winkel) ",\n"
" \"L_GF\": " (rtos L_GF 2 1) ",\n"
" \"L_VF\": " (rtos L_VF 2 1)))
)
(setq json (strcat json "\n }"))
json
)
;; ============================================================
;; C:TEST_FOERDERER - Hauptbefehl
;; ============================================================
(defun c:TEST_FOERDERER ( / deltaL deltaH richtung ergebnis
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
test-id)
;; Bibliothek initialisieren (laedt Block-Library und extrahiert Masse)
(if (not *lib-initialized*)
(init-bibliothek)
)
(ssg-start "TEST_FOERDERER" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq deltaL 7000)
(setq hoehen-liste '(0 1000 2000 3000 4000 5000))
(setq y-offset 0)
(setq idx 0)
(setq results-list '())
(setq anz-gebaut 0)
(setq anz-nicht-gebaut 0)
(princ "\n")
(princ "\n================================================================")
(princ "\n TEST_FOERDERER - Variofoerderer Integrationstest")
(princ "\n================================================================")
(princ (strcat "\n Distanz dL = " (rtos deltaL 2 0) " mm"))
(princ "\n Hoehenstufen: 0, 1000, 2000, 3000, 4000, 5000 mm")
(princ "\n Richtungen: Auf + Ab")
(princ "\n================================================================")
;; ==========================================================
;; TEIL 1: Aufwaerts-Tests (6 Foerderer)
;; ==========================================================
(foreach deltaH hoehen-liste
(setq idx (1+ idx))
(setq richtung "Auf")
(setq test-id (strcat "VF_Auf_" (rtos deltaH 2 0)))
(setq ergebnis (berechne-alle-winkel deltaL deltaH richtung))
(setq best-winkel (car ergebnis))
(setq L_GF (cadr ergebnis))
(setq L_VF (caddr ergebnis))
(if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0))
(progn
(setq anz-gebaut (1+ anz-gebaut))
(princ (strcat "\n " (itoa idx) ". " test-id " -> GEBAUT "
(itoa best-winkel) " Grad L_GF=" (rtos L_GF 2 1)
" L_VF=" (rtos L_VF 2 1)))
(foerderanlage-einfuegen deltaL deltaH richtung best-winkel
(/ L_GF 2.0) (/ L_GF 2.0) L_VF
(list 0 y-offset 0))
(setq results-list (cons
(foerderer:test-result-json test-id richtung deltaL deltaH
"GEBAUT" best-winkel L_GF L_VF)
results-list))
)
(progn
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n " (itoa idx) ". " test-id " -> NICHT_GEBAUT"))
(setq results-list (cons
(foerderer:test-result-json test-id richtung deltaL deltaH
"NICHT_GEBAUT" nil nil nil)
results-list))
)
)
(setq y-offset (- y-offset 200))
)
;; ==========================================================
;; TEIL 2: Abwaerts-Tests (6 Foerderer)
;; ==========================================================
(foreach deltaH hoehen-liste
(setq idx (1+ idx))
(setq richtung "Ab")
(setq test-id (strcat "VF_Ab_" (rtos deltaH 2 0)))
(if (< deltaH 1)
(progn
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n " (itoa idx) ". " test-id " -> GEOMETRISCH_UNMOEGLICH"))
(setq results-list (cons
(foerderer:test-result-json test-id richtung deltaL deltaH
"GEOMETRISCH_UNMOEGLICH" nil nil nil)
results-list))
)
(progn
(setq ergebnis (berechne-alle-winkel deltaL deltaH richtung))
(setq best-winkel (car ergebnis))
(setq L_GF (cadr ergebnis))
(setq L_VF (caddr ergebnis))
(if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0))
(progn
(setq anz-gebaut (1+ anz-gebaut))
(princ (strcat "\n " (itoa idx) ". " test-id " -> GEBAUT "
(itoa best-winkel) " Grad L_GF=" (rtos L_GF 2 1)
" L_VF=" (rtos L_VF 2 1)))
(foerderanlage-einfuegen deltaL deltaH richtung best-winkel
(/ L_GF 2.0) (/ L_GF 2.0) L_VF
(list 0 y-offset 0))
(setq results-list (cons
(foerderer:test-result-json test-id richtung deltaL deltaH
"GEBAUT" best-winkel L_GF L_VF)
results-list))
)
(progn
(setq anz-nicht-gebaut (1+ anz-nicht-gebaut))
(princ (strcat "\n " (itoa idx) ". " test-id " -> NICHT_GEBAUT"))
(setq results-list (cons
(foerderer:test-result-json test-id richtung deltaL deltaH
"NICHT_GEBAUT" nil nil nil)
results-list))
)
)
)
)
(setq y-offset (- y-offset 200))
)
;; ==========================================================
;; Zusammenfassung
;; ==========================================================
(princ "\n================================================================")
(princ (strcat "\n Ergebnis: " (itoa anz-gebaut) " GEBAUT, "
(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" "DXF" out-dxf)
(princ (strcat "\n DXF gespeichert: " out-dxf))
(ssg-end)
(princ "\n================================================================")
(princ "\n TEST_FOERDERER abgeschlossen.")
(princ "\n================================================================")
(princ)
)
+255
View File
@@ -0,0 +1,255 @@
;; ============================================================
;; test_kreisel.lsp - Automatischer Integrationstest fuer Kreisel
;;
;; Laedt Testfaelle aus tests/testdata/kreisel_tests.json,
;; fuegt Kreisel per insert und connect ein, sammelt
;; Ergebnisse und speichert:
;; - tests/output/kreisel_tests.dxf (Zeichnung mit Bloecken)
;; - tests/output/kreisel_results.json (Attribut-/Positions-Daten)
;;
;; Voraussetzungen:
;; - SSG_LIB geladen (KreiselInsert.lsp, ssg_core.lsp)
;; - Umgebungsvariable DXFMAKRO gesetzt
;;
;; Aufruf in BricsCAD:
;; (load "tests/test_kreisel.lsp")
;; TEST_KREISEL
;; ============================================================
;; --- Ergebnis eines Testfalls als JSON-String erzeugen ---
(defun kreisel:test-result-json (test-id status block-name block-handle
insert-point attribs /
json att-json tag val first)
(setq json (strcat " {\n"
" \"test_id\": \"" test-id "\",\n"
" \"status\": \"" status "\",\n"
" \"block_name\": \"" (if block-name block-name "") "\",\n"
" \"block_handle\": \"" (if block-handle block-handle "") "\",\n"
" \"insert_point\": ["
(if insert-point
(strcat (rtos (car insert-point) 2 1) ", "
(rtos (cadr insert-point) 2 1) ", "
(rtos (if (caddr insert-point) (caddr insert-point) 0.0) 2 1))
"0.0, 0.0, 0.0"
)
"],\n"
" \"actual_attributes\": {"))
;; Attribute als JSON
(setq first T)
(foreach att attribs
(setq tag (car att))
(setq val (cdr att))
(if (not first) (setq json (strcat json ",")))
(setq json (strcat json "\n \"" tag "\": \"" (if val val "") "\""))
(setq first nil)
)
(setq json (strcat json "\n }\n }"))
json
)
;; --- Einzelnen Insert-Testfall ausfuehren ---
(defun kreisel:run-insert-test (eintrag / id x y z abstand rotation typ
pt blockEnt ed attribs block-name
block-handle insert-point)
(setq id (omni:val eintrag "id"))
(setq x (omni:val eintrag "x"))
(setq y (omni:val eintrag "y"))
(setq z (omni:val eintrag "z"))
(setq abstand (omni:val eintrag "abstand"))
(setq rotation (omni:val eintrag "rotation"))
(setq typ (omni:val eintrag "typ"))
(if (numberp x) (setq x (float x)))
(if (numberp y) (setq y (float y)))
(if (numberp z) (setq z (float z)))
(if (numberp abstand) (setq abstand (float abstand)))
(if (numberp rotation) (setq rotation (float rotation)))
(setq pt (list x y z))
(princ (strcat "\n [INSERT] " id " -> (" (rtos x 2 0) ", " (rtos y 2 0)
", " (rtos z 2 0) ") A=" (rtos abstand 2 0)
" R=" (rtos rotation 2 1) " " typ))
(setq blockEnt (kreisel-insert-script pt abstand rotation typ z))
(if blockEnt
(progn
(setq ed (entget blockEnt))
(setq block-name (cdr (assoc 2 ed)))
(setq block-handle (cdr (assoc 5 ed)))
(setq insert-point (cdr (assoc 10 ed)))
(setq attribs (ssg-attrib-read blockEnt))
(princ (strcat " OK: " block-name))
(kreisel:test-result-json id "executed" block-name block-handle
insert-point attribs)
)
(progn
(princ (strcat " FEHLER: " id))
(kreisel:test-result-json id "failed" nil nil nil nil)
)
)
)
;; --- Einzelnen Connect-Testfall ausfuehren ---
(defun kreisel:run-connect-test (eintrag / id sx sy sz ex ey ez typ
ptStart ptEnd blockEnt ed attribs
block-name block-handle insert-point)
(setq id (omni:val eintrag "id"))
(setq sx (omni:val eintrag "start_x"))
(setq sy (omni:val eintrag "start_y"))
(setq sz (omni:val eintrag "start_z"))
(setq ex (omni:val eintrag "end_x"))
(setq ey (omni:val eintrag "end_y"))
(setq ez (omni:val eintrag "end_z"))
(setq typ (omni:val eintrag "typ"))
(if (numberp sx) (setq sx (float sx)))
(if (numberp sy) (setq sy (float sy)))
(if (numberp sz) (setq sz (float sz)))
(if (numberp ex) (setq ex (float ex)))
(if (numberp ey) (setq ey (float ey)))
(if (numberp ez) (setq ez (float ez)))
(setq ptStart (list sx sy sz))
(setq ptEnd (list ex ey ez))
(princ (strcat "\n [CONNECT] " id
" -> (" (rtos sx 2 0) "," (rtos sy 2 0)
") -> (" (rtos ex 2 0) "," (rtos ey 2 0) ") " typ))
(setq blockEnt (kreisel-connect-script ptStart ptEnd typ sz))
(if blockEnt
(progn
(setq ed (entget blockEnt))
(setq block-name (cdr (assoc 2 ed)))
(setq block-handle (cdr (assoc 5 ed)))
(setq insert-point (cdr (assoc 10 ed)))
(setq attribs (ssg-attrib-read blockEnt))
(princ (strcat " OK: " block-name))
(kreisel:test-result-json id "executed" block-name block-handle
insert-point attribs)
)
(progn
(princ (strcat " FEHLER: " id))
(kreisel:test-result-json id "failed" nil nil nil nil)
)
)
)
;; ============================================================
;; 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
anzahl-ok anzahl-fehler)
(ssg-start "TEST_KREISEL" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
;; Testdaten laden
(setq tests-json-pfad
(strcat (getenv "DXFMAKRO") "/tests/testdata/kreisel_tests.json"))
(if (not (findfile tests-json-pfad))
(progn
(princ (strcat "\n[TEST_KREISEL] FEHLER: " tests-json-pfad " nicht gefunden!"))
(ssg-end)
(princ)
)
(progn
(setq testfaelle (omni:load-json tests-json-pfad))
(if (null testfaelle)
(progn
(princ "\n[TEST_KREISEL] FEHLER: Testdaten konnten nicht geladen werden.")
(ssg-end)
(princ)
)
(progn
(princ "\n================================================================")
(princ "\n TEST_KREISEL")
(princ (strcat "\n " (itoa (length testfaelle)) " Testfaelle geladen"))
(princ "\n================================================================")
(setq results-list nil)
(setq anzahl-ok 0)
(setq anzahl-fehler 0)
;; Testfaelle ausfuehren
(foreach eintrag testfaelle
(setq func (omni:val eintrag "function"))
(setq result-json
(cond
((= func "insert")
(kreisel:run-insert-test eintrag))
((= func "connect")
(kreisel:run-connect-test eintrag))
(T
(princ (strcat "\n WARNUNG: Unbekannte Funktion: " func))
nil)
)
)
(if result-json
(progn
(setq results-list (cons result-json results-list))
(if (vl-string-search "executed" result-json)
(setq anzahl-ok (1+ anzahl-ok))
(setq anzahl-fehler (1+ anzahl-fehler))
)
)
)
)
;; Zusammenfassung
(princ "\n================================================================")
(princ (strcat "\n Ergebnis: " (itoa anzahl-ok) " OK, "
(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" "DXF" out-dxf)
(princ (strcat "\n DXF gespeichert: " out-dxf))
(ssg-end)
(princ "\n================================================================")
(princ "\n TEST_KREISEL abgeschlossen.")
(princ "\n================================================================")
(princ)
)
)
)
)
)
+262
View File
@@ -0,0 +1,262 @@
;; ============================================================
;; test_ks.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)
;; Gruppe 2: Alle Boegen aufwaerts (in Z verschoben)
;; Gruppe 3: Alle Boegen abwaerts (in Z verschoben)
;;
;; Pro Gruppe:
;; Reihe A: nach KS_EIN ausgerichtet
;; Reihe B: nach KS_AUS ausgerichtet
;; Luecke von 400mm zwischen den Reihen
;;
;; Speichert:
;; - tests/output/ks_results.json (Ergebnisse)
;; - tests/output/ks_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"))
;; TEST_KSEINAUS
;; ============================================================
;; --- Ergebnis eines Testfalls als JSON-String erzeugen ---
(defun ks:test-result-json (test-id block-name gruppe ks-type status /
json)
(setq json (strcat " {\n"
" \"test_id\": \"" test-id "\",\n"
" \"block_name\": \"" (if block-name block-name "") "\",\n"
" \"gruppe\": \"" gruppe "\",\n"
" \"ks_type\": \"" ks-type "\",\n"
" \"status\": \"" status "\"\n"
" }"))
json
)
;; --- 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
gruppe results-in /
bname block-obj ks-data ks-ein ks-aus
insert-pt offset-vec y-pos idx
test-id results-out)
(setq results-out results-in)
;; --- Reihe A: nach KS_EIN ---
(princ "\n Reihe KS_EIN:")
(setq y-pos y-start)
(setq idx 0)
(foreach bname namen
(setq idx (1+ idx))
(setq test-id (strcat gruppe "_KS_EIN_" (itoa idx)))
(setq insert-pt (list x-start y-pos z-offset))
(setq block-obj (vla-InsertBlock modelspace
(vlax-3D-point insert-pt)
bname 1.0 1.0 1.0 0))
(setq ks-data (extract-ks-from-block block-obj))
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
(if ks-ein
(progn
(setq offset-vec (list (- x-start (car (car ks-ein)))
(- y-pos (cadr (car ks-ein)))
(- z-offset (caddr (car ks-ein)))))
(vla-Move block-obj
(vlax-3D-point '(0 0 0))
(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")
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")
results-out))
)
)
(setq y-pos (- y-pos y-abstand))
)
;; --- Luecke ---
(setq y-pos (- y-pos y-luecke))
;; --- Reihe B: nach KS_AUS ---
(princ "\n Reihe KS_AUS:")
(setq idx 0)
(foreach bname namen
(setq idx (1+ idx))
(setq test-id (strcat gruppe "_KS_AUS_" (itoa idx)))
(setq insert-pt (list x-start y-pos z-offset))
(setq block-obj (vla-InsertBlock modelspace
(vlax-3D-point insert-pt)
bname 1.0 1.0 1.0 0))
(setq ks-data (extract-ks-from-block block-obj))
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
(if ks-aus
(progn
(setq offset-vec (list (- x-start (car (car ks-aus)))
(- y-pos (cadr (car ks-aus)))
(- z-offset (caddr (car ks-aus)))))
(vla-Move block-obj
(vlax-3D-point '(0 0 0))
(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")
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")
results-out))
)
)
(setq y-pos (- y-pos y-abstand))
)
;; Rueckgabe: (naechste-y-pos . results-list)
(cons y-pos results-out)
)
;; ============================================================
;; 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)
;; Bibliothek initialisieren
(if (not *lib-initialized*)
(init-bibliothek)
)
(ssg-start "TEST_KSEINAUS" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq y-abstand 200)
(setq y-luecke 400)
(setq z-bogen 2500)
(setq results-list '())
;; Gruppe 1: Stationaere Elemente
(setq stationen (list
"_3D_AS_90_links"
"Staustrecke_Separator_SP_300_mm"
"Vario_Umlenkstation_500mm"
"Vario_Motorstation_500mm"
"_3D_ES_90_links"
))
;; Gruppe 2+3: Boegen sammeln
(setq boegen-auf-liste '())
(setq boegen-ab-liste '())
(foreach w '(3 6 9 12 15 18 21 27 33 39 45 51)
(setq bname (strcat "Vario_Bogen_auf_" (itoa w) grad-zeichen))
(if (tblsearch "BLOCK" bname)
(setq boegen-auf-liste (append boegen-auf-liste (list bname)))
)
(setq bname (strcat "Vario_Bogen_ab_" (itoa w) grad-zeichen))
(if (tblsearch "BLOCK" bname)
(setq boegen-ab-liste (append boegen-ab-liste (list bname)))
)
)
(princ "\n================================================================")
(princ "\n TEST_KSEINAUS - KS-Ausrichtungstest")
(princ (strcat "\n Stationen: " (itoa (length stationen))))
(princ (strcat "\n Boegen auf: " (itoa (length boegen-auf-liste))))
(princ (strcat "\n Boegen ab: " (itoa (length boegen-ab-liste))))
(princ (strcat "\n Z-Offset Boegen: " (rtos z-bogen 2 0) " mm"))
(princ "\n================================================================")
;; 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
"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
"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
"Boegen_Ab" results-list))
(setq y-pos (car reihe-result))
(setq results-list (cdr reihe-result))
;; Zusammenfassung
(setq anz-ok 0)
(setq anz-fehlt 0)
(foreach r results-list
(if (vl-string-search "\"OK\"" r)
(setq anz-ok (1+ anz-ok))
(setq anz-fehlt (1+ anz-fehlt))
)
)
(princ "\n================================================================")
(princ (strcat "\n Ergebnis: " (itoa anz-ok) " OK, "
(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" "DXF" out-dxf)
(princ (strcat "\n DXF gespeichert: " out-dxf))
(ssg-end)
(princ "\n================================================================")
(princ "\n TEST_KSEINAUS abgeschlossen.")
(princ "\n================================================================")
(princ)
)
+71
View File
@@ -0,0 +1,71 @@
;; ============================================================
;; 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
;;
;; Ergebnisse werden jeweils in tests/output/ gespeichert.
;;
;; Voraussetzungen:
;; - SSG_LIB geladen
;; - Umgebungsvariable DXFMAKRO gesetzt
;;
;; Aufruf in BricsCAD:
;; (load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp"))
;; 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"))
;; 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))
(setq idx 0)
(princ "\n")
(princ "\n================================================================")
(princ "\n SSG_RUN_ALL_TESTS")
(princ (strcat "\n " (itoa anz) " Testmodule"))
(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"))
)
)
test-dateien
test-befehle
)
(princ "\n\n================================================================")
(princ "\n SSG_RUN_ALL_TESTS abgeschlossen.")
(princ (strcat "\n Ergebnisse in: " (getenv "DXFMAKRO") "/tests/output/"))
(princ "\n================================================================")
(princ)
)