"""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 freeroute.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