"""Tests for the continuous expansion-room routing track. The room router decomposes free space into exact rectangles (rooms) joined by doors, instead of a fixed grid. The headline result is the *continuity win*: a board with a narrow, off-grid channel that the grid/exact track cannot route (no cell centre lands in the channel) but the room track can. """ from __future__ import annotations from pathlib import Path import sys import pytest from freeroute.board import build_board from freeroute.dsn import parse_dsn from freeroute.dsn.sexp import parse from freeroute.geometry import Polyline from freeroute.route import route, route_dsn_board_exact, route_dsn_board_rooms sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) FIXTURES = Path(__file__).resolve().parent.parent / "dsn" / "fixtures" SIMPLE = FIXTURES / "simple_2net.dsn" CROSSING = FIXTURES / "crossing_2net.dsn" KICAD = FIXTURES / "kicad_routable.dsn" NARROW = FIXTURES / "narrow_channel.dsn" SHOVE_CHANNEL = FIXTURES / "rooms_shove_channel.dsn" WIDE_DOOR = FIXTURES / "rooms_wide_door.dsn" def _clearance(dsn, scale): from freeroute.route.pipeline import _rule_clearance_dsn return round(_rule_clearance_dsn(dsn) * scale) # --- DRC-clean invariant (same non-negotiable as the exact track) ----------- @pytest.mark.parametrize("fixture", [SIMPLE, CROSSING, KICAD, NARROW, SHOVE_CHANNEL, WIDE_DOOR]) def test_room_router_output_is_drc_clean(fixture): dsn = parse_dsn(fixture.read_text()) rooms, scale, _ = route_dsn_board_rooms(dsn) assert rooms.drc_clean assert rooms.tree.has_violation(_clearance(dsn, scale)) is None # --- connectivity + geometry ------------------------------------------------ def test_room_router_connects_simple_and_crossing(): for fixture in (SIMPLE, CROSSING): rooms, _, _ = route_dsn_board_rooms(parse_dsn(fixture.read_text())) assert rooms.routed_net_numbers == {1, 2} def test_room_router_uses_a_via_on_the_crossing_board(): rooms, _, _ = route_dsn_board_rooms(parse_dsn(CROSSING.read_text())) assert rooms.via_count() >= 1 def test_room_router_routes_the_real_boards_multipin_nets(): dsn = parse_dsn(KICAD.read_text()) rooms, _, _ = route_dsn_board_rooms(dsn) multi = sum(1 for n in dsn.nets if len(n.pins) >= 2) assert len(rooms.routed_net_numbers) == multi == 4 def test_room_traces_are_orthogonal_and_end_on_pads(): rooms, _, _ = route_dsn_board_rooms(parse_dsn(SIMPLE.read_text())) board = build_board(parse_dsn(SIMPLE.read_text())) pins_by_net: dict[int, set[tuple[int, int]]] = {} for pin in board.get_pins(): for net_no in pin.net_nos: pins_by_net.setdefault(net_no, set()).add((pin.location.x, pin.location.y)) for net_no, segments in rooms.result.wires.items(): pts = [(p.x, p.y) for _, seg in segments for p in seg] assert {pts[0], pts[-1]} == pins_by_net[net_no] for _, points in segments: for a, b in Polyline(points).segments(): assert a.x == b.x or a.y == b.y def test_room_engine_emits_valid_ses(): ses = route(SIMPLE.read_text(), engine="room") assert parse(ses).head == "session" # --- the headline: continuity beats the grid -------------------------------- def test_room_router_routes_a_channel_the_grid_cannot(): dsn = parse_dsn(NARROW.read_text()) # the exact/grid track cannot fit a centreline in the narrow, off-grid gap exact, scale, _ = route_dsn_board_exact(dsn) assert exact.routed_net_numbers == set() # grid quantization drops the net assert exact.drc_clean # the continuous room track routes it — and stays DRC-clean rooms, _, _ = route_dsn_board_rooms(dsn) assert rooms.routed_net_numbers == {1} assert rooms.drc_clean assert rooms.tree.has_violation(_clearance(dsn, scale)) is None # --- oracle parity ---------------------------------------------------------- @pytest.mark.oracle @pytest.mark.parametrize("fixture", [SIMPLE, CROSSING]) def test_room_connectivity_parity_with_oracle(fixture): from oracle import HAS_ORACLE, route_dsn, routed_net_set if not HAS_ORACLE: pytest.skip("FreeRouting oracle unavailable") ours = routed_net_set(route(fixture.read_text(), engine="room")) theirs = routed_net_set(route_dsn(fixture, max_passes=3, timeout=300)) assert theirs, "oracle routed nothing on a routable board" assert theirs <= ours