Files
rpmroute/tests/geometry/test_box.py
T
rsp2k a6aa1991a1 Rename to rpmroute
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.
2026-10-07 14:10:36 -06:00

132 lines
3.9 KiB
Python

"""Tests for IntBox.
Oracles hand-derived from ``geometry/planar/IntBox.java``. Emphasis on boundary
containment and degenerate (empty / point / segment) tiles.
"""
from __future__ import annotations
from rpmroute.geometry import IntBox, IntPoint, IntVector, RationalPoint
def test_measures():
b = IntBox(1, 2, 5, 8)
assert b.width() == 4
assert b.height() == 6
assert b.area() == 24
assert b.circumference() == 20
assert b.max_width() == 6
assert b.min_width() == 4
def test_corners_counter_clockwise():
b = IntBox(0, 0, 4, 3)
assert b.corners() == [
IntPoint(0, 0),
IntPoint(4, 0),
IntPoint(4, 3),
IntPoint(0, 3),
]
def test_dimension_variants():
assert IntBox(0, 0, 4, 3).dimension() == 2
assert IntBox(0, 0, 0, 3).dimension() == 1 # vertical segment
assert IntBox(0, 0, 4, 0).dimension() == 1 # horizontal segment
assert IntBox(2, 2, 2, 2).dimension() == 0 # single point
assert IntBox.empty().dimension() == -1
def test_boundary_containment_inclusive_vs_interior():
b = IntBox(0, 0, 10, 10)
corner = IntPoint(0, 0)
edge = IntPoint(0, 5)
inside = IntPoint(5, 5)
outside = IntPoint(11, 5)
# border-inclusive contains
assert b.contains(corner)
assert b.contains(edge)
assert b.contains(inside)
assert not b.contains(outside)
# strict interior
assert not b.contains_inside(corner)
assert not b.contains_inside(edge)
assert b.contains_inside(inside)
def test_contains_rational_point_on_border():
b = IntBox(0, 0, 3, 3)
# (3, 1.5) sits exactly on the right edge -> contained (inclusive)
assert b.contains(RationalPoint(6, 3, 2))
# (3.5, 1.5) just outside
assert not b.contains(RationalPoint(7, 3, 2))
def test_intersection_overlap_and_touch():
a = IntBox(0, 0, 10, 10)
assert a.intersection(IntBox(5, 5, 20, 20)) == IntBox(5, 5, 10, 10)
# touching along an edge -> 1-dimensional intersection, still non-empty
touch = a.intersection(IntBox(10, 0, 20, 10))
assert touch == IntBox(10, 0, 10, 10)
assert touch.dimension() == 1
# disjoint -> empty
assert a.intersection(IntBox(20, 20, 30, 30)).is_empty()
def test_intersects_vs_overlaps_on_touching_edge():
a = IntBox(0, 0, 10, 10)
edge_neighbor = IntBox(10, 0, 20, 10)
assert a.intersects(edge_neighbor) # closed-interval: touching counts
assert not a.overlaps(edge_neighbor) # open-interval: no 2D overlap
def test_union():
assert IntBox(0, 0, 2, 2).union(IntBox(5, 5, 8, 8)) == IntBox(0, 0, 8, 8)
def test_offset_expands_and_contracts():
b = IntBox(0, 0, 10, 10)
assert b.offset(2) == IntBox(-2, -2, 12, 12)
assert b.offset(-3) == IntBox(3, 3, 7, 7)
assert b.offset(0) is b
assert b.horizontal_offset(2) == IntBox(-2, 0, 12, 10)
assert b.vertical_offset(2) == IntBox(0, -2, 10, 12)
def test_offset_rounds_half_up():
b = IntBox(0, 0, 10, 10)
assert b.offset(2.5) == IntBox(-3, -3, 13, 13) # 2.5 -> 3 (half up)
def test_shrink_collapses_to_center_not_past():
b = IntBox(0, 0, 10, 10)
assert b.shrink(3) == IntBox(3, 3, 7, 7)
# over-shrink collapses to the center line rather than inverting
collapsed = b.shrink(20)
assert collapsed == IntBox(5, 5, 5, 5)
assert collapsed.dimension() == 0
def test_containment_between_boxes():
outer = IntBox(0, 0, 10, 10)
inner = IntBox(2, 2, 8, 8)
assert inner.is_contained_in(outer)
assert outer.contains_box(inner)
assert outer.contains_in_interior(inner)
edge = IntBox(0, 2, 8, 8) # touches left edge
assert edge.is_contained_in(outer)
assert not outer.contains_in_interior(edge)
def test_translate_by():
b = IntBox(0, 0, 4, 4)
assert b.translate_by(IntVector(3, -2)) == IntBox(3, -2, 7, 2)
assert b.translate_by(IntVector(0, 0)) is b
def test_empty_box_predicates():
e = IntBox.empty()
assert e.is_empty()
assert e.is_contained_in(IntBox(0, 0, 1, 1))
assert e.offset(5) is e