import math import pytest from matrixmania import project_perspective def approx_equal(a: float, b: float, rel_tol: float = 1e-9) -> bool: """Utility to compare two floats with a relative tolerance.""" return math.isclose(a, b, rel_tol=rel_tol) @pytest.mark.parametrize( "point,focal_length,scale,expected", [ # Case 1 – no scaling, unit focal length ( (1.0, 2.0, 3.0), 1.0, # focal_length 1.0, # scale ( 1.0 / (4.0 + 3.0), # x projected 2.0 / (4.0 + 3.0), # y projected ), ), # Case 2 – scale 100, focal length 2 ( (1.0, 2.0, 3.0), 2.0, # focal_length 100.0, # scale ( 2.0 * 100.0 / (4.0 + 3.0), # x projected 2.0 * 100.0 * 2.0 / (4.0 + 3.0), # y projected ), ), ], ) def test_project_perspective(point, focal_length, scale, expected): """Test that project_perspective returns the correct 2‑D projection.""" # Call the function under test result = project_perspective(point, focal_length=focal_length, scale=scale) # Basic sanity checks assert isinstance(result, tuple), "Result should be a tuple" assert len(result) == 2, "Result should contain two coordinates" # Confirm values are close to expected (within tiny tolerance) assert approx_equal(result[0], expected[0]), f"X coordinate mismatch: {result[0]} != {expected[0]}" assert approx_equal(result[1], expected[1]), f"Y coordinate mismatch: {result[1]} != {expected[1]}"