""" Unit tests for interaction validators and change detection. """ import pytest from pyPhotoAlbum.mixins.interaction_validators import ChangeValidator, InteractionChangeDetector class TestChangeValidator: """Tests for ChangeValidator class.""" def test_position_changed_significant(self): """Test that significant position changes are detected.""" validator = ChangeValidator() old_pos = (0.0, 0.0) new_pos = (5.0, 5.0) assert validator.position_changed(old_pos, new_pos, threshold=0.1) def test_position_changed_insignificant(self): """Test that insignificant position changes are not detected.""" validator = ChangeValidator() old_pos = (0.0, 0.0) new_pos = (0.05, 0.05) assert not validator.position_changed(old_pos, new_pos, threshold=0.1) def test_position_changed_none_values(self): """Test that None values return False.""" validator = ChangeValidator() assert not validator.position_changed(None, (1.0, 1.0)) assert not validator.position_changed((1.0, 1.0), None) assert not validator.position_changed(None, None) def test_size_changed_significant(self): """Test that significant size changes are detected.""" validator = ChangeValidator() old_size = (100.0, 100.0) new_size = (150.0, 150.0) assert validator.size_changed(old_size, new_size, threshold=0.1) def test_size_changed_insignificant(self): """Test that insignificant size changes are not detected.""" validator = ChangeValidator() old_size = (100.0, 100.0) new_size = (100.05, 100.05) assert not validator.size_changed(old_size, new_size, threshold=0.1) def test_rotation_changed_significant(self): """Test that significant rotation changes are detected.""" validator = ChangeValidator() old_rotation = 0.0 new_rotation = 45.0 assert validator.rotation_changed(old_rotation, new_rotation, threshold=0.1) def test_rotation_changed_insignificant(self): """Test that insignificant rotation changes are not detected.""" validator = ChangeValidator() old_rotation = 0.0 new_rotation = 0.05 assert not validator.rotation_changed(old_rotation, new_rotation, threshold=0.1) def test_crop_changed_significant(self): """Test that significant crop changes are detected.""" validator = ChangeValidator() old_crop = (0.0, 0.0, 1.0, 1.0) new_crop = (0.1, 0.1, 0.9, 0.9) assert validator.crop_changed(old_crop, new_crop, threshold=0.001) def test_crop_changed_insignificant(self): """Test that insignificant crop changes are not detected.""" validator = ChangeValidator() old_crop = (0.0, 0.0, 1.0, 1.0) new_crop = (0.0001, 0.0001, 1.0, 1.0) assert not validator.crop_changed(old_crop, new_crop, threshold=0.001) def test_crop_changed_identical(self): """Test that identical crop values return False.""" validator = ChangeValidator() crop = (0.0, 0.0, 1.0, 1.0) assert not validator.crop_changed(crop, crop) class TestInteractionChangeDetector: """Tests for InteractionChangeDetector class.""" def test_detect_position_change_significant(self): """Test detecting significant position changes.""" detector = InteractionChangeDetector(threshold=0.1) old_pos = (0.0, 0.0) new_pos = (5.0, 3.0) change = detector.detect_position_change(old_pos, new_pos) assert change is not None assert change["old_position"] == old_pos assert change["new_position"] == new_pos assert change["delta_x"] == 5.0 assert change["delta_y"] == 3.0 def test_detect_position_change_insignificant(self): """Test that insignificant position changes return None.""" detector = InteractionChangeDetector(threshold=0.1) old_pos = (0.0, 0.0) new_pos = (0.05, 0.05) change = detector.detect_position_change(old_pos, new_pos) assert change is None def test_detect_size_change_significant(self): """Test detecting significant size changes.""" detector = InteractionChangeDetector(threshold=0.1) old_size = (100.0, 100.0) new_size = (150.0, 120.0) change = detector.detect_size_change(old_size, new_size) assert change is not None assert change["old_size"] == old_size assert change["new_size"] == new_size assert change["delta_width"] == 50.0 assert change["delta_height"] == 20.0 def test_detect_rotation_change_significant(self): """Test detecting significant rotation changes.""" detector = InteractionChangeDetector(threshold=0.1) old_rotation = 0.0 new_rotation = 45.0 change = detector.detect_rotation_change(old_rotation, new_rotation) assert change is not None assert change["old_rotation"] == old_rotation assert change["new_rotation"] == new_rotation assert change["delta_angle"] == 45.0 def test_detect_crop_change_significant(self): """Test detecting significant crop changes.""" detector = InteractionChangeDetector(threshold=0.1) old_crop = (0.0, 0.0, 1.0, 1.0) new_crop = (0.1, 0.1, 0.9, 0.9) change = detector.detect_crop_change(old_crop, new_crop) assert change is not None assert change["old_crop"] == old_crop assert change["new_crop"] == new_crop # Use approximate comparison for floating point assert abs(change["delta"][0] - 0.1) < 0.001 assert abs(change["delta"][1] - 0.1) < 0.001 assert abs(change["delta"][2] - (-0.1)) < 0.001 assert abs(change["delta"][3] - (-0.1)) < 0.001 def test_custom_threshold(self): """Test using custom threshold values.""" detector = InteractionChangeDetector(threshold=5.0) old_pos = (0.0, 0.0) new_pos = (3.0, 3.0) # Should be insignificant with threshold of 5.0 change = detector.detect_position_change(old_pos, new_pos) assert change is None # Change detector with smaller threshold detector2 = InteractionChangeDetector(threshold=1.0) change2 = detector2.detect_position_change(old_pos, new_pos) assert change2 is not None