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