"""Tests for directions. Oracles hand-derived from ``geometry/planar/{Direction,IntDirection}.java``. """ from __future__ import annotations from freeroute.geometry import Direction, IntDirection, IntPoint, IntVector, Side def test_normalized_direction_reduces_by_gcd(): d = IntVector(2, 4).to_normalized_direction() assert isinstance(d, IntDirection) assert (d.x, d.y) == (1, 2) def test_normalized_direction_beyond_java_int(): # gcd reduction stays exact for coordinates far past Java's int range. d = IntVector(6 * 10**12, 9 * 10**12).to_normalized_direction() assert (d.x, d.y) == (2, 3) def test_turn_45_degree_cycles(): right = IntDirection(1, 0) assert (right.turn_45_degree(1).x, right.turn_45_degree(1).y) == (1, 1) assert (right.turn_45_degree(2).x, right.turn_45_degree(2).y) == (0, 1) assert (right.turn_45_degree(4).x, right.turn_45_degree(4).y) == (-1, 0) assert (right.turn_45_degree(8).x, right.turn_45_degree(8).y) == (1, 0) def test_opposite(): o = IntDirection(1, 2).opposite() assert (o.x, o.y) == (-1, -2) def test_direction_equals_ignores_magnitude_not_sign(): a = IntDirection(1, 1) assert a.equals(IntDirection(3, 3)) # same ray assert not a.equals(IntDirection(-1, -1)) # opposite ray assert not a.equals(IntDirection(1, 0)) def test_from_points_returns_none_for_equal(): assert Direction.from_points(IntPoint(1, 1), IntPoint(1, 1)) is None d = Direction.from_points(IntPoint(0, 0), IntPoint(4, 4)) assert (d.x, d.y) == (1, 1) def test_compare_to_angular_order(): right = IntDirection(1, 0) up = IntDirection(0, 1) down = IntDirection(0, -1) # angle(right)=0, angle(up)=90, angle(down)=270 assert right.compare_to(up) == -1 assert up.compare_to(right) == 1 assert up.compare_to(down) == -1 assert right.compare_to(IntDirection(2, 0)) == 0 def test_side_of_direction(): assert IntDirection(0, 1).side_of(IntDirection(1, 0)) == Side.ON_THE_LEFT