Vorwärtskanten weichen Elementen über freie Linien aus (#22)
- build_bpmn() prüft jeden Standardweg einer Vorwärtskante gegen alle fremden Elemente. Nur bei einer Kreuzung sucht umweg_points() einen rechtwinkligen Weg von Stub zu Stub über freie Linien (Lückenmitten und 15 neben jedem Element), erst mit einem, dann mit zwei Zwischenknicken; der kürzeste gewinnt. Saubere Kanten bleiben byte-gleich, die Beispiel-.bpmn ändern sich nicht. - Belastungstest aus #12 als dauerhafter Test (126 Varianten: keine Kreuzung, rechtwinklige Anschlüsse), Test für das Beispiel aus dem Issue und zwei Einzeltests für umweg_points(). - Im Belastungstest werden 23 Kanten umgeleitet (3 bis 4 Zwischenpunkte); Kreuzungen vorher 24, jetzt 0. - Tests: python -m pytest -q -> 253 bestanden, 1 übersprungen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -275,6 +275,58 @@ def test_kanten_setzen_an_aufgaben_rechtwinklig_an(md):
|
||||
assert funde == [], "nicht rechtwinklig (Kante, Element): " + ", ".join(f"{k} → {e}" for k, e in funde)
|
||||
|
||||
|
||||
# Belastungstest (#12, #22): kleine Modelle, in die je eine zusätzliche Kante "zurück -> <früherer Schritt>" eingefügt
|
||||
# wird – für alle Paare, ohne Lanes, mit einer Lane und mit zwei abwechselnden Lanes. Querverbindungen zwischen
|
||||
# Geschwisterzweigen verschieben dabei das Layout (eine Aufgabe rutscht eine Ebene tiefer).
|
||||
BELASTUNGSMODELLE = {
|
||||
"drei": ["S1 Start: A", " -> S2", "S2 Gateway XOR: W?", " a -> S3", " b -> S4", " c -> S5",
|
||||
"S3 Task: Links", " -> S6", "S4 Task: Mitte", " -> S6", "S5 Task: Rechts", " -> S6",
|
||||
"S6 Gateway XOR: Z", " -> S7", "S7 Task: Danach", " -> S8", "S8 Ende: E"],
|
||||
"parallel": ["S1 Start: A", " -> S2", "S2 Task: Erfassen", " -> S3", "S3 Gateway AND: T", " -> S4", " -> S5",
|
||||
"S4 Task: L", " -> S6", "S5 Task: R", " -> S6", "S6 Gateway AND: Z", " -> S7",
|
||||
"S7 Gateway XOR: Ok?", " Ja -> S8", "S8 Ende: E"],
|
||||
}
|
||||
|
||||
|
||||
def _mit_lanes(zeilen, lane_von):
|
||||
return [z.replace(": ", f": {lane_von(z.split()[0])}: ", 1) if z[:1] == "S" else z for z in zeilen]
|
||||
|
||||
|
||||
def _belastungsfaelle():
|
||||
faelle = []
|
||||
for name, zeilen in BELASTUNGSMODELLE.items():
|
||||
ids = [z.split()[0] for z in zeilen if z[:1] == "S"]
|
||||
for quelle in ids[:-1]:
|
||||
for ziel in ids[1:ids.index(quelle) + 1]:
|
||||
mit = []
|
||||
for z in zeilen:
|
||||
mit.append(z)
|
||||
if z.startswith(quelle + " "):
|
||||
mit.append(f" zurück -> {ziel}")
|
||||
for variante, zz in (("ohne", mit), ("1lane", _mit_lanes(mit, lambda s: "A")),
|
||||
("2lanes", _mit_lanes(mit, lambda s: "A" if int(s[1:]) % 2 else "B"))):
|
||||
faelle.append(pytest.param("\n".join(zz), id=f"{name}-{quelle}-{ziel}-{variante}"))
|
||||
return faelle
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", _belastungsfaelle())
|
||||
def test_belastung_keine_kante_durch_ein_element_und_rechtwinklig(text):
|
||||
"""Prüft an allen Varianten des Belastungstests, dass keine Kante durch ein Element läuft und jede Kante an Aufgaben
|
||||
rechtwinklig ansetzt – auch wenn eine Querverbindung zwischen Zweigen das Layout verschiebt (Issue #22)."""
|
||||
defs = m.build_bpmn(*m.parse_markdown(text))
|
||||
assert kreuzungen(defs) == []
|
||||
assert schraege_anschluesse(defs) == []
|
||||
|
||||
|
||||
def test_beispiel_aus_issue_22_ohne_kreuzung():
|
||||
"""Prüft das Beispiel aus Issue #22: Sprung von hinten in den rechten Zweig; die Kante vom Gateway zu diesem Zweig
|
||||
läuft nicht durch die linke Aufgabe."""
|
||||
zeilen = list(BELASTUNGSMODELLE["drei"])
|
||||
zeilen.insert(zeilen.index("S7 Task: Danach") + 1, " zurück -> S5")
|
||||
text = "\n".join(zeilen)
|
||||
assert kreuzungen(m.build_bpmn(*m.parse_markdown(text))) == []
|
||||
|
||||
|
||||
def test_kreuzungspruefung_findet_eine_kante_durch_eine_aufgabe():
|
||||
"""Prüft die Prüfung selbst: eine absichtlich durch eine Aufgabe gelegte Kante wird gefunden, eine daneben nicht."""
|
||||
defs = baue(SKILL / "beispiele" / "beispiel_prozess.md")
|
||||
|
||||
Reference in New Issue
Block a user