4ce2a02205
Die Streckenbloecke GF_N und VF_N tragen Winkel und Seite ihres AS-/ES-
Elements bereits als Attribute des gemeinsamen Schemas (WINKEL_AS/SEITE_AS/
WINKEL_ES/SEITE_ES, *strecke-attr-front* in ssg_core.lsp). Diese Information
landet jetzt auch im details-JSON des Sivas-Exports.
Zuordnung (Sivas-Hierarchie: 4431/4432 schalten Winkel und Seite frei):
4431/4432 AS-/ES-Element vorhanden Ja/Nein
4427/4429 Winkel "30 °"/"90 °"
4428/4430 Seite links/rechts
Die Zuordnung steht vollstaendig in cfg/sivas.cfg - mit denselben sechs
Zeilen in [gefaellestrecke] und [variofoerderer], jeweils direkt hinter 2950,
was auch die Reihenfolge im details-JSON bestimmt.
Ob ein Element vorhanden ist, entscheidet ausschliesslich WINKEL_AS/WINKEL_ES:
das Schema laesst den Winkel leer, wenn keines gewaehlt wurde, waehrend
SEITE_AS/SEITE_ES mit "rechts" immer einen Vorgabewert tragen. Ohne Element
bleiben Winkel UND Seite leer, damit in Sivas keine Seite unter einem
"Nein"-Knoten haengt.
Weitere Punkte:
- sivas_mapping: neuer Dekorator @braucht_attribs. Ein so markierter
Transform wird als fn(wert, attribs) statt fn(wert) aufgerufen und sieht
damit die uebrigen Attribute des Blocks - noetig, weil die Seite vom
Winkel abhaengt. Ohne diese Klammer muessten bedingte Merkmale wieder als
Python-Code aus der Config herauswandern.
- Die Winkel-Schreibweise der Sivas-Auswahlliste ("30 °" mit Leerzeichen vor
dem Gradzeichen) steht als Tabelle [as_es_winkel_anzeige] in sivas.cfg,
Bauart wie [geruest_typ_anzeige] - weicht Sivas davon ab, ist das die
einzige Stelle zum Nachziehen.
- gefaellestrecke_signature beruecksichtigt AS/ES: zwei sonst baugleiche
Gefaellestrecken mit AS links bzw. rechts bleiben getrennte Zeilen, sonst
zeigte die gemeinsame Zeile nur die Seite des ersten Blocks.
- Altbestand ohne diese Attribute meldet "Nein" statt abzubrechen.
- Merkmalsstamm_in_Sivas.xlsx auf den aktuellen Sivas-Stand gebracht
(enthaelt neben 4427-4432 auch 4002, 7010-7013 und Klartext-Korrekturen;
4339/4383 heissen jetzt eindeutig "... Gefaellestrecke"/"... Variofoerderer").
- 12 neue Tests in tests/test_export_sivas_as_es.py, ohne BricsCAD lauffaehig.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
182 lines
7.9 KiB
Python
182 lines
7.9 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
test_export_sivas_as_es.py - Sivas-Merkmale 4427-4432 (AS-/ES-Element) fuer
|
|
Gefaellestrecke (GF_N) und Streckengruppe (VF_N).
|
|
|
|
Pruefpunkte: Vorhandensein haengt am Winkel (nicht an der Seite, die immer
|
|
einen Vorgabewert traegt), der Winkel wird in die Sivas-Schreibweise der
|
|
Auswahlliste uebersetzt, ohne Element bleiben Winkel UND Seite leer, die
|
|
Zuordnung steht vollstaendig in cfg/sivas.cfg, und die GF-Gruppierung trennt
|
|
Bloecke mit unterschiedlichem AS-/ES-Element.
|
|
|
|
Laeuft komplett ohne BricsCAD (reine Python-Logik).
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
|
|
|
|
import export_sivas # noqa: E402
|
|
import sivas_mapping # noqa: E402
|
|
|
|
# Sivas-Schreibweise der Winkel-Auswahlliste (cfg/sivas.cfg
|
|
# [as_es_winkel_anzeige]) - die Tests vergleichen gegen die Config, damit ein
|
|
# Nachziehen der Schreibweise dort nicht die halbe Testdatei bricht.
|
|
W30 = export_sivas.as_es_winkel("30")
|
|
W90 = export_sivas.as_es_winkel("90")
|
|
|
|
|
|
def _strecke(nr, typ="Gefaellestrecke", **attr):
|
|
"""GF_N-/VF_N-Block mit dem gemeinsamen Strecken-Attributschema."""
|
|
attribs = {"ID": f"000{nr}", "Bezeichnung": f"GF_{nr}", "ARTINR": "6220",
|
|
"MONTAGEHOEHE_m": "2.000", "HOEHE_VON_mm": "2000",
|
|
"HOEHE_BIS_mm": "1000", "TYP": typ,
|
|
"L_GF_m": "3.000", "GF_WINKEL": "3",
|
|
"SEITE_AS": "links", "WINKEL_AS": "90",
|
|
"SEITE_ES": "links", "WINKEL_ES": "90"}
|
|
attribs.update(attr)
|
|
return {"block_name": f"GF_{nr}", "x": 0.0, "y": 0.0, "z": 2000.0,
|
|
"rotation": 0.0, "attribs": attribs}
|
|
|
|
|
|
def test_as_es_vorhanden_mit_winkel_und_seite():
|
|
details = export_sivas.build_gefaellestrecke_details(_strecke(1))
|
|
assert details["4431"] == "Ja"
|
|
assert details["4427"] == W90
|
|
assert details["4428"] == "links"
|
|
assert details["4432"] == "Ja"
|
|
assert details["4429"] == W90
|
|
assert details["4430"] == "links"
|
|
|
|
|
|
def test_zuordnung_steht_in_der_config():
|
|
"""Die sechs Merkmale muessen in BEIDEN Strecken-Abschnitten von
|
|
sivas.cfg stehen (GF_N und VF_N lesen dieselben Attribute)."""
|
|
for abschnitt in ("gefaellestrecke", "variofoerderer"):
|
|
mapping = sivas_mapping.load_section_mapping(abschnitt)
|
|
for merkmal, attribut, transform in (
|
|
("4431", "WINKEL_AS", "as_es_vorhanden"),
|
|
("4427", "WINKEL_AS", "as_es_winkel"),
|
|
("4428", "SEITE_AS", "as_seite"),
|
|
("4432", "WINKEL_ES", "as_es_vorhanden"),
|
|
("4429", "WINKEL_ES", "as_es_winkel"),
|
|
("4430", "SEITE_ES", "es_seite")):
|
|
assert merkmal in mapping, f"{merkmal} fehlt in [{abschnitt}]"
|
|
ist_attribut, _alt, _default, ist_transform = mapping[merkmal]
|
|
assert ist_attribut == attribut, f"[{abschnitt}] {merkmal}"
|
|
assert ist_transform == transform, f"[{abschnitt}] {merkmal}"
|
|
assert ist_transform in export_sivas.TRANSFORMS
|
|
|
|
|
|
def test_winkel_in_sivas_schreibweise():
|
|
"""4427/4429 tragen den Optionswert der Auswahlliste, nicht die nackte
|
|
Attributzahl (Vorgabe aus cfg/sivas.cfg [as_es_winkel_anzeige])."""
|
|
details = export_sivas.build_gefaellestrecke_details(
|
|
_strecke(1, WINKEL_AS="30", WINKEL_ES="90.0"))
|
|
assert details["4427"] == W30
|
|
assert details["4429"] == W90
|
|
# Unbekannter Winkel faellt auf die ganzzahlige Rohzahl zurueck
|
|
assert export_sivas.as_es_winkel("60.0") in (W30, W90, "60")
|
|
|
|
|
|
def test_ohne_winkel_kein_element_und_keine_seite():
|
|
"""Leerer WINKEL_AS = kein AS-Element; die Seite darf dann NICHT
|
|
durchgereicht werden (SEITE_AS traegt mit "rechts" immer einen
|
|
Schema-Vorgabewert)."""
|
|
details = export_sivas.build_gefaellestrecke_details(
|
|
_strecke(1, WINKEL_AS="", SEITE_AS="rechts"))
|
|
assert details["4431"] == "Nein"
|
|
assert details["4427"] == ""
|
|
assert details["4428"] == ""
|
|
# ES bleibt davon unberuehrt
|
|
assert details["4432"] == "Ja"
|
|
assert details["4430"] == "links"
|
|
|
|
|
|
def test_seite_rechts():
|
|
details = export_sivas.build_gefaellestrecke_details(
|
|
_strecke(1, SEITE_AS="rechts", SEITE_ES="rechts"))
|
|
assert details["4428"] == "rechts"
|
|
assert details["4430"] == "rechts"
|
|
|
|
|
|
def test_variofoerderer_hat_dieselben_merkmale():
|
|
block = _strecke(1, typ="Streckengruppe", L_VF_m="2.000", VF_WINKEL="0",
|
|
ANTRIEBFAHRTRICHTUNG="Auf", MOTORSEITE="rechts",
|
|
WINKEL_AS="30", SEITE_AS="rechts")
|
|
details = export_sivas.build_variofoerderer_details(block)
|
|
assert details["4431"] == "Ja"
|
|
assert details["4427"] == W30
|
|
assert details["4428"] == "rechts"
|
|
assert details["4429"] == W90
|
|
|
|
|
|
def test_gruppierung_trennt_nach_as_seite():
|
|
"""Sonst baugleiche Gefaellestrecken mit AS links bzw. rechts duerfen
|
|
nicht in einer Sivas-Zeile landen (die Zeile wuerde nur eine der beiden
|
|
Seiten zeigen)."""
|
|
links = export_sivas.gefaellestrecke_signature(_strecke(1, SEITE_AS="links"))
|
|
rechts = export_sivas.gefaellestrecke_signature(_strecke(2, SEITE_AS="rechts"))
|
|
assert links != rechts
|
|
assert links == export_sivas.gefaellestrecke_signature(_strecke(3, SEITE_AS="links"))
|
|
|
|
|
|
def test_gruppierung_trennt_nach_as_winkel():
|
|
assert (export_sivas.gefaellestrecke_signature(_strecke(1, WINKEL_AS="30"))
|
|
!= export_sivas.gefaellestrecke_signature(_strecke(2, WINKEL_AS="90")))
|
|
|
|
|
|
def test_gruppierung_ohne_element_ignoriert_die_seite():
|
|
"""Ohne AS-Element ist die Seite bedeutungslos und steht auch nicht in der
|
|
Zeile - sie darf die Gruppierung dann nicht aufspalten."""
|
|
assert (export_sivas.gefaellestrecke_signature(
|
|
_strecke(1, WINKEL_AS="", SEITE_AS="links"))
|
|
== export_sivas.gefaellestrecke_signature(
|
|
_strecke(2, WINKEL_AS="", SEITE_AS="rechts")))
|
|
|
|
|
|
def test_reihenfolge_im_details_json():
|
|
"""Die sechs Merkmale stehen im details-JSON direkt HINTER 2950
|
|
(Anlagenhoehe) - so vorgegeben, und so steht es in beiden Abschnitten von
|
|
sivas.cfg. Die Reihenfolge der JSON-Keys folgt der Zeilenreihenfolge der
|
|
Config (configparser und dict erhalten beide die Einfuegereihenfolge)."""
|
|
erwartet = ["2950", "4431", "4427", "4428", "4432", "4429", "4430"]
|
|
gf = list(export_sivas.build_gefaellestrecke_details(_strecke(1)))
|
|
vf = list(export_sivas.build_variofoerderer_details(
|
|
_strecke(2, typ="Streckengruppe", L_VF_m="2.000")))
|
|
assert gf[:len(erwartet)] == erwartet
|
|
assert vf[:len(erwartet)] == erwartet
|
|
|
|
|
|
def test_altbestand_ohne_die_attribute():
|
|
"""Bloecke aus Zeichnungen, die vor der Einfuehrung von WINKEL_AS gebaut
|
|
wurden, haben die Attribute gar nicht - dann greift der leere Default und
|
|
es wird "Nein" gemeldet (statt KeyError). Das ist die einzig moegliche
|
|
Aussage: Sivas kennt nur Ja/Nein, kein "unbekannt"."""
|
|
block = _strecke(1)
|
|
for tag in ("WINKEL_AS", "SEITE_AS", "WINKEL_ES", "SEITE_ES"):
|
|
del block["attribs"][tag]
|
|
details = export_sivas.build_gefaellestrecke_details(block)
|
|
assert details["4431"] == "Nein"
|
|
assert details["4432"] == "Nein"
|
|
assert details["4427"] == details["4428"] == ""
|
|
assert details["4429"] == details["4430"] == ""
|
|
|
|
|
|
def test_transform_mit_attribs_kontext():
|
|
"""Der @braucht_attribs-Transform muss das komplette Attribut-Dict sehen -
|
|
sonst koennte die Seite ihre Abhaengigkeit vom Winkel nicht pruefen."""
|
|
assert getattr(export_sivas.as_seite, "braucht_attribs", False)
|
|
assert getattr(export_sivas.es_seite, "braucht_attribs", False)
|
|
assert not getattr(export_sivas.ja_nein, "braucht_attribs", False)
|
|
|
|
mapping = {"4428": ("SEITE_AS", None, "", "as_seite")}
|
|
attribs = {"SEITE_AS": "links", "WINKEL_AS": "90"}
|
|
assert sivas_mapping.anwenden(mapping, attribs, export_sivas.TRANSFORMS) \
|
|
== {"4428": "links"}
|
|
attribs_ohne = {"SEITE_AS": "links", "WINKEL_AS": ""}
|
|
assert sivas_mapping.anwenden(mapping, attribs_ohne, export_sivas.TRANSFORMS) \
|
|
== {"4428": ""}
|