pyWebLayout/tests/test_paragraph_layout_fix.py

175 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""
Test paragraph layout specifically to diagnose the line breaking issue
"""
from pyWebLayout.concrete.page import Page
from pyWebLayout.style.fonts import Font
from pyWebLayout.abstract.block import Paragraph
from pyWebLayout.abstract.inline import Word
from pyWebLayout.typesetting.paragraph_layout import ParagraphLayout
from pyWebLayout.style.layout import Alignment
from PIL import Image
def test_paragraph_layout_directly():
"""Test the paragraph layout system directly"""
print("Testing paragraph layout system directly...")
# Create a paragraph with multiple words
paragraph = Paragraph()
font = Font(font_size=14)
# Add many words to force line breaking
words_text = [
"This", "is", "a", "very", "long", "paragraph", "that", "should",
"definitely", "wrap", "across", "multiple", "lines", "when", "rendered",
"in", "a", "narrow", "width", "container", "to", "test", "the",
"paragraph", "layout", "system", "and", "ensure", "proper", "line",
"breaking", "functionality", "works", "correctly", "as", "expected."
]
for word_text in words_text:
word = Word(word_text, font)
paragraph.add_word(word)
# Create paragraph layout with narrow width to force wrapping
layout = ParagraphLayout(
line_width=300, # Narrow width
line_height=20,
word_spacing=(3, 8),
line_spacing=3,
halign=Alignment.LEFT
)
# Layout the paragraph
lines = layout.layout_paragraph(paragraph)
print(f"✓ Created paragraph with {len(words_text)} words")
print(f"✓ Layout produced {len(lines)} lines")
# Check each line
for i, line in enumerate(lines):
word_count = len(line.renderable_words) if hasattr(line, 'renderable_words') else 0
print(f" Line {i+1}: {word_count} words")
return len(lines) > 1 # Should have multiple lines
def test_page_with_long_paragraph():
"""Test a page with a long paragraph to see line breaking"""
print("\nTesting page with long paragraph...")
html_content = """
<html>
<body>
<h1>Test Long Paragraph</h1>
<p>This is a very long paragraph that should definitely wrap across multiple lines when rendered in the page. It contains many words and should demonstrate the line breaking functionality of the paragraph layout system. The paragraph layout should break this text into multiple lines based on the available width, and each line should be rendered separately on the page. This allows for proper text flow and readability in the final rendered output.</p>
<p>This is another paragraph to test multiple paragraph rendering and spacing between paragraphs.</p>
</body>
</html>
"""
# Create a page with narrower width to force wrapping
page = Page(size=(400, 600))
page.load_html_string(html_content)
print(f"✓ Page loaded with {len(page._children)} top-level elements")
# Check the structure of the page
for i, child in enumerate(page._children):
child_type = type(child).__name__
print(f" Element {i+1}: {child_type}")
# If it's a container (paragraph), check its children
if hasattr(child, '_children'):
print(f" Contains {len(child._children)} child elements")
for j, subchild in enumerate(child._children):
subchild_type = type(subchild).__name__
print(f" Sub-element {j+1}: {subchild_type}")
# Try to render the page
try:
image = page.render()
print(f"✓ Page rendered successfully: {image.size}")
# Save for inspection
image.save("test_paragraph_layout_output.png")
print("✓ Saved rendered page to: test_paragraph_layout_output.png")
return True
except Exception as e:
print(f"✗ Error rendering page: {e}")
import traceback
traceback.print_exc()
return False
def test_simple_text_vs_paragraph():
"""Compare simple text vs paragraph rendering"""
print("\nTesting simple text vs paragraph rendering...")
# Test 1: Simple HTML with short text
simple_html = "<p>Short text</p>"
page1 = Page(size=(400, 200))
page1.load_html_string(simple_html)
print(f"Simple text page has {len(page1._children)} children")
# Test 2: Complex HTML with long text
complex_html = """
<p>This is a much longer paragraph that should wrap across multiple lines and demonstrate the difference between simple text rendering and proper paragraph layout with line breaking functionality.</p>
"""
page2 = Page(size=(400, 200))
page2.load_html_string(complex_html)
print(f"Complex text page has {len(page2._children)} children")
# Render both
try:
img1 = page1.render()
img2 = page2.render()
img1.save("test_simple_text.png")
img2.save("test_complex_text.png")
print("✓ Saved both test images")
return True
except Exception as e:
print(f"✗ Error rendering: {e}")
return False
def main():
"""Run all paragraph layout tests"""
print("Testing paragraph layout fixes...")
print("=" * 50)
tests = [
("Direct Paragraph Layout", test_paragraph_layout_directly),
("Page with Long Paragraph", test_page_with_long_paragraph),
("Simple vs Complex Text", test_simple_text_vs_paragraph),
]
results = []
for test_name, test_func in tests:
print(f"\nTesting: {test_name}")
print("-" * 30)
try:
success = test_func()
results.append((test_name, success))
except Exception as e:
print(f"✗ Test failed with exception: {e}")
import traceback
traceback.print_exc()
results.append((test_name, False))
# Summary
print("\n" + "=" * 50)
print("Test Summary:")
for test_name, success in results:
status = "PASS" if success else "FAIL"
print(f" {test_name}: {status}")
total_tests = len(results)
passed_tests = sum(1 for _, success in results if success)
print(f"\nPassed: {passed_tests}/{total_tests}")
if __name__ == "__main__":
main()