pyPhotoAlbum/tests/test_interaction_validators.py
Duncan Tourolle f6ed11b0bc
All checks were successful
Python CI / test (push) Successful in 1m20s
Lint / lint (push) Successful in 1m4s
Tests / test (3.11) (push) Successful in 1m27s
Tests / test (3.12) (push) Successful in 2m25s
Tests / test (3.13) (push) Successful in 2m52s
Tests / test (3.14) (push) Successful in 1m9s
black formatting
2025-11-27 23:07:16 +01:00

177 lines
6.3 KiB
Python

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