2025-11-13 13:29:16 +01:00

93 lines
3.1 KiB
Python

import math
import pytest
from src.matrixmania.compute import rot_2D
# --- HELPER FUNCTION ---
def assert_matrices_close(m1, m2, abs_tol=1e-9):
"""
Helper function to compare two 2x2 matrices element-wise
using math.isclose for float comparison.
"""
assert len(m1) == 2 and len(m1[0]) == 2, "Matrix 1 is not 2x2"
assert len(m2) == 2 and len(m2[0]) == 2, "Matrix 2 is not 2x2"
for i in range(2):
for j in range(2):
# Assert that each element is close within the tolerance
assert math.isclose(m1[i][j], m2[i][j], abs_tol=abs_tol), \
f"Mismatch at [{i}][{j}]: {m1[i][j]} != {m2[i][j]}"
def test_90_degree_rotation_in_radians():
"""Tests a 90-degree rotation (input is pi/2 radians)."""
# 90 degrees = pi / 2 radians
# cos(pi/2) = 0, sin(pi/2) = 1
# Expected: [[0, -1], [1, 0]]
expected = [[0.0, -1.0], [1.0, 0.0]]
# Use the helper function for comparison
assert_matrices_close(rot_2D(math.pi / 2), expected)
def test_0_radian_rotation():
"""Tests a 0-radian rotation (should return the identity matrix)."""
# cos(0) = 1, sin(0) = 0
# Expected: [[1, 0], [0, 1]]
expected = [[1.0, 0.0], [0.0, 1.0]]
assert_matrices_close(rot_2D(0), expected)
assert_matrices_close(rot_2D(0.0), expected)
def test_180_degree_rotation_in_radians():
"""Tests a 180-degree rotation (input is pi radians)."""
# 180 degrees = pi radians
# cos(pi) = -1, sin(pi) = 0
# Expected: [[-1, 0], [0, -1]]
expected = [[-1.0, 0.0], [0.0, -1.0]]
assert_matrices_close(rot_2D(math.pi), expected)
def test_360_degree_rotation_in_radians():
"""Tests a 360-degree rotation (input is 2*pi radians)."""
# 360 degrees = 2*pi radians
# cos(2*pi) = 1, sin(2*pi) = 0
expected = [[1.0, 0.0], [0.0, 1.0]]
assert_matrices_close(rot_2D(math.pi * 2), expected)
def test_negative_90_degree_rotation_in_radians():
"""Tests a clockwise 90-degree rotation (input is -pi/2 radians)."""
# -90 degrees = -pi/2 radians
# cos(-pi/2) = 0, sin(-pi/2) = -1
# Expected: [[0, 1], [-1, 0]]
expected = [[0.0, 1.0], [-1.0, 0.0]]
assert_matrices_close(rot_2D(-math.pi / 2), expected)
def test_45_degree_rotation_in_radians():
"""Tests a 45-degree rotation (input is pi/4 radians)."""
# 45 degrees = pi/4 radians
val = math.sqrt(2) / 2 # This is cos(pi/4) and sin(pi/4)
# Expected: [[val, -val], [val, val]]
expected = [[val, -val], [val, val]]
assert_matrices_close(rot_2D(math.pi / 4), expected)
# --- Tests for error handling (Invalid Inputs) ---
# (These tests remain the same)
def test_error_on_string_input():
"""Tests that a ValueError is raised for string input."""
with pytest.raises(ValueError, match="instance of a numeric datatype"):
rot_2D("90")
def test_error_on_list_input():
"""Tests that a ValueError is raised for list input."""
with pytest.raises(ValueError, match="instance of a numeric datatype"):
rot_2D([math.pi])
def test_error_on_none_input():
"""Tests that a ValueError is raised for None input."""
with pytest.raises(ValueError, match="instance of a numeric datatype"):
rot_2D(None)