192 lines
7.4 KiB
Python
192 lines
7.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for the new external pagination system.
|
|
|
|
Tests the BlockPaginator and handler architecture to ensure it works correctly
|
|
with different block types using the unittest framework.
|
|
"""
|
|
|
|
import unittest
|
|
from pyWebLayout.abstract.block import Paragraph, Heading, HeadingLevel
|
|
from pyWebLayout.abstract.inline import Word
|
|
from pyWebLayout.concrete.page import Page
|
|
from pyWebLayout.style.fonts import Font
|
|
from pyWebLayout.typesetting.block_pagination import BlockPaginator, PaginationResult
|
|
|
|
|
|
class TestNewPaginationSystem(unittest.TestCase):
|
|
"""Test cases for the new pagination system."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.font = Font(font_size=16)
|
|
self.heading_font = Font(font_size=20)
|
|
|
|
def create_test_paragraph(self, text: str, font: Font = None) -> Paragraph:
|
|
"""Create a test paragraph with the given text."""
|
|
if font is None:
|
|
font = self.font
|
|
|
|
paragraph = Paragraph(font)
|
|
words = text.split()
|
|
|
|
for word_text in words:
|
|
word = Word(word_text, font)
|
|
paragraph.add_word(word)
|
|
|
|
return paragraph
|
|
|
|
def create_test_heading(self, text: str, level: HeadingLevel = HeadingLevel.H1) -> Heading:
|
|
"""Create a test heading with the given text."""
|
|
heading = Heading(level, self.heading_font)
|
|
|
|
words = text.split()
|
|
for word_text in words:
|
|
word = Word(word_text, self.heading_font)
|
|
heading.add_word(word)
|
|
|
|
return heading
|
|
|
|
def test_paragraph_pagination(self):
|
|
"""Test paragraph pagination with line breaking."""
|
|
# Create a long paragraph
|
|
long_text = " ".join(["This is a very long paragraph that should be broken across multiple lines."] * 10)
|
|
paragraph = self.create_test_paragraph(long_text)
|
|
|
|
# Create a page with limited height
|
|
page = Page(size=(400, 200)) # Small page
|
|
|
|
# Test the pagination handler
|
|
paginator = BlockPaginator()
|
|
result = paginator.paginate_block(paragraph, page, available_height=100)
|
|
|
|
# Assertions
|
|
self.assertIsInstance(result, PaginationResult)
|
|
self.assertIsInstance(result.success, bool)
|
|
self.assertIsInstance(result.height_used, (int, float))
|
|
self.assertGreaterEqual(result.height_used, 0)
|
|
|
|
def test_page_filling(self):
|
|
"""Test filling a page with multiple blocks."""
|
|
# Create test blocks
|
|
blocks = [
|
|
self.create_test_heading("Chapter 1: Introduction"),
|
|
self.create_test_paragraph("This is the first paragraph of the chapter. It contains some introductory text."),
|
|
self.create_test_paragraph("This is the second paragraph. It has more content and should flow nicely."),
|
|
self.create_test_heading("Section 1.1: Overview", HeadingLevel.H2),
|
|
self.create_test_paragraph("This is a paragraph under the section. It has even more content that might not fit on the same page."),
|
|
self.create_test_paragraph("This is another long paragraph that definitely won't fit. " * 20),
|
|
]
|
|
|
|
# Create a page
|
|
page = Page(size=(600, 400))
|
|
|
|
# Fill the page
|
|
next_index, remainder_blocks = page.fill_with_blocks(blocks)
|
|
|
|
# Assertions
|
|
self.assertIsInstance(next_index, int)
|
|
self.assertGreaterEqual(next_index, 0)
|
|
self.assertLessEqual(next_index, len(blocks))
|
|
self.assertIsInstance(remainder_blocks, list)
|
|
self.assertGreaterEqual(len(page._children), 0)
|
|
|
|
# Try to render the page
|
|
try:
|
|
page_image = page.render()
|
|
self.assertIsNotNone(page_image)
|
|
self.assertEqual(len(page_image.size), 2) # Should have width and height
|
|
except Exception as e:
|
|
self.fail(f"Page rendering failed: {e}")
|
|
|
|
def test_multi_page_creation(self):
|
|
"""Test creating multiple pages from a list of blocks."""
|
|
# Create many test blocks
|
|
blocks = []
|
|
for i in range(5): # Reduced for faster testing
|
|
blocks.append(self.create_test_heading(f"Chapter {i+1}"))
|
|
for j in range(2): # Reduced for faster testing
|
|
long_text = f"This is paragraph {j+1} of chapter {i+1}. " * 10
|
|
blocks.append(self.create_test_paragraph(long_text))
|
|
|
|
self.assertGreater(len(blocks), 0)
|
|
|
|
# Create pages until all blocks are processed
|
|
pages = []
|
|
remaining_blocks = blocks
|
|
page_count = 0
|
|
|
|
while remaining_blocks and page_count < 10: # Safety limit
|
|
page = Page(size=(600, 400))
|
|
next_index, remainder_blocks = page.fill_with_blocks(remaining_blocks)
|
|
|
|
if page._children:
|
|
pages.append(page)
|
|
page_count += 1
|
|
|
|
# Update remaining blocks
|
|
if remainder_blocks:
|
|
remaining_blocks = remainder_blocks
|
|
elif next_index < len(remaining_blocks):
|
|
remaining_blocks = remaining_blocks[next_index:]
|
|
else:
|
|
remaining_blocks = []
|
|
|
|
# Safety check to prevent infinite loops
|
|
if not page._children and remaining_blocks:
|
|
break
|
|
|
|
# Assertions
|
|
self.assertGreater(len(pages), 0, "Should create at least one page")
|
|
self.assertLessEqual(page_count, 10, "Should not exceed safety limit")
|
|
|
|
# Try to render a few pages
|
|
rendered_count = 0
|
|
for page in pages[:2]: # Test first 2 pages
|
|
try:
|
|
page_image = page.render()
|
|
rendered_count += 1
|
|
self.assertIsNotNone(page_image)
|
|
except Exception as e:
|
|
self.fail(f"Page rendering failed: {e}")
|
|
|
|
self.assertGreater(rendered_count, 0, "Should render at least one page")
|
|
|
|
def test_empty_blocks_list(self):
|
|
"""Test handling of empty blocks list."""
|
|
page = Page(size=(600, 400))
|
|
next_index, remainder_blocks = page.fill_with_blocks([])
|
|
|
|
self.assertEqual(next_index, 0)
|
|
self.assertEqual(len(remainder_blocks), 0)
|
|
self.assertEqual(len(page._children), 0)
|
|
|
|
def test_single_block(self):
|
|
"""Test handling of single block."""
|
|
blocks = [self.create_test_paragraph("Single paragraph test.")]
|
|
page = Page(size=(600, 400))
|
|
|
|
next_index, remainder_blocks = page.fill_with_blocks(blocks)
|
|
|
|
self.assertEqual(next_index, 1)
|
|
self.assertEqual(len(remainder_blocks), 0)
|
|
self.assertGreater(len(page._children), 0)
|
|
|
|
def test_pagination_result_properties(self):
|
|
"""Test PaginationResult object properties."""
|
|
paragraph = self.create_test_paragraph("Test paragraph for pagination result.")
|
|
page = Page(size=(400, 200))
|
|
|
|
paginator = BlockPaginator()
|
|
result = paginator.paginate_block(paragraph, page, available_height=100)
|
|
|
|
# Test that result has expected properties
|
|
self.assertTrue(hasattr(result, 'success'))
|
|
self.assertTrue(hasattr(result, 'height_used'))
|
|
self.assertTrue(hasattr(result, 'remainder'))
|
|
self.assertTrue(hasattr(result, 'can_continue'))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|