diff --git a/tests/README.md b/tests/README.md index cc2f7a0..4d22346 100644 --- a/tests/README.md +++ b/tests/README.md @@ -253,6 +253,32 @@ Felder: ] ``` +**Foerderer-Beispiel** (`foerderer_tests.json`): + +```json +[ + { "y_abstand": 800 }, + { + "test_id": "VF_Auf_2000_Rechts", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 2000, + "seite": "rechts", + "winkel": 27, + "gf_verteilung": "vorne" + } +] +``` + +Felder: + +- `test_id` — Eindeutiger Name des Testfalls +- `richtung` — `"Auf"` oder `"Ab"` +- `deltaL`, `deltaH` — Horizontal-/Hoehendistanz in mm +- `seite` *(optional, Default `"links"`)* — `"links"` oder `"rechts"`, steuert AS-/ES-Seite (`SEITE_AS`/`SEITE_ES`-Attribut) +- `winkel` *(optional)* — erzwingt einen bestimmten Kandidatenwinkel statt des automatisch gewaehlten kleinsten gueltigen Winkels; muss ein gueltiger Wert aus der `bogen_winkel`-Kandidatenliste sein, sonst wird der Testfall `NICHT_GEBAUT` +- `gf_verteilung` *(optional, Default `"gleichmaessig"`)* — `"gleichmaessig"` (50/50 auf Einlauf/Auslauf), `"vorne"` (alles am Einlauf) oder `"hinten"` (alles am Auslauf) + ### Schritt 2: LISP-Testrunner erweitern (falls neues Modul) Fuer ein neues Modul eine neue `.lsp`-Datei erstellen nach dem Muster: diff --git a/tests/test_foerderer.lsp b/tests/test_foerderer.lsp index b3812ce..be88005 100644 --- a/tests/test_foerderer.lsp +++ b/tests/test_foerderer.lsp @@ -17,14 +17,22 @@ ;; --- Ergebnis eines Testfalls als JSON-String erzeugen --- (defun foerderer:test-result-json (test-id richtung deltaL deltaH status - winkel L_GF L_VF / + winkel L_GF L_VF + seite gf-verteilung winkel-angefordert / 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 "\"")) + " \"status\": \"" status "\",\n" + " \"seite\": \"" seite "\",\n" + " \"gf_verteilung\": \"" gf-verteilung "\"")) + + (if winkel-angefordert + (setq json (strcat json ",\n" + " \"winkel_angefordert\": " (itoa winkel-angefordert))) + ) (if winkel (setq json (strcat json ",\n" @@ -66,15 +74,36 @@ ) +;; --- L_GF gemaess gf-verteilung auf L_GF1 (Einlauf) / L_GF2 (Auslauf) verteilen --- +(defun foerderer:split-gf (gf-verteilung L_GF) + (cond + ((= gf-verteilung "vorne") (list L_GF 0.0)) + ((= gf-verteilung "hinten") (list 0.0 L_GF)) + (T (list (/ L_GF 2.0) (/ L_GF 2.0))) ;; "gleichmaessig" + unbekannt + ) +) + +;; --- Sucht winkel-soll in der von berechne-alle-winkel gelieferten +;; ergebnis-liste (Elemente: (winkel L_GF L_VF gueltig)). +;; Rueckgabe: das Element, oder nil wenn winkel-soll nicht in der +;; Kandidatenliste vorkommt. Aufrufer muss zusaetzlich (cadddr item) +;; (gueltig) und L_GF/L_VF > 0 pruefen. --- +(defun foerderer:winkel-erzwingen (ergebnis-liste winkel-soll) + (car (vl-remove-if-not + '(lambda (item) (= (car item) winkel-soll)) + ergebnis-liste)) +) + + ;; --- Einen VF-Testblock bauen und lastEnt hinter dessen SEQEND schieben --- (defun foerderer:baue-block (startpunkt vf-nummer hoehe-von hoehe-bis deltaH deltaL richtung best-winkel - L_GF1 L_GF2 L_VF lastEnt / + L_GF1 L_GF2 L_VF seite lastEnt / sub-ent) (variofoerderer-einfuegen deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF - startpunkt "links" 0.0) - (vf-block-erstellen "standard" "links" vf-nummer 0 + startpunkt seite 0.0) + (vf-block-erstellen "standard" seite vf-nummer 0 hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2 richtung best-winkel startpunkt lastEnt 0.0) @@ -103,7 +132,9 @@ y-offset y-abstand idx blk-nummer anz-gebaut anz-nicht-gebaut results-list startpunkt hoehe-von hoehe-bis lastEnt - sub-typ) + sub-typ + seite gf-verteilung winkel-soll winkel-treffer + gf-split horizontal-gf-split) ;; Bibliothek initialisieren (laedt Block-Library und extrahiert Masse). ;; Auch bei gesetztem Flag, aber leerer Bogen-Tabelle neu initialisieren @@ -167,6 +198,12 @@ (setq deltaH (float (ssg-val eintrag "deltaH"))) (setq idx (1+ idx)) + (setq seite (ssg-val eintrag "seite")) + (if (or (null seite) (= seite "")) (setq seite "links")) + (setq gf-verteilung (ssg-val eintrag "gf_verteilung")) + (if (or (null gf-verteilung) (= gf-verteilung "")) (setq gf-verteilung "gleichmaessig")) + (setq winkel-soll (ssg-val eintrag "winkel")) + ;; Geometrisch unmoeglich: Ab mit deltaH=0 (if (and (= richtung "Ab") (< deltaH 1)) (progn @@ -174,7 +211,8 @@ (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) + "GEOMETRISCH_UNMOEGLICH" nil nil nil + seite gf-verteilung winkel-soll) results-list)) ) (progn @@ -183,6 +221,26 @@ (setq L_GF (cadr ergebnis)) (setq L_VF (caddr ergebnis)) + ;; Optionaler erzwungener Winkel: statt des automatisch gewaehlten + ;; kleinsten gueltigen Winkels einen bestimmten Kandidaten aus der + ;; vollstaendigen ergebnis-liste (4. Rueckgabeelement) verwenden. + (if (numberp winkel-soll) + (progn + (setq winkel-treffer + (foerderer:winkel-erzwingen (cadddr ergebnis) winkel-soll)) + (if (and winkel-treffer (cadddr winkel-treffer) + (numberp (cadr winkel-treffer)) (numberp (caddr winkel-treffer)) + (> (cadr winkel-treffer) 0) (> (caddr winkel-treffer) 0)) + (progn + (setq best-winkel (car winkel-treffer)) + (setq L_GF (cadr winkel-treffer)) + (setq L_VF (caddr winkel-treffer))) + (progn + (setq best-winkel nil) (setq L_GF nil) (setq L_VF nil)) + ) + ) + ) + (if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0)) (progn (setq anz-gebaut (1+ anz-gebaut)) @@ -198,14 +256,17 @@ ;; VF_N-Blocks ueberspringen, sonst rutschen sie in den naechsten ;; Block hinein (Blockerstellung faengt sonst am falschen Entity an). (setq lastEnt (vf-lastent-ohne-attribute)) + (setq gf-split (foerderer:split-gf gf-verteilung L_GF)) (setq lastEnt (foerderer:baue-block startpunkt blk-nummer hoehe-von hoehe-bis deltaH deltaL richtung best-winkel - (/ L_GF 2.0) (/ L_GF 2.0) L_VF lastEnt)) + (car gf-split) (cadr gf-split) L_VF + seite lastEnt)) (setq results-list (cons (foerderer:test-result-json test-id richtung deltaL deltaH - "GEBAUT" best-winkel L_GF L_VF) + "GEBAUT" best-winkel L_GF L_VF + seite gf-verteilung winkel-soll) results-list)) ) (progn @@ -213,7 +274,8 @@ (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) + "NICHT_GEBAUT" nil nil nil + seite gf-verteilung winkel-soll) results-list)) ) ) @@ -238,17 +300,24 @@ (setq hoehe-von 0) (setq hoehe-bis (- deltaH)) (setq lastEnt (vf-lastent-ohne-attribute)) + ;; seite/gf-verteilung vom Elternfall erben (gleicher + ;; Foerderer); winkel-soll ist hier nicht anwendbar - + ;; berechne-horizontale-mitte hat keine Winkel-Kandidatenliste + ;; (die Mittelstrecke ist immer auf 0 Grad fixiert). + (setq horizontal-gf-split + (foerderer:split-gf gf-verteilung (car horizontal-info))) (setq lastEnt (foerderer:baue-block startpunkt blk-nummer hoehe-von hoehe-bis deltaH deltaL "Ab" 0 - (/ (car horizontal-info) 2.0) - (/ (car horizontal-info) 2.0) - (cadr horizontal-info) lastEnt)) + (car horizontal-gf-split) + (cadr horizontal-gf-split) + (cadr horizontal-info) seite lastEnt)) (setq results-list (cons (foerderer:test-result-json (strcat test-id "_HORIZONTAL") richtung deltaL deltaH "GEBAUT" 0 - (car horizontal-info) (cadr horizontal-info)) + (car horizontal-info) (cadr horizontal-info) + seite gf-verteilung nil) results-list)) ) ) diff --git a/tests/testdata/foerderer_tests.json b/tests/testdata/foerderer_tests.json index e306055..08661cb 100644 --- a/tests/testdata/foerderer_tests.json +++ b/tests/testdata/foerderer_tests.json @@ -73,5 +73,40 @@ "richtung": "Ab", "deltaL": 7000, "deltaH": 5000 + }, + { + "test_id": "VF_Auf_2000_Rechts", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 2000, + "seite": "rechts" + }, + { + "test_id": "VF_Ab_2000_Winkel27", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 2000, + "winkel": 27 + }, + { + "test_id": "VF_Auf_3000_GF_Gleichmaessig", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 3000, + "gf_verteilung": "gleichmaessig" + }, + { + "test_id": "VF_Auf_1000_GF_Vorne", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 1000, + "gf_verteilung": "vorne" + }, + { + "test_id": "VF_Ab_3000_GF_Hinten", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 3000, + "gf_verteilung": "hinten" } ]