425 lines
15 KiB
Python
425 lines
15 KiB
Python
"""
|
|
Unit tests for pyPhotoAlbum models
|
|
"""
|
|
|
|
import pytest
|
|
from pyPhotoAlbum.models import ImageData, PlaceholderData, TextBoxData, BaseLayoutElement
|
|
|
|
|
|
class TestBaseLayoutElement:
|
|
"""Tests for BaseLayoutElement abstract class"""
|
|
|
|
def test_cannot_instantiate_abstract_class(self):
|
|
"""Test that BaseLayoutElement cannot be instantiated directly"""
|
|
with pytest.raises(TypeError):
|
|
BaseLayoutElement()
|
|
|
|
|
|
class TestImageData:
|
|
"""Tests for ImageData class"""
|
|
|
|
def test_initialization_default(self):
|
|
"""Test ImageData initialization with default values"""
|
|
img = ImageData()
|
|
assert img.image_path == ""
|
|
assert img.position == (0, 0)
|
|
assert img.size == (100, 100)
|
|
assert img.rotation == 0
|
|
assert img.z_index == 0
|
|
assert img.crop_info == (0, 0, 1, 1)
|
|
|
|
def test_initialization_with_parameters(self, temp_image_file):
|
|
"""Test ImageData initialization with custom parameters"""
|
|
img = ImageData(
|
|
image_path=temp_image_file,
|
|
x=10.0,
|
|
y=20.0,
|
|
width=200.0,
|
|
height=150.0,
|
|
rotation=45.0,
|
|
z_index=5
|
|
)
|
|
assert img.image_path == temp_image_file
|
|
assert img.position == (10.0, 20.0)
|
|
assert img.size == (200.0, 150.0)
|
|
assert img.rotation == 45.0
|
|
assert img.z_index == 5
|
|
|
|
def test_initialization_with_crop_info(self):
|
|
"""Test ImageData initialization with custom crop info"""
|
|
crop = (0.1, 0.2, 0.8, 0.9)
|
|
img = ImageData(image_path="test.jpg", crop_info=crop)
|
|
assert img.crop_info == crop
|
|
|
|
def test_serialization(self, temp_image_file):
|
|
"""Test ImageData serialization to dictionary"""
|
|
img = ImageData(
|
|
image_path=temp_image_file,
|
|
x=15.0,
|
|
y=25.0,
|
|
width=180.0,
|
|
height=120.0,
|
|
rotation=30.0,
|
|
z_index=3
|
|
)
|
|
data = img.serialize()
|
|
|
|
assert data["type"] == "image"
|
|
assert data["image_path"] == temp_image_file
|
|
assert data["position"] == (15.0, 25.0)
|
|
assert data["size"] == (180.0, 120.0)
|
|
assert data["rotation"] == 30.0
|
|
assert data["z_index"] == 3
|
|
assert data["crop_info"] == (0, 0, 1, 1)
|
|
|
|
def test_deserialization(self):
|
|
"""Test ImageData deserialization from dictionary"""
|
|
img = ImageData()
|
|
data = {
|
|
"position": (30.0, 40.0),
|
|
"size": (220.0, 180.0),
|
|
"rotation": 90.0,
|
|
"z_index": 7,
|
|
"image_path": "new_image.jpg",
|
|
"crop_info": (0.2, 0.3, 0.7, 0.8)
|
|
}
|
|
img.deserialize(data)
|
|
|
|
assert img.position == (30.0, 40.0)
|
|
assert img.size == (220.0, 180.0)
|
|
assert img.rotation == 90.0
|
|
assert img.z_index == 7
|
|
assert img.image_path == "new_image.jpg"
|
|
assert img.crop_info == (0.2, 0.3, 0.7, 0.8)
|
|
|
|
def test_deserialization_with_defaults(self):
|
|
"""Test ImageData deserialization with missing fields uses defaults"""
|
|
img = ImageData()
|
|
data = {"image_path": "test.jpg"}
|
|
img.deserialize(data)
|
|
|
|
assert img.position == (0, 0)
|
|
assert img.size == (100, 100)
|
|
assert img.rotation == 0
|
|
assert img.z_index == 0
|
|
assert img.crop_info == (0, 0, 1, 1)
|
|
|
|
def test_serialize_deserialize_roundtrip(self, temp_image_file):
|
|
"""Test that serialize and deserialize are inverse operations"""
|
|
original = ImageData(
|
|
image_path=temp_image_file,
|
|
x=50.0,
|
|
y=60.0,
|
|
width=300.0,
|
|
height=200.0,
|
|
rotation=15.0,
|
|
z_index=2,
|
|
crop_info=(0.1, 0.1, 0.9, 0.9)
|
|
)
|
|
data = original.serialize()
|
|
restored = ImageData()
|
|
restored.deserialize(data)
|
|
|
|
assert restored.image_path == original.image_path
|
|
assert restored.position == original.position
|
|
assert restored.size == original.size
|
|
assert restored.rotation == original.rotation
|
|
assert restored.z_index == original.z_index
|
|
assert restored.crop_info == original.crop_info
|
|
|
|
def test_position_modification(self):
|
|
"""Test modifying position after initialization"""
|
|
img = ImageData()
|
|
img.position = (100.0, 200.0)
|
|
assert img.position == (100.0, 200.0)
|
|
|
|
def test_size_modification(self):
|
|
"""Test modifying size after initialization"""
|
|
img = ImageData()
|
|
img.size = (400.0, 300.0)
|
|
assert img.size == (400.0, 300.0)
|
|
|
|
|
|
class TestPlaceholderData:
|
|
"""Tests for PlaceholderData class"""
|
|
|
|
def test_initialization_default(self):
|
|
"""Test PlaceholderData initialization with default values"""
|
|
placeholder = PlaceholderData()
|
|
assert placeholder.placeholder_type == "image"
|
|
assert placeholder.default_content == ""
|
|
assert placeholder.position == (0, 0)
|
|
assert placeholder.size == (100, 100)
|
|
assert placeholder.rotation == 0
|
|
assert placeholder.z_index == 0
|
|
|
|
def test_initialization_with_parameters(self):
|
|
"""Test PlaceholderData initialization with custom parameters"""
|
|
placeholder = PlaceholderData(
|
|
placeholder_type="text",
|
|
default_content="Sample",
|
|
x=20.0,
|
|
y=30.0,
|
|
width=150.0,
|
|
height=100.0,
|
|
rotation=10.0,
|
|
z_index=4
|
|
)
|
|
assert placeholder.placeholder_type == "text"
|
|
assert placeholder.default_content == "Sample"
|
|
assert placeholder.position == (20.0, 30.0)
|
|
assert placeholder.size == (150.0, 100.0)
|
|
assert placeholder.rotation == 10.0
|
|
assert placeholder.z_index == 4
|
|
|
|
def test_serialization(self):
|
|
"""Test PlaceholderData serialization to dictionary"""
|
|
placeholder = PlaceholderData(
|
|
placeholder_type="image",
|
|
default_content="placeholder.jpg",
|
|
x=40.0,
|
|
y=50.0,
|
|
width=200.0,
|
|
height=150.0,
|
|
rotation=20.0,
|
|
z_index=2
|
|
)
|
|
data = placeholder.serialize()
|
|
|
|
assert data["type"] == "placeholder"
|
|
assert data["placeholder_type"] == "image"
|
|
assert data["default_content"] == "placeholder.jpg"
|
|
assert data["position"] == (40.0, 50.0)
|
|
assert data["size"] == (200.0, 150.0)
|
|
assert data["rotation"] == 20.0
|
|
assert data["z_index"] == 2
|
|
|
|
def test_deserialization(self):
|
|
"""Test PlaceholderData deserialization from dictionary"""
|
|
placeholder = PlaceholderData()
|
|
data = {
|
|
"position": (60.0, 70.0),
|
|
"size": (250.0, 180.0),
|
|
"rotation": 45.0,
|
|
"z_index": 6,
|
|
"placeholder_type": "text",
|
|
"default_content": "Default Text"
|
|
}
|
|
placeholder.deserialize(data)
|
|
|
|
assert placeholder.position == (60.0, 70.0)
|
|
assert placeholder.size == (250.0, 180.0)
|
|
assert placeholder.rotation == 45.0
|
|
assert placeholder.z_index == 6
|
|
assert placeholder.placeholder_type == "text"
|
|
assert placeholder.default_content == "Default Text"
|
|
|
|
def test_deserialization_with_defaults(self):
|
|
"""Test PlaceholderData deserialization with missing fields uses defaults"""
|
|
placeholder = PlaceholderData()
|
|
data = {"placeholder_type": "image"}
|
|
placeholder.deserialize(data)
|
|
|
|
assert placeholder.position == (0, 0)
|
|
assert placeholder.size == (100, 100)
|
|
assert placeholder.rotation == 0
|
|
assert placeholder.z_index == 0
|
|
assert placeholder.default_content == ""
|
|
|
|
def test_serialize_deserialize_roundtrip(self):
|
|
"""Test that serialize and deserialize are inverse operations"""
|
|
original = PlaceholderData(
|
|
placeholder_type="image",
|
|
default_content="test.jpg",
|
|
x=80.0,
|
|
y=90.0,
|
|
width=300.0,
|
|
height=250.0,
|
|
rotation=60.0,
|
|
z_index=8
|
|
)
|
|
data = original.serialize()
|
|
restored = PlaceholderData()
|
|
restored.deserialize(data)
|
|
|
|
assert restored.placeholder_type == original.placeholder_type
|
|
assert restored.default_content == original.default_content
|
|
assert restored.position == original.position
|
|
assert restored.size == original.size
|
|
assert restored.rotation == original.rotation
|
|
assert restored.z_index == original.z_index
|
|
|
|
|
|
class TestTextBoxData:
|
|
"""Tests for TextBoxData class"""
|
|
|
|
def test_initialization_default(self):
|
|
"""Test TextBoxData initialization with default values"""
|
|
textbox = TextBoxData()
|
|
assert textbox.text_content == ""
|
|
assert textbox.font_settings == {"family": "Arial", "size": 12, "color": (0, 0, 0)}
|
|
assert textbox.alignment == "left"
|
|
assert textbox.position == (0, 0)
|
|
assert textbox.size == (100, 100)
|
|
assert textbox.rotation == 0
|
|
assert textbox.z_index == 0
|
|
|
|
def test_initialization_with_parameters(self):
|
|
"""Test TextBoxData initialization with custom parameters"""
|
|
font_settings = {"family": "Times", "size": 14, "color": (255, 0, 0)}
|
|
textbox = TextBoxData(
|
|
text_content="Hello World",
|
|
font_settings=font_settings,
|
|
alignment="center",
|
|
x=25.0,
|
|
y=35.0,
|
|
width=180.0,
|
|
height=60.0,
|
|
rotation=5.0,
|
|
z_index=3
|
|
)
|
|
assert textbox.text_content == "Hello World"
|
|
assert textbox.font_settings == font_settings
|
|
assert textbox.alignment == "center"
|
|
assert textbox.position == (25.0, 35.0)
|
|
assert textbox.size == (180.0, 60.0)
|
|
assert textbox.rotation == 5.0
|
|
assert textbox.z_index == 3
|
|
|
|
def test_serialization(self):
|
|
"""Test TextBoxData serialization to dictionary"""
|
|
font_settings = {"family": "Helvetica", "size": 16, "color": (0, 0, 255)}
|
|
textbox = TextBoxData(
|
|
text_content="Test Text",
|
|
font_settings=font_settings,
|
|
alignment="right",
|
|
x=45.0,
|
|
y=55.0,
|
|
width=220.0,
|
|
height=80.0,
|
|
rotation=15.0,
|
|
z_index=5
|
|
)
|
|
data = textbox.serialize()
|
|
|
|
assert data["type"] == "textbox"
|
|
assert data["text_content"] == "Test Text"
|
|
assert data["font_settings"] == font_settings
|
|
assert data["alignment"] == "right"
|
|
assert data["position"] == (45.0, 55.0)
|
|
assert data["size"] == (220.0, 80.0)
|
|
assert data["rotation"] == 15.0
|
|
assert data["z_index"] == 5
|
|
|
|
def test_deserialization(self):
|
|
"""Test TextBoxData deserialization from dictionary"""
|
|
textbox = TextBoxData()
|
|
font_settings = {"family": "Courier", "size": 18, "color": (128, 128, 128)}
|
|
data = {
|
|
"position": (65.0, 75.0),
|
|
"size": (260.0, 100.0),
|
|
"rotation": 30.0,
|
|
"z_index": 7,
|
|
"text_content": "Deserialized Text",
|
|
"font_settings": font_settings,
|
|
"alignment": "justify"
|
|
}
|
|
textbox.deserialize(data)
|
|
|
|
assert textbox.position == (65.0, 75.0)
|
|
assert textbox.size == (260.0, 100.0)
|
|
assert textbox.rotation == 30.0
|
|
assert textbox.z_index == 7
|
|
assert textbox.text_content == "Deserialized Text"
|
|
assert textbox.font_settings == font_settings
|
|
assert textbox.alignment == "justify"
|
|
|
|
def test_deserialization_with_defaults(self):
|
|
"""Test TextBoxData deserialization with missing fields uses defaults"""
|
|
textbox = TextBoxData()
|
|
data = {"text_content": "Minimal"}
|
|
textbox.deserialize(data)
|
|
|
|
assert textbox.position == (0, 0)
|
|
assert textbox.size == (100, 100)
|
|
assert textbox.rotation == 0
|
|
assert textbox.z_index == 0
|
|
assert textbox.font_settings == {"family": "Arial", "size": 12, "color": (0, 0, 0)}
|
|
assert textbox.alignment == "left"
|
|
|
|
def test_serialize_deserialize_roundtrip(self):
|
|
"""Test that serialize and deserialize are inverse operations"""
|
|
font_settings = {"family": "Georgia", "size": 20, "color": (255, 255, 0)}
|
|
original = TextBoxData(
|
|
text_content="Round Trip Test",
|
|
font_settings=font_settings,
|
|
alignment="center",
|
|
x=85.0,
|
|
y=95.0,
|
|
width=320.0,
|
|
height=120.0,
|
|
rotation=25.0,
|
|
z_index=9
|
|
)
|
|
data = original.serialize()
|
|
restored = TextBoxData()
|
|
restored.deserialize(data)
|
|
|
|
assert restored.text_content == original.text_content
|
|
assert restored.font_settings == original.font_settings
|
|
assert restored.alignment == original.alignment
|
|
assert restored.position == original.position
|
|
assert restored.size == original.size
|
|
assert restored.rotation == original.rotation
|
|
assert restored.z_index == original.z_index
|
|
|
|
def test_text_content_modification(self):
|
|
"""Test modifying text content after initialization"""
|
|
textbox = TextBoxData()
|
|
textbox.text_content = "Modified Text"
|
|
assert textbox.text_content == "Modified Text"
|
|
|
|
def test_font_settings_modification(self):
|
|
"""Test modifying font settings after initialization"""
|
|
textbox = TextBoxData()
|
|
new_font = {"family": "Verdana", "size": 24, "color": (100, 200, 50)}
|
|
textbox.font_settings = new_font
|
|
assert textbox.font_settings == new_font
|
|
|
|
def test_alignment_modification(self):
|
|
"""Test modifying alignment after initialization"""
|
|
textbox = TextBoxData()
|
|
textbox.alignment = "right"
|
|
assert textbox.alignment == "right"
|
|
|
|
|
|
class TestElementComparison:
|
|
"""Tests comparing different element types"""
|
|
|
|
def test_different_element_types_serialize_differently(self):
|
|
"""Test that different element types have different serialization"""
|
|
img = ImageData(x=10, y=10)
|
|
placeholder = PlaceholderData(x=10, y=10)
|
|
textbox = TextBoxData(x=10, y=10)
|
|
|
|
img_data = img.serialize()
|
|
placeholder_data = placeholder.serialize()
|
|
textbox_data = textbox.serialize()
|
|
|
|
assert img_data["type"] == "image"
|
|
assert placeholder_data["type"] == "placeholder"
|
|
assert textbox_data["type"] == "textbox"
|
|
|
|
def test_z_index_comparison(self):
|
|
"""Test that z_index can be used for layering"""
|
|
img1 = ImageData(z_index=1)
|
|
img2 = ImageData(z_index=5)
|
|
img3 = ImageData(z_index=3)
|
|
|
|
elements = [img1, img2, img3]
|
|
sorted_elements = sorted(elements, key=lambda e: e.z_index)
|
|
|
|
assert sorted_elements[0].z_index == 1
|
|
assert sorted_elements[1].z_index == 3
|
|
assert sorted_elements[2].z_index == 5
|