pyPhotoAlbum/tests/test_interaction_validators.py
Duncan Tourolle 6755549dfd
All checks were successful
Python CI / test (push) Successful in 1m37s
Lint / lint (push) Successful in 1m32s
Tests / test (3.10) (push) Successful in 1m11s
Tests / test (3.11) (push) Successful in 1m11s
Tests / test (3.9) (push) Successful in 1m8s
Refactor to allow indepth testing
2025-11-23 11:05:46 +01:00

180 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