tro_flow.link_tros: Uebergang durch eine Weiche zwischen zwei Kreiseln
Der Weichenknoten-TRO leitet ueber jede seiner Weichen auf den Partnerkreisel um; dort faehrt der Traeger zum naechsten Halt nach der Weiche. Ohne diese Kante fehlte z. B. in der Testanlage test_system TRO(0011) -> TRO(0010), der Ausgang war vom Eingang aus unerreichbar. Test tests/test_tro_link.py mit Fixture test_system_sep22_export.csv; ID-Datei cfg/export_tro_ids.ini der Testanlage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
df24cf5adb
commit
77c5aac343
@@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Tests fuer tro_flow.link_tros - Uebergang durch eine Kreisel-Kreisel-Weiche.
|
||||
|
||||
Fixture: Testanlage test_system (dxfmakros results/export.csv) mit einem
|
||||
zusaetzlichen Separator 0022 auf Kreisel 0007. Kreisel 0009 hat nur einen
|
||||
eigenen Separator (0010 vor Weiche 0024 zu Kreisel 0001 mit der Entladung);
|
||||
in Kreisel 0009 gelangt man nur ueber Weiche 0023, die Separator 0011 auf
|
||||
Kreisel 0008 steuert. Die Kreiselketten kennen Weichen nicht als Glied - ohne
|
||||
eigene Weichenkante fehlte TRO(0011) -> TRO(0010), der Ausgang war vom
|
||||
Eingang aus unerreichbar und stattdessen zeigte TRO(0010) rueckwaerts auf
|
||||
TRO(0011).
|
||||
|
||||
TROs werden ueber ihre Separatoren angesprochen, nicht ueber die IDs (die
|
||||
haengen an der ID-Datei der Anlage).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from material_flow import build_graph, read_elements
|
||||
from tro_flow import BOUNDARY_ENTRY, BOUNDARY_EXIT, analyse_tros
|
||||
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
|
||||
|
||||
def _analyse(name: str):
|
||||
path = FIXTURES / name
|
||||
elements = read_elements(path, [])
|
||||
graph = build_graph(elements, path.name, [])
|
||||
return analyse_tros(graph, elements)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def analysis():
|
||||
return _analyse("test_system_sep22_export.csv")
|
||||
|
||||
|
||||
def _tro_mit_sep(analysis, sep_id: str) -> str:
|
||||
return next(t.tro_id for t in analysis.tros if sep_id in t.separators)
|
||||
|
||||
|
||||
def _erreichbar(edges, start: str) -> set[str]:
|
||||
nach: dict[str, list[str]] = {}
|
||||
for a, b in edges:
|
||||
nach.setdefault(a, []).append(b)
|
||||
seen, stack = {start}, [start]
|
||||
while stack:
|
||||
for nxt in nach.get(stack.pop(), []):
|
||||
if nxt not in seen:
|
||||
seen.add(nxt)
|
||||
stack.append(nxt)
|
||||
return seen
|
||||
|
||||
|
||||
def test_weiche_fuehrt_auf_partnerkreisel(analysis):
|
||||
von, nach = _tro_mit_sep(analysis, "0011"), _tro_mit_sep(analysis, "0010")
|
||||
assert (von, nach) in analysis.edges
|
||||
|
||||
|
||||
def test_keine_rueckwaertskante_ueber_die_weiche(analysis):
|
||||
von, nach = _tro_mit_sep(analysis, "0010"), _tro_mit_sep(analysis, "0011")
|
||||
assert (von, nach) not in analysis.edges
|
||||
|
||||
|
||||
def test_ausgang_vom_eingang_erreichbar(analysis):
|
||||
# Nicht fuer test_system_export.csv: dort fehlt auf Kreisel 0007 der
|
||||
# Separator vor der Weiche zu Kreisel 0008 (erst 0022 hier steuert sie) -
|
||||
# die Anlage ist dort physisch nicht durchgaengig.
|
||||
eingang = next(b.tro_id for b in analysis.boundaries if b.type_name == BOUNDARY_ENTRY)
|
||||
ausgang = next(b.tro_id for b in analysis.boundaries if b.type_name == BOUNDARY_EXIT)
|
||||
assert ausgang in _erreichbar(analysis.edges, eingang)
|
||||
Reference in New Issue
Block a user