pyWebLayout/tests/test_concrete_box.py
Duncan Tourolle 3f9bd0072e
All checks were successful
Python CI / test (push) Successful in 48s
test for concrete
2025-06-07 19:43:59 +02:00

190 lines
7.2 KiB
Python

"""
Unit tests for pyWebLayout.concrete.box module.
Tests the Box class which handles basic box model rendering with alignment.
"""
import unittest
import numpy as np
from PIL import Image
from unittest.mock import Mock, patch
from pyWebLayout.concrete.box import Box
from pyWebLayout.style.layout import Alignment
class TestBox(unittest.TestCase):
"""Test cases for the Box class"""
def setUp(self):
"""Set up test fixtures"""
self.origin = (10, 20)
self.size = (100, 50)
self.callback = Mock()
def test_box_initialization_basic(self):
"""Test basic box initialization"""
box = Box(self.origin, self.size)
np.testing.assert_array_equal(box._origin, np.array([10, 20]))
np.testing.assert_array_equal(box._size, np.array([100, 50]))
np.testing.assert_array_equal(box._end, np.array([110, 70]))
self.assertIsNone(box._callback)
self.assertIsNone(box._sheet)
self.assertIsNone(box._mode)
self.assertEqual(box._halign, Alignment.CENTER)
self.assertEqual(box._valign, Alignment.CENTER)
def test_box_initialization_with_callback(self):
"""Test box initialization with callback"""
box = Box(self.origin, self.size, callback=self.callback)
self.assertEqual(box._callback, self.callback)
def test_box_initialization_with_sheet(self):
"""Test box initialization with image sheet"""
sheet = Image.new('RGBA', (200, 100), (255, 255, 255, 255))
box = Box(self.origin, self.size, sheet=sheet)
self.assertEqual(box._sheet, sheet)
self.assertEqual(box._mode, 'RGBA')
def test_box_initialization_with_mode(self):
"""Test box initialization with explicit mode"""
box = Box(self.origin, self.size, mode='RGB')
self.assertEqual(box._mode, 'RGB')
def test_box_initialization_with_alignment(self):
"""Test box initialization with custom alignment"""
box = Box(self.origin, self.size, halign=Alignment.LEFT, valign=Alignment.TOP)
self.assertEqual(box._halign, Alignment.LEFT)
self.assertEqual(box._valign, Alignment.TOP)
def test_in_shape_point_inside(self):
"""Test in_shape method with point inside box"""
box = Box(self.origin, self.size)
# Test point inside
self.assertTrue(box.in_shape(np.array([50, 40])))
self.assertTrue(box.in_shape(np.array([10, 20]))) # Top-left corner
self.assertTrue(box.in_shape(np.array([109, 69]))) # Just inside bottom-right
def test_in_shape_point_outside(self):
"""Test in_shape method with point outside box"""
box = Box(self.origin, self.size)
# Test points outside
self.assertFalse(box.in_shape(np.array([5, 15]))) # Before origin
self.assertFalse(box.in_shape(np.array([110, 70]))) # At end (exclusive)
self.assertFalse(box.in_shape(np.array([150, 100]))) # Far outside
def test_in_shape_multiple_points(self):
"""Test in_shape method with array of points"""
box = Box(self.origin, self.size)
points = np.array([[50, 40], [5, 15], [109, 69], [110, 70]])
result = box.in_shape(points)
np.testing.assert_array_equal(result, [True, False, True, False])
def test_render_default_no_content(self):
"""Test render method with no content"""
box = Box(self.origin, self.size)
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
self.assertEqual(result.mode, 'RGBA')
def test_render_with_sheet_mode(self):
"""Test render method with sheet providing mode"""
sheet = Image.new('RGB', (200, 100), (255, 0, 0))
box = Box(self.origin, self.size, sheet=sheet)
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
self.assertEqual(result.mode, 'RGB')
def test_render_with_explicit_mode(self):
"""Test render method with explicit mode"""
box = Box(self.origin, self.size, mode='L') # Grayscale
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
self.assertEqual(result.mode, 'L')
def test_render_with_content_centered(self):
"""Test render method with content centered"""
box = Box(self.origin, self.size, halign=Alignment.CENTER, valign=Alignment.CENTER)
# Mock content that has a render method
mock_content = Mock()
mock_content.render.return_value = Image.new('RGBA', (50, 30), (255, 0, 0, 255))
box._content = mock_content
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
mock_content.render.assert_called_once()
def test_render_with_content_left_aligned(self):
"""Test render method with content left-aligned"""
box = Box(self.origin, self.size, halign=Alignment.LEFT, valign=Alignment.TOP)
# Mock content
mock_content = Mock()
mock_content.render.return_value = Image.new('RGBA', (30, 20), (0, 255, 0, 255))
box._content = mock_content
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
mock_content.render.assert_called_once()
def test_render_with_content_right_aligned(self):
"""Test render method with content right-aligned"""
box = Box(self.origin, self.size, halign=Alignment.RIGHT, valign=Alignment.BOTTOM)
# Mock content
mock_content = Mock()
mock_content.render.return_value = Image.new('RGBA', (40, 25), (0, 0, 255, 255))
box._content = mock_content
result = box.render()
self.assertIsInstance(result, Image.Image)
self.assertEqual(result.size, tuple(self.size))
mock_content.render.assert_called_once()
def test_render_content_larger_than_box(self):
"""Test render method when content is larger than box"""
small_box = Box((0, 0), (20, 15))
# Mock content larger than box
mock_content = Mock()
mock_content.render.return_value = Image.new('RGBA', (50, 40), (255, 255, 0, 255))
small_box._content = mock_content
result = small_box.render()
# Should still create box-sized canvas
self.assertEqual(result.size, (20, 15))
mock_content.render.assert_called_once()
def test_properties_access(self):
"""Test that properties can be accessed correctly"""
box = Box(self.origin, self.size, callback=self.callback)
# Test that origin property works (should be available via inheritance)
np.testing.assert_array_equal(box._origin, np.array([10, 20]))
np.testing.assert_array_equal(box._size, np.array([100, 50]))
if __name__ == '__main__':
unittest.main()