pyWebLayout/test_new_pagination_system.py
Duncan Tourolle 8c35cbf5ce
Some checks failed
Python CI / test (push) Failing after 4m8s
Improved handling of pagnination.
2025-06-08 13:29:44 +02:00

198 lines
6.3 KiB
Python

#!/usr/bin/env python3
"""
Test script for the new external pagination system.
This script tests the new BlockPaginator and handler architecture
to ensure it works correctly with different block types.
"""
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
def create_test_paragraph(text: str, font: Font = None) -> Paragraph:
"""Create a test paragraph with the given text."""
if font is None:
font = Font(font_size=16)
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(text: str, level: HeadingLevel = HeadingLevel.H1) -> Heading:
"""Create a test heading with the given text."""
font = Font(font_size=20)
heading = Heading(level, font)
words = text.split()
for word_text in words:
word = Word(word_text, font)
heading.add_word(word)
return heading
def test_paragraph_pagination():
"""Test paragraph pagination with line breaking."""
print("Testing paragraph pagination...")
# Create a long paragraph
long_text = " ".join(["This is a very long paragraph that should be broken across multiple lines."] * 10)
paragraph = 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)
print(f"Paragraph pagination result:")
print(f" Success: {result.success}")
print(f" Height used: {result.height_used}")
print(f" Has remainder: {result.remainder is not None}")
print(f" Can continue: {result.can_continue}")
return result.success
def test_page_filling():
"""Test filling a page with multiple blocks."""
print("\nTesting page filling with multiple blocks...")
# Create test blocks
blocks = [
create_test_heading("Chapter 1: Introduction"),
create_test_paragraph("This is the first paragraph of the chapter. It contains some introductory text."),
create_test_paragraph("This is the second paragraph. It has more content and should flow nicely."),
create_test_heading("Section 1.1: Overview", HeadingLevel.H2),
create_test_paragraph("This is a paragraph under the section. It has even more content that might not fit on the same page."),
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)
print(f"Page filling result:")
print(f" Blocks processed: {next_index} out of {len(blocks)}")
print(f" Remainder blocks: {len(remainder_blocks)}")
print(f" Page children: {len(page._children)}")
# Try to render the page
try:
page_image = page.render()
print(f" Page rendered successfully: {page_image.size}")
return True
except Exception as e:
print(f" Page rendering failed: {e}")
return False
def test_multi_page_creation():
"""Test creating multiple pages from a list of blocks."""
print("\nTesting multi-page creation...")
# Create many test blocks
blocks = []
for i in range(10):
blocks.append(create_test_heading(f"Chapter {i+1}"))
for j in range(3):
long_text = f"This is paragraph {j+1} of chapter {i+1}. " * 15
blocks.append(create_test_paragraph(long_text))
print(f"Created {len(blocks)} blocks total")
# Create pages until all blocks are processed
pages = []
remaining_blocks = blocks
page_count = 0
while remaining_blocks and page_count < 20: # 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
if not page._children and remaining_blocks:
print(f" Warning: Infinite loop detected, stopping")
break
print(f"Multi-page creation result:")
print(f" Pages created: {len(pages)}")
print(f" Remaining blocks: {len(remaining_blocks)}")
# Try to render a few pages
rendered_count = 0
for i, page in enumerate(pages[:3]): # Test first 3 pages
try:
page_image = page.render()
rendered_count += 1
print(f" Page {i+1} rendered: {page_image.size}")
except Exception as e:
print(f" Page {i+1} rendering failed: {e}")
return len(pages) > 0 and rendered_count > 0
def main():
"""Run all pagination tests."""
print("=== Testing New Pagination System ===")
results = []
try:
results.append(test_paragraph_pagination())
except Exception as e:
print(f"Paragraph pagination test failed: {e}")
results.append(False)
try:
results.append(test_page_filling())
except Exception as e:
print(f"Page filling test failed: {e}")
results.append(False)
try:
results.append(test_multi_page_creation())
except Exception as e:
print(f"Multi-page creation test failed: {e}")
results.append(False)
print(f"\n=== Test Results ===")
print(f"Paragraph pagination: {'PASS' if results[0] else 'FAIL'}")
print(f"Page filling: {'PASS' if results[1] else 'FAIL'}")
print(f"Multi-page creation: {'PASS' if results[2] else 'FAIL'}")
overall_result = all(results)
print(f"Overall: {'PASS' if overall_result else 'FAIL'}")
return overall_result
if __name__ == "__main__":
success = main()
exit(0 if success else 1)