The router began as a port of FreeRouting and has grown its own engine (negotiated congestion, tree nets, exact checks, axis escapes), and 'freeroute' was one letter from the project it no longer follows. The package, module and command are now rpmroute; the freeroute command stays as an alias, and the RPMROUTE / RPMROUTE_ORACLE_JAVA variables fall back to the old FREEROUTE names. Version 2026.10.07. Routing is unchanged: a PCBench board routes to a byte-identical session either way.
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
"""Unit tests for the board data model (layers, units, transform, nets, clearance)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from rpmroute.board import (
|
|
ClearanceMatrix,
|
|
CoordinateTransform,
|
|
Layer,
|
|
LayerStructure,
|
|
Nets,
|
|
Unit,
|
|
)
|
|
|
|
|
|
def test_unit_scale_and_parse():
|
|
assert Unit.from_string("um") is Unit.UM
|
|
assert Unit.from_string("MM") is Unit.MM
|
|
assert Unit.from_string("bogus") is None
|
|
assert Unit.scale(1.0, Unit.MM, Unit.UM) == 1000.0
|
|
assert Unit.scale(1.0, Unit.INCH, Unit.MIL) == 1000.0
|
|
assert str(Unit.MIL) == "mil"
|
|
|
|
|
|
def test_layer_structure_lookup():
|
|
ls = LayerStructure([Layer("F.Cu", True), Layer("In1", False), Layer("B.Cu", True)])
|
|
assert len(ls) == 3
|
|
assert ls.get_no("F.Cu") == 0
|
|
assert ls.get_no("B.Cu") == 2
|
|
assert ls.get_no("missing") == -1
|
|
assert ls.signal_layer_count() == 2
|
|
assert ls.get_signal_layer(1).name == "B.Cu"
|
|
|
|
|
|
def test_coordinate_transform_roundtrip():
|
|
t = CoordinateTransform(10)
|
|
assert t.dsn_to_board(5) == 50
|
|
assert t.board_to_dsn(50) == 5
|
|
p = t.dsn_to_board_point(100, -200)
|
|
assert (p.x, p.y) == (1000, -2000)
|
|
back = t.board_to_dsn_point(p)
|
|
assert (back.x, back.y) == (100.0, -200.0)
|
|
|
|
|
|
def test_nets_add_and_lookup():
|
|
nets = Nets()
|
|
a = nets.add("GND")
|
|
b = nets.add("VCC", subnet_number=1)
|
|
assert a.net_number == 1
|
|
assert b.net_number == 2
|
|
assert nets.max_net_no() == 2
|
|
assert nets.get("GND") is a
|
|
assert nets.get_by_number(2) is b
|
|
assert nets.get("missing") is None
|
|
assert nets.names() == {"GND", "VCC"}
|
|
assert len(nets) == 2
|
|
|
|
|
|
def test_clearance_matrix_default_and_classes():
|
|
cm = ClearanceMatrix.default_instance(200)
|
|
assert cm.get_class_count() == 2 # null + default
|
|
assert cm.get_name(0) == "null"
|
|
assert cm.get_name(1) == "default"
|
|
assert cm.get_value(1, 1) == 200
|
|
assert cm.get_value(0, 1) == 0 # null class has no clearance
|
|
via = cm.append_class("via")
|
|
assert cm.get_no("via") == via
|
|
cm.set_value(1, via, 300)
|
|
assert cm.get_value(via, 1) == 300 # symmetric
|
|
assert cm.get_value(1, 1, add_safety_margin=True) == 216 # +16 margin
|