Add observable AppConfig (grid/snap/arc-on-crossing/animation/theme), pure-geometry orthogonal router with grid-snapped bends and perpendicular crossing detection for arc hops, and a mock flow-distribution solver that pushes supply to demand along shortest paths and records signed per-edge flow and direction. Covered by routing and flow-solver tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
"""Tests for orthogonal routing and crossing detection (pure geometry)."""
|
|
import math
|
|
|
|
from pipeline_editor.view.routing import (
|
|
orthogonal_route, polyline_segments, segment_crossings,
|
|
)
|
|
|
|
|
|
def _is_orthogonal(points):
|
|
for (x0, y0), (x1, y1) in zip(points, points[1:]):
|
|
if not (math.isclose(x0, x1) or math.isclose(y0, y1)):
|
|
return False
|
|
return True
|
|
|
|
|
|
def test_route_is_orthogonal_horizontal_ports():
|
|
# source outlet facing right -> pump inlet facing left
|
|
pts = orthogonal_route((0, 0), (1, 0), (200, 80), (-1, 0), grid=20)
|
|
assert pts[0] == (0, 0)
|
|
assert pts[-1] == (200, 80)
|
|
assert _is_orthogonal(pts)
|
|
assert len(pts) >= 2
|
|
|
|
|
|
def test_route_is_orthogonal_vertical_ports():
|
|
pts = orthogonal_route((50, 0), (0, -1), (130, 200), (0, 1), grid=20)
|
|
assert pts[0] == (50, 0) and pts[-1] == (130, 200)
|
|
assert _is_orthogonal(pts)
|
|
|
|
|
|
def test_route_straight_line_collapses():
|
|
# aligned ports facing each other -> essentially a straight run
|
|
pts = orthogonal_route((0, 40), (1, 0), (200, 40), (-1, 0), grid=20)
|
|
assert _is_orthogonal(pts)
|
|
assert all(math.isclose(p[1], 40) for p in pts)
|
|
|
|
|
|
def test_bends_snapped_to_grid():
|
|
pts = orthogonal_route((0, 0), (1, 0), (207, 83), (-1, 0), grid=20)
|
|
for x, y in pts[1:-1]:
|
|
assert math.isclose(x % 20, 0) or math.isclose(x % 20, 20)
|
|
|
|
|
|
def test_perpendicular_crossing_detected():
|
|
horiz = polyline_segments([(0, 50), (100, 50)])
|
|
vert = polyline_segments([(50, 0), (50, 100)])
|
|
cx = segment_crossings(horiz, vert)
|
|
assert cx == [(50, 50)]
|
|
|
|
|
|
def test_shared_endpoint_is_not_a_crossing():
|
|
# a T-junction where the vertical touches the horizontal endpoint
|
|
horiz = polyline_segments([(0, 50), (50, 50)])
|
|
vert = polyline_segments([(50, 50), (50, 100)])
|
|
assert segment_crossings(horiz, vert) == []
|
|
|
|
|
|
def test_parallel_segments_no_crossing():
|
|
a = polyline_segments([(0, 50), (100, 50)])
|
|
b = polyline_segments([(0, 70), (100, 70)])
|
|
assert segment_crossings(a, b) == []
|