;; ============================================================ ;; test_mubea.lsp - Integrationstest: erzeugt das Mubea-Gesamtmodell ;; ;; Liest tests/testdata/mubea.json und baut in EINER Zeichnung: ;; - Kreisel (Eintraege mit "id", Block KREISEL_*) via kreisel-insert-script ;; - Vario (test_id "VF_*") Block VF_* via variofoerderer-einfuegen ;; + vf-block-erstellen ;; (deltaL/L_VF werden fuer winkel+deltaH geloest, L_GF Split 500/4230; ;; "anzahl"/"delta_y"/"delta_x" wie bei Gefaelle: Template->mehrere ;; Foerderer mit fortlaufend suffixiertem test_id, _01.._anzahl) ;; - Gefaelle (test_id "GF_*", Modus 1) Block GF_* via gefaellestrecke-einfuegen ;; - Separator (Eintraege mit "block") Block S-LP/Separator_SP via _.INSERT ;; ;; Speichert (via SSG_RUN_ALL_TESTS bei "save":"dxf"): ;; tests/output/mubea_tests.dxf ;; tests/output/mubea_results.json (via mubea:export-results) ;; ;; Voraussetzungen: ;; - SSG_LIB geladen (KreiselInsert, VarioFoerderer, Gefaellestrecke, ;; SSG_LIB_Commands, ssg_core, vf_core) ;; - Umgebungsvariable DXFMAKRO gesetzt ;; ;; Aufruf in BricsCAD: ;; (load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp")) ;; TEST_MUBEA ;; ============================================================ ;; --- Ergebnis eines Bau-Schritts als JSON-String erzeugen --- (defun mubea:result-json (test-id kind status block-name block-handle insert-point attribs / json tag val first) (setq json (strcat " {\n" " \"test_id\": \"" test-id "\",\n" " \"kind\": \"" kind "\",\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\": {")) (setq first T) (foreach att attribs (setq tag (car att) 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 ) ;; --- Aus einer Block-ENAME ein Ergebnis-JSON erzeugen --- (defun mubea:ent-json (test-id kind ent / ed) (if ent (progn (setq ed (entget ent)) (mubea:result-json test-id kind "executed" (cdr (assoc 2 ed)) (cdr (assoc 5 ed)) (cdr (assoc 10 ed)) (ssg-attrib-read ent))) (mubea:result-json test-id kind "failed" nil nil nil nil)) ) ;; --- Letzten INSERT mit Blocknamen-Praefix (rueckwaerts) suchen --- (defun mubea:last-insert-prefix (pref / ent found ed bn) (setq ent (entlast)) (while (and ent (null found)) (setq ed (entget ent) bn (cdr (assoc 2 ed))) (if (and (= (cdr (assoc 0 ed)) "INSERT") bn (>= (strlen bn) (strlen pref)) (= (substr bn 1 (strlen pref)) pref)) (setq found ent)) (setq ent (entprev ent))) found ) ;; ============================================================ ;; Bau-Funktionen je Elementtyp ;; ============================================================ ;; --- Kreisel (wie test_kreisel: kreisel-insert-script) --- (defun mubea:build-kreisel (e / id x y z abstand rotation typ pt ent) (setq id (ssg-val e "id") x (float (ssg-val e "x")) y (float (ssg-val e "y")) z (float (ssg-val e "z")) abstand (float (ssg-val e "abstand")) rotation (float (ssg-val e "rotation")) typ (ssg-val e "typ")) (if (null typ) (setq typ "STANDARD")) (setq pt (list x y z)) (princ (strcat "\n [KREISEL] " id " -> (" (rtos x 2 0) "," (rtos y 2 0) "," (rtos z 2 0) ") A=" (rtos abstand 2 0) " R=" (rtos rotation 2 1))) (setq ent (kreisel-insert-script pt abstand rotation typ z)) (mubea:ent-json id "kreisel" ent) ) ;; --- Vario (VF_*): L_GF/L_VF fuer gegebenes deltaL+deltaH+winkel loesen, dann bauen --- ;; deltaL ist (wie bei der Gefaellestrecke) die horizontale PROJIZIERTE ;; Gesamtlaenge des VF (Vorlauf L_GF1 + Foerderer L_VF + Nachlauf L_GF2 + ;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/object_data.md 3.1 - ;; KEIN abgeleiteter Wert. "winkel" erzwingt einen bestimmten Bogenwinkel aus ;; der Kandidatenliste von berechne-alle-winkel (wie foerderer:winkel- ;; erzwingen in test_foerderer.lsp), statt den automatisch kleinsten ;; gueltigen Winkel zu nehmen. L_GF1 aus JSON ist der Vorlauf-Zielwert; ;; L_GF2 (Nachlauf) ist der Rest (L_GF_gesamt - L_GF1). (defun mubea:build-vario-one (tid richtung deltaL deltaH winkel-soll gf1-ziel seite hz startpunkt / ergebnis winkel-treffer best-winkel L_GF L_VF gf1 gf2 hoehe-bis lastEnt ent) (if (or (null seite) (= seite "")) (setq seite "links")) (if (null hz) (setq hz 0.0) (setq hz (float hz))) (princ (strcat "\n [VARIO] " tid " -> deltaL=" (rtos deltaL 2 0) " deltaH=" (rtos deltaH 2 0) " Winkel(soll)=" (if winkel-soll (itoa (fix winkel-soll)) "auto") " L_GF1-Ziel=" (rtos gf1-ziel 2 0))) (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung nil)) (setq best-winkel (car ergebnis) L_GF (cadr ergebnis) L_VF (caddr ergebnis)) (if (numberp winkel-soll) (progn (setq winkel-treffer (car (vl-remove-if-not '(lambda (a) (= (car a) (fix winkel-soll))) (cadddr ergebnis)))) (if (and winkel-treffer (cadddr winkel-treffer) (numberp (cadr winkel-treffer)) (numberp (caddr winkel-treffer)) (> (cadr winkel-treffer) 0) (> (caddr winkel-treffer) 0)) (setq best-winkel (car winkel-treffer) L_GF (cadr winkel-treffer) L_VF (caddr winkel-treffer)) (setq best-winkel nil L_GF nil L_VF nil)))) (if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0)) (progn (setq gf1 (min gf1-ziel L_GF)) (setq gf2 (max 0.0 (- L_GF gf1))) (princ (strcat " -> Winkel=" (itoa best-winkel) " L_GF=" (rtos L_GF 2 1) " L_VF=" (rtos L_VF 2 1) " L_GF1=" (rtos gf1 2 1) " L_GF2=" (rtos gf2 2 1))) (setq hoehe-bis (if (= richtung "Auf") deltaH (- deltaH))) (setq lastEnt (vf-lastent-ohne-attribute)) (variofoerderer-einfuegen deltaL deltaH richtung best-winkel gf1 gf2 L_VF startpunkt seite hz) (setq ent (vf-block-erstellen "standard" seite 1 0 0 hoehe-bis deltaH deltaL L_VF gf1 gf2 richtung best-winkel startpunkt lastEnt hz "0" "Schoenenberger Geruest")) (if (or (null ent) (/= (type ent) 'ENAME)) (setq ent (mubea:last-insert-prefix "VF_"))) ;; SSG_VF_EDIT-XDATA schreiben (wie vfs-standard-dialog-berechnen- ;; einfuegen) - sonst erkennt VARIOFOERDERER_EDIT den Block beim ;; Doppelklick nicht als "per Dialog erstellt" und verweigert die ;; Bearbeitung (vfs-edit-keine-xdata). (if (and ent (= (type ent) 'ENAME)) (vfs-xdata-schreiben ent hz)) (mubea:ent-json tid "vario" ent)) (progn (princ (strcat "\n FEHLER: deltaL=" (rtos deltaL 2 0) " bei Winkel " (if winkel-soll (rtos winkel-soll 2 0) "auto") " nicht loesbar (kein gueltiges L_GF/L_VF).")) (mubea:result-json tid "vario" "failed" nil nil nil nil))) ) ;; --- Vario(s) aus einem Template-Eintrag bauen --- ;; Wie mubea:build-gf: "anzahl" identische Kopien, je um "delta_y"/"delta_x" (mm) ;; versetzt (nur startpunkt x/y - Default 1/0/0 -> genau ein Foerderer wie bisher). ;; Bei mehreren Kopien wird "test_id" fortlaufend suffixiert (_01.._anzahl), ;; bei genau einer Kopie bleibt der Template-Name erhalten (kompatibel zur ;; frueheren Einzelbenennung). ;; Rueckgabe: LISTE von Ergebnis-JSON-Strings (eine je Kopie). (defun mubea:build-vario (e / tid0 richtung deltaL deltaH winkel-soll gf1-ziel seite hz start0 anzahl dy dx i off nr tid startpunkt ergebnisse) (setq tid0 (ssg-val e "test_id") richtung (ssg-val e "richtung") deltaL (float (ssg-val e "deltaL")) deltaH (float (ssg-val e "deltaH")) winkel-soll(ssg-val e "winkel") gf1-ziel (float (ssg-val e "L_GF1")) seite (ssg-val e "seite") hz (ssg-val e "hz") start0 (list (float (ssg-val e "x")) (float (ssg-val e "y")) (float (ssg-val e "z"))) anzahl (ssg-val e "anzahl") dy (ssg-val e "delta_y") dx (ssg-val e "delta_x")) (if (or (null anzahl) (< anzahl 1)) (setq anzahl 1)) (setq dy (if dy (float dy) 0.0)) (setq dx (if dx (float dx) 0.0)) (setq ergebnisse '() i 0) (while (< i anzahl) (setq off (float i)) (setq nr (1+ i)) (setq tid (if (> anzahl 1) (strcat tid0 "_" (if (< nr 10) (strcat "0" (itoa nr)) (itoa nr))) tid0)) (setq startpunkt (list (+ (car start0) (* dx off)) (+ (cadr start0) (* dy off)) (caddr start0))) (setq ergebnisse (cons (mubea:build-vario-one tid richtung deltaL deltaH winkel-soll gf1-ziel seite hz startpunkt) ergebnisse)) (setq i (1+ i)) ) (reverse ergebnisse) ) ;; --- Gefaellestrecke: Init-Konflikt umgehen ----------------------------- ;; gefaellestrecke-einfuegen ruft "(if (not *lib-initialized*) (gf-init- ;; bibliothek))" auf (Gefaellestrecke.lsp:1567) - dasselbe Flag, das ;; init-bibliothek (Vario, vf_standard.lsp) fuer SEINE EIGENEN aus-dx/ein-dx/ ;; aus-dz/ein-dz setzt. Da C:TEST_MUBEA zuerst den Vario baut (init- ;; bibliothek setzt *lib-initialized*=T), wuerde gf-init-bibliothek NIE mehr ;; laufen und die Gefaellestrecke mit den (voellig andersartigen) Vario- ;; Bogenmassen statt den echten AS_Element/ES_Element-Massen rechnen - genau ;; das fuehrte zur falschen Zielhoehe im ersten TEST_MUBEA-Lauf. Fix: Flag ;; kurz zuruecksetzen, gf-init-bibliothek EINMAL erzwingen (danach haben ;; aus-dx/ein-dx/aus-dz/ein-dz die korrekten GF-spezifischen Werte). (defun mubea:ensure-gf-init ( / ) (if (not *mubea-gf-init-done*) (progn (setq *lib-initialized* nil) (gf-init-bibliothek) (setq *lib-initialized* t) (setq *mubea-gf-init-done* T) ) ) ) ;; --- Eine einzelne Gefaellestrecke bauen (Modus 1) --- ;; Aufbau AUSSCHLIESSLICH aus Anfangspunkt (start-mm) und horizontaler ;; Gesamtlaenge deltaL - KEIN Endpunkt (wie Produktion/gefaellestrecke.dcl ;; Modus 1, siehe object_data.md 2.1). L_stau wird aus deltaL abgeleitet ;; (identische Formel wie test_gefaellestrecke.lsp): ;; L_stau = (deltaL - aus-dx - ein-dx - sep_x) / cos(v) ;; sep_x = 300 * cos(v), v = Element-Winkel (winkel_grad, Default 3 Grad) ;; Die Zielhoehe ergibt sich aus L_stau/Winkel (kein Ziel-Hoehen-Parameter). ;; Rueckgabe: Ergebnis-JSON-String. (defun mubea:build-gf-one (tid start-mm deltaL hz as-seite es-seite as-winkel es-winkel winkel / rad sep-x test-L_stau ent) (mubea:ensure-gf-init) ;; Element-Masse fuer die gewaehlte AS/ES-Variante setzen, damit aus-dx/ein-dx ;; zur Variante (90/30 Grad) passen. Danach wieder auf 90 zuruecksetzen. (vf-set-as-masse as-winkel as-seite) (vf-set-es-masse es-winkel es-seite) (setq rad (* winkel (/ pi 180.0))) (setq sep-x (* 300.0 (cos rad))) (setq test-L_stau (/ (- deltaL (float aus-dx) (float ein-dx) sep-x) (cos rad))) (princ (strcat "\n [GF] " tid " -> Start=(" (rtos (car start-mm) 2 0) "," (rtos (cadr start-mm) 2 0) "," (rtos (caddr start-mm) 2 0) ") hz=" (rtos hz 2 0) " deltaL=" (rtos deltaL 2 0) " winkel=" (rtos winkel 2 2) " L_stau=" (rtos test-L_stau 2 1))) (setq ent (car (gefaellestrecke-einfuegen test-L_stau winkel start-mm as-seite es-seite hz deltaL as-winkel es-winkel "0" "Schoenenberger Geruest"))) (vf-set-as-masse "90" as-seite) (vf-set-es-masse "90" es-seite) (mubea:ent-json tid "gefaellestrecke" ent) ) ;; --- Gefaellestrecke(n) aus einem Template-Eintrag bauen --- ;; Ein einziger JSON-Eintrag beschreibt per "anzahl" + "delta_y"/"delta_x" eine ;; ganze Reihe identischer Gefaellestrecken (statt 20 Einzeleintraege). Element i ;; (1..anzahl) wird um (i-1)*delta in Y bzw. X versetzt (nur start_mm - es gibt ;; keinen Endpunkt). Fehlen anzahl/delta -> genau eine Strecke am angegebenen Ort. ;; Aus JSON: start_mm, deltaL_mm, hz_grad, as_seite, es_seite, as_winkel, ;; es_winkel, winkel_grad (Default 3.0), anzahl (Default 1), delta_y ;; (Default 0), delta_x (Default 0). ;; Rueckgabe: LISTE von Ergebnis-JSON-Strings (eine je Kopie). (defun mubea:build-gf (e / tid0 start0 deltaL hz as-seite es-seite as-winkel es-winkel winkel anzahl dy dx i off nr tid s-mm ergebnisse) (setq tid0 (ssg-val e "test_id") start0 (mapcar 'float (ssg-val e "start_mm")) deltaL (float (ssg-val e "deltaL_mm")) hz (float (ssg-val e "hz_grad")) as-seite (ssg-val e "as_seite") es-seite (ssg-val e "es_seite") as-winkel(ssg-val e "as_winkel") es-winkel(ssg-val e "es_winkel") winkel (ssg-val e "winkel_grad") anzahl (ssg-val e "anzahl") dy (ssg-val e "delta_y") dx (ssg-val e "delta_x")) (if (or (null as-seite) (= as-seite "")) (setq as-seite "links")) (if (or (null es-seite) (= es-seite "")) (setq es-seite "links")) (if (or (null as-winkel) (= as-winkel "")) (setq as-winkel "90")) (if (or (null es-winkel) (= es-winkel "")) (setq es-winkel "90")) (setq winkel (if winkel (float winkel) 3.0)) (if (or (null anzahl) (< anzahl 1)) (setq anzahl 1)) (setq dy (if dy (float dy) 0.0)) (setq dx (if dx (float dx) 0.0)) (setq ergebnisse '() i 0) (while (< i anzahl) (setq off (float i)) (setq nr (1+ i)) ;; Bei mehreren Kopien fortlaufende ID GF_Mubea_01.. bilden (kompatibel zur ;; frueheren Einzelbenennung); bei genau einer Kopie den Template-Namen behalten. (setq tid (if (> anzahl 1) (strcat tid0 "_" (if (< nr 10) (strcat "0" (itoa nr)) (itoa nr))) tid0)) (setq s-mm (list (+ (car start0) (* dx off)) (+ (cadr start0) (* dy off)) (caddr start0))) (setq ergebnisse (cons (mubea:build-gf-one tid s-mm deltaL hz as-seite es-seite as-winkel es-winkel winkel) ergebnisse)) (setq i (1+ i)) ) (reverse ergebnisse) ) ;; --- Ein einzelner Separator: Blockdefinition laden, dann per Name einfuegen --- ;; Verwendet den in JSON genannten Block; faellt auf Separator_SP zurueck ;; (Block der "Separator einfuegen"-Routine ILS_SEPARATOR_INSERT). ;; Nutzt ssg-ils-block-laden (wie Kreisel/GF/VF), um den Block vorab zu ;; definieren, dann klassisches "_.INSERT eff pt "" "" rot" (wie ueberall sonst ;; im Projekt, z.B. omni:insert-dxf/KreiselInsert). NEUE Bloecke (z.B. "Scanner") ;; koennen dabei eine zusaetzliche Rueckfrage einschieben, die die feste ;; Antwortfolge verschiebt und das INSERT nicht sauber beendet (CMDACTIVE bleibt ;; > 0) - dieselbe Absicherung wie in ssg-ils-block-laden-dim (Zeilen 418f.) und ;; omni:insert-dxf (Zeile 980): nach dem INSERT verbleibende Prompts mit Leer- ;; Antworten (Enter) abfangen, bis der Befehl sauber beendet ist. (defun mubea:build-separator-one (tid blockname pt rot / eff) (princ (strcat "\n [SEP] " tid " '" (if blockname blockname "?") "' -> (" (rtos (car pt) 2 0) "," (rtos (cadr pt) 2 0) "," (rtos (caddr pt) 2 0) ") R=" (rtos rot 2 0))) ;; NICHT (and blockname (ssg-ils-block-laden blockname)) verwenden: AutoLISPs ;; AND liefert bei mehreren wahren Ausdruecken T zurueck, NICHT den letzten ;; Wert (anders als z.B. in Common Lisp/Scheme) - eff waere dann bei einem ;; erfolgreich direkt gefundenen Block (z.B. "Scanner", das NICHT ueber den ;; Separator_SP-Fallback laeuft) das Symbol T statt des Blocknamen-Strings, ;; und das anschliessende "_.INSERT" wuerde einen Block namens T einfuegen. (setq eff (if blockname (ssg-ils-block-laden blockname))) (if (null eff) (setq eff (ssg-ils-block-laden "Separator_SP"))) (if eff (progn (command "_.INSERT" eff pt "" "" rot) (while (> (getvar "CMDACTIVE") 0) (command "")) (mubea:ent-json tid "separator" (entlast))) (progn ;; Kein Block gefunden -> sichtbaren Platzhalter zeichnen (if (not (tblsearch "LAYER" "MUBEA_SEPARATOR")) (entmake (list '(0 . "LAYER") '(2 . "MUBEA_SEPARATOR") '(70 . 0) '(62 . 1)))) (entmake (list '(0 . "CIRCLE") (cons 10 pt) (cons 40 150.0) '(8 . "MUBEA_SEPARATOR"))) (princ " (Block fehlt - Platzhalter)") (mubea:result-json tid "separator" "placeholder" (if blockname blockname "S-LP") nil pt nil))) ) ;; --- Separator(en) aus einem Eintrag bauen (Eintraege mit "block") --- ;; Wie mubea:build-gf: "anzahl" identische Kopien, je um "delta_y"/"delta_x" ;; (mm) versetzt (Default 1/0/0 -> genau ein Separator am angegebenen Ort). ;; Namensbasis fuer die Kopien: "test_id", falls angegeben (erzeugt ;; "_01".."_anzahl"), sonst Fallback "SEPARATOR_" wie ;; bisher (Einzel-Separatoren ohne "test_id" bleiben dadurch unveraendert). ;; "assigned_to" bleibt reine Dokumentation und wird hier NICHT zur Namens- ;; bildung verwendet, da mehrere Separatoren denselben assigned_to-Wert teilen ;; koennen (z.B. mehrere S-LP-Eintraege mit assigned_to "GF_Mubea_01"). ;; Rueckgabe: LISTE von Ergebnis-JSON-Strings (eine je Kopie). (defun mubea:build-separator (e idx / blockname x0 y0 z rot tid0 anzahl dy dx i nr tid pt ergebnisse) (setq blockname (ssg-val e "block") x0 (float (ssg-val e "x")) y0 (float (ssg-val e "y")) z (float (ssg-val e "z")) rot (ssg-val e "rotation") tid0 (cond ((ssg-val e "test_id")) ((strcat "SEPARATOR_" (itoa idx)))) anzahl (ssg-val e "anzahl") dy (ssg-val e "delta_y") dx (ssg-val e "delta_x")) (if (null rot) (setq rot 0)) (setq rot (float rot)) (if (or (null anzahl) (< anzahl 1)) (setq anzahl 1)) (setq dy (if dy (float dy) 0.0)) (setq dx (if dx (float dx) 0.0)) (setq ergebnisse '() i 0) (while (< i anzahl) (setq nr (1+ i)) (setq tid (if (> anzahl 1) (strcat tid0 "_" (if (< nr 10) (strcat "0" (itoa nr)) (itoa nr))) tid0)) (setq pt (list (+ x0 (* dx (float i))) (+ y0 (* dy (float i))) z)) (setq ergebnisse (cons (mubea:build-separator-one tid blockname pt rot) ergebnisse)) (setq i (1+ i)) ) (reverse ergebnisse) ) ;; --- JSON-Export der Mubea-Ergebnisse --- (defun mubea:export-results (tests-out-dir / out-json f first) (if (null *mubea-test-results*) (princ "\n Keine Mubea-Ergebnisse vorhanden.") (progn (vl-mkdir tests-out-dir) (setq out-json (strcat tests-out-dir "/mubea_results.json")) (setq f (open out-json "w")) (if f (progn (write-line "[" f) (setq first T) (foreach r *mubea-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_MUBEA - Hauptbefehl ;; ============================================================ (defun c:TEST_MUBEA ( / json-datei daten eintrag tid blk res r results-list sep-idx anz-ok anz-fehler kind) ;; Benoetigte Feature-Module laden (ssg-ensure "KreiselInsert") (ssg-ensure "VarioFoerderer") (ssg-ensure "Gefaellestrecke") (ssg-ensure "SSG_LIB_Commands") (ssg-start "TEST_MUBEA" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) ;; Block-Bibliothek (Bogen-/AS-/ES-Masse) initialisieren - fuer Vario+GF noetig (if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek)) ;; Cache fuer GF-Init-Workaround pro Lauf zuruecksetzen ;; (siehe mubea:ensure-gf-init weiter oben) (setq *mubea-gf-init-done* nil) ;; Testdaten laden (setq json-datei (strcat (getenv "DXFMAKRO") "/tests/testdata/mubea.json")) (if (not (findfile json-datei)) (progn (princ (strcat "\n[TEST_MUBEA] FEHLER: " json-datei " nicht gefunden!")) (ssg-end) (exit))) (setq daten (ssg-load-json json-datei)) (if (null daten) (progn (princ "\n[TEST_MUBEA] FEHLER: Testdaten konnten nicht geladen werden.") (ssg-end) (exit))) (princ "\n\n================================================================") (princ "\n TEST_MUBEA - Mubea-Gesamtmodell") (princ (strcat "\n " (itoa (length daten)) " Eintraege geladen")) (princ "\n================================================================") (setq results-list '() sep-idx 0 anz-ok 0 anz-fehler 0) (foreach eintrag daten (setq tid (ssg-val eintrag "test_id")) (setq res (cond ;; Separator: hat "block" ((ssg-val eintrag "block") (setq sep-idx (1+ sep-idx)) (mubea:build-separator eintrag sep-idx)) ;; Kreisel: hat "id" ((ssg-val eintrag "id") (mubea:build-kreisel eintrag)) ;; Vario: test_id "VF_*" ((and tid (>= (strlen tid) 3) (= (substr tid 1 3) "VF_")) (mubea:build-vario eintrag)) ;; Gefaellestrecke: test_id "GF_*" ((and tid (>= (strlen tid) 3) (= (substr tid 1 3) "GF_")) (mubea:build-gf eintrag)) (T (princ (strcat "\n WARNUNG: Unbekannter Eintrag uebersprungen")) nil))) ;; mubea:build-gf liefert eine LISTE (Template -> mehrere Strecken), die ;; uebrigen Builder je einen String. Beides einheitlich einsammeln. (if res (progn (if (= (type res) 'STR) (setq res (list res))) (foreach r res (setq results-list (cons r results-list)) (if (or (vl-string-search "\"executed\"" r) (vl-string-search "\"placeholder\"" r)) (setq anz-ok (1+ anz-ok)) (setq anz-fehler (1+ anz-fehler))))))) (princ "\n================================================================") (princ (strcat "\n Ergebnis: " (itoa anz-ok) " OK, " (itoa anz-fehler) " Fehler")) (princ "\n================================================================") (setq *mubea-test-results* (reverse results-list)) (ssg-end) (princ "\n TEST_MUBEA abgeschlossen.") (princ) )