@@ -0,0 +1,189 @@
|
||||
"""
|
||||
Test the new Page implementation to verify it meets the requirements:
|
||||
1. Accepts a PageStyle that defines borders, line spacing and inter-block spacing
|
||||
2. Makes an image canvas
|
||||
3. Provides a method for accepting child objects
|
||||
4. Provides methods for determining canvas size and border size
|
||||
5. Has a method that calls render on all children
|
||||
6. Has a method to query a point and determine which child it belongs to
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
from pyWebLayout.style.fonts import Font
|
||||
from pyWebLayout.core.base import Renderable, Queriable
|
||||
|
||||
|
||||
class SimpleTestRenderable(Renderable, Queriable):
|
||||
"""A simple test renderable for testing the page system"""
|
||||
|
||||
def __init__(self, text: str, size: tuple = (100, 50)):
|
||||
self._text = text
|
||||
self._size = size
|
||||
self._origin = np.array([0, 0])
|
||||
|
||||
def render(self):
|
||||
"""Render returns None - drawing is done via the page's draw object"""
|
||||
return None
|
||||
|
||||
|
||||
def test_page_creation_with_style():
|
||||
"""Test creating a page with a PageStyle"""
|
||||
style = PageStyle(
|
||||
border_width=2,
|
||||
border_color=(255, 0, 0),
|
||||
line_spacing=8,
|
||||
inter_block_spacing=20,
|
||||
padding=(15, 15, 15, 15),
|
||||
background_color=(240, 240, 240)
|
||||
)
|
||||
|
||||
page = Page(size=(800, 600), style=style)
|
||||
|
||||
assert page.size == (800, 600)
|
||||
assert page.style == style
|
||||
assert page.border_size == 2
|
||||
|
||||
|
||||
def test_page_canvas_and_content_sizes():
|
||||
"""Test that page correctly calculates canvas and content sizes"""
|
||||
style = PageStyle(
|
||||
border_width=5,
|
||||
padding=(10, 20, 30, 40) # top, right, bottom, left
|
||||
)
|
||||
|
||||
page = Page(size=(800, 600), style=style)
|
||||
|
||||
# Canvas size should be page size minus borders
|
||||
assert page.canvas_size == (790, 590) # 800-10, 600-10 (border on both sides)
|
||||
|
||||
# Content size should be canvas minus padding
|
||||
assert page.content_size == (730, 550) # 790-60, 590-40 (padding left+right, top+bottom)
|
||||
|
||||
|
||||
def test_page_add_remove_children():
|
||||
"""Test adding and removing children from the page"""
|
||||
page = Page(size=(800, 600))
|
||||
|
||||
# Initially no children
|
||||
assert len(page.children) == 0
|
||||
|
||||
# Add children
|
||||
child1 = SimpleTestRenderable("Child 1")
|
||||
child2 = SimpleTestRenderable("Child 2")
|
||||
|
||||
page.add_child(child1)
|
||||
assert len(page.children) == 1
|
||||
|
||||
page.add_child(child2)
|
||||
assert len(page.children) == 2
|
||||
|
||||
# Test method chaining
|
||||
child3 = SimpleTestRenderable("Child 3")
|
||||
result = page.add_child(child3)
|
||||
assert result is page # Should return self for chaining
|
||||
assert len(page.children) == 3
|
||||
|
||||
# Remove child
|
||||
removed = page.remove_child(child2)
|
||||
assert removed is True
|
||||
assert len(page.children) == 2
|
||||
assert child2 not in page.children
|
||||
|
||||
# Try to remove non-existent child
|
||||
removed = page.remove_child(child2)
|
||||
assert removed is False
|
||||
|
||||
# Clear all children
|
||||
page.clear_children()
|
||||
assert len(page.children) == 0
|
||||
|
||||
|
||||
def test_page_render():
|
||||
"""Test that page renders and creates a canvas"""
|
||||
style = PageStyle(
|
||||
border_width=2,
|
||||
border_color=(255, 0, 0),
|
||||
background_color=(255, 255, 255)
|
||||
)
|
||||
|
||||
page = Page(size=(200, 150), style=style)
|
||||
|
||||
# Add a child
|
||||
child = SimpleTestRenderable("Test child")
|
||||
page.add_child(child)
|
||||
|
||||
# Render the page
|
||||
image = page.render()
|
||||
|
||||
# Check that we got an image
|
||||
assert isinstance(image, Image.Image)
|
||||
assert image.size == (200, 150)
|
||||
assert image.mode == 'RGBA'
|
||||
|
||||
# Check that draw object is available
|
||||
assert page.draw is not None
|
||||
|
||||
|
||||
def test_page_query_point():
|
||||
"""Test querying points to find children"""
|
||||
page = Page(size=(400, 300))
|
||||
|
||||
# Add children with known positions and sizes
|
||||
child1 = SimpleTestRenderable("Child 1", (100, 50))
|
||||
child2 = SimpleTestRenderable("Child 2", (80, 40))
|
||||
|
||||
page.add_child(child1).add_child(child2)
|
||||
|
||||
# Query points
|
||||
# Point within first child
|
||||
found_child = page.query_point((90, 30))
|
||||
assert found_child == child1
|
||||
|
||||
# Point within second child
|
||||
found_child = page.query_point((30, 30))
|
||||
assert found_child == child2
|
||||
|
||||
# Point outside any child
|
||||
found_child = page.query_point((300, 250))
|
||||
assert found_child is None
|
||||
|
||||
|
||||
def test_page_in_object():
|
||||
"""Test that page correctly implements in_object"""
|
||||
page = Page(size=(400, 300))
|
||||
|
||||
# Points within page bounds
|
||||
assert page.in_object((0, 0)) is True
|
||||
assert page.in_object((200, 150)) is True
|
||||
assert page.in_object((399, 299)) is True
|
||||
|
||||
# Points outside page bounds
|
||||
assert page.in_object((-1, 0)) is False
|
||||
assert page.in_object((0, -1)) is False
|
||||
assert page.in_object((400, 299)) is False
|
||||
assert page.in_object((399, 300)) is False
|
||||
|
||||
|
||||
def test_page_with_borders():
|
||||
"""Test page rendering with borders"""
|
||||
style = PageStyle(
|
||||
border_width=3,
|
||||
border_color=(128, 128, 128),
|
||||
background_color=(255, 255, 255)
|
||||
)
|
||||
|
||||
page = Page(size=(100, 100), style=style)
|
||||
image = page.render()
|
||||
|
||||
# Check that image was created
|
||||
assert isinstance(image, Image.Image)
|
||||
assert image.size == (100, 100)
|
||||
|
||||
# The border should be drawn but we can't easily test pixel values
|
||||
# Just verify the image exists and has the right properties
|
||||
|
||||
|
||||
Reference in New Issue
Block a user