masque/masque/test/test_advanced_routing.py
2026-02-15 12:36:13 -08:00

87 lines
2.9 KiB
Python

import pytest
from numpy.testing import assert_equal
from numpy import pi
from ..builder import Pather
from ..builder.tools import PathTool
from ..library import Library
from ..ports import Port
@pytest.fixture
def advanced_pather() -> tuple[Pather, PathTool, Library]:
lib = Library()
# Simple PathTool: 2um width on layer (1,0)
tool = PathTool(layer=(1, 0), width=2, ptype="wire")
p = Pather(lib, tools=tool)
return p, tool, lib
def test_path_into_straight(advanced_pather: tuple[Pather, PathTool, Library]) -> None:
p, tool, lib = advanced_pather
# Facing ports
p.ports["src"] = Port((0, 0), 0, ptype="wire") # Facing East (into device)
# Forward (+pi relative to port) is West (-x).
# Put destination at (-20, 0) pointing East (pi).
p.ports["dst"] = Port((-20, 0), pi, ptype="wire")
p.path_into("src", "dst")
assert "src" not in p.ports
assert "dst" not in p.ports
# Pather.path adds a Reference to the generated pattern
assert len(p.pattern.refs) == 1
def test_path_into_bend(advanced_pather: tuple[Pather, PathTool, Library]) -> None:
p, tool, lib = advanced_pather
# Source at (0,0) rot 0 (facing East). Forward is West (-x).
p.ports["src"] = Port((0, 0), 0, ptype="wire")
# Destination at (-20, -20) rot pi (facing West). Forward is East (+x).
# Wait, src forward is -x. dst is at -20, -20.
# To use a single bend, dst should be at some -x, -y and its rotation should be 3pi/2 (facing South).
# Forward for South is North (+y).
p.ports["dst"] = Port((-20, -20), 3 * pi / 2, ptype="wire")
p.path_into("src", "dst")
assert "src" not in p.ports
assert "dst" not in p.ports
# Single bend should result in 2 segments (one for x move, one for y move)
assert len(p.pattern.refs) == 2
def test_path_into_sbend(advanced_pather: tuple[Pather, PathTool, Library]) -> None:
p, tool, lib = advanced_pather
# Facing but offset ports
p.ports["src"] = Port((0, 0), 0, ptype="wire") # Forward is West (-x)
p.ports["dst"] = Port((-20, -10), pi, ptype="wire") # Facing East (rot pi)
p.path_into("src", "dst")
assert "src" not in p.ports
assert "dst" not in p.ports
def test_path_from(advanced_pather: tuple[Pather, PathTool, Library]) -> None:
p, tool, lib = advanced_pather
p.ports["src"] = Port((0, 0), 0, ptype="wire")
p.ports["dst"] = Port((-20, 0), pi, ptype="wire")
p.at("dst").path_from("src")
assert "src" not in p.ports
assert "dst" not in p.ports
def test_path_into_thru(advanced_pather: tuple[Pather, PathTool, Library]) -> None:
p, tool, lib = advanced_pather
p.ports["src"] = Port((0, 0), 0, ptype="wire")
p.ports["dst"] = Port((-20, 0), pi, ptype="wire")
p.ports["other"] = Port((10, 10), 0)
p.path_into("src", "dst", thru="other")
assert "src" in p.ports
assert_equal(p.ports["src"].offset, [10, 10])
assert "other" not in p.ports