190 lines
7.3 KiB
Python
190 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Comprehensive test to verify both the line-level hyphenation fix
|
|
and the paragraph-level overflow fix are working correctly.
|
|
"""
|
|
|
|
from unittest.mock import patch, Mock
|
|
from pyWebLayout.concrete.text import Line
|
|
from pyWebLayout.abstract.block import Paragraph
|
|
from pyWebLayout.abstract.inline import Word
|
|
from pyWebLayout.typesetting.paragraph_layout import ParagraphLayout
|
|
from pyWebLayout.style import Font
|
|
|
|
def test_complete_fix():
|
|
"""Test that both line-level and paragraph-level fixes work together"""
|
|
print("Testing complete line splitting fix...")
|
|
|
|
font = Font(font_path=None, font_size=12, colour=(0, 0, 0))
|
|
|
|
# Test 1: Direct line hyphenation fix
|
|
print("\n1. Testing direct line hyphenation fix:")
|
|
|
|
with patch('pyWebLayout.abstract.inline.pyphen') as mock_pyphen_module:
|
|
mock_dic = Mock()
|
|
mock_pyphen_module.Pyphen.return_value = mock_dic
|
|
mock_dic.inserted.return_value = "can-vas"
|
|
|
|
line = Line((3, 6), (0, 0), (50, 20), font)
|
|
overflow = line.add_word("canvas")
|
|
|
|
first_part = line.renderable_words[0].word.text if line.renderable_words else "None"
|
|
|
|
print(f" Word: 'canvas' -> hyphenated to 'can-vas'")
|
|
print(f" First part in line: '{first_part}'")
|
|
print(f" Overflow: '{overflow}'")
|
|
|
|
if overflow == "vas":
|
|
print(" ✓ Line-level fix working: overflow contains only next part")
|
|
else:
|
|
print(" ✗ Line-level fix failed")
|
|
return False
|
|
|
|
# Test 2: Paragraph-level overflow handling
|
|
print("\n2. Testing paragraph-level overflow handling:")
|
|
|
|
with patch('pyWebLayout.abstract.inline.pyphen') as mock_pyphen_module:
|
|
mock_dic = Mock()
|
|
mock_pyphen_module.Pyphen.return_value = mock_dic
|
|
|
|
# Mock different hyphenation patterns
|
|
def mock_inserted(text, hyphen='-'):
|
|
patterns = {
|
|
"canvas": "can-vas",
|
|
"vas": "vas", # No hyphenation needed for short words
|
|
"pants": "pants",
|
|
}
|
|
return patterns.get(text, text)
|
|
|
|
mock_dic.inserted.side_effect = mock_inserted
|
|
|
|
# Create a paragraph with the problematic sentence
|
|
paragraph = Paragraph(style=font)
|
|
words_text = ["and", "a", "pair", "of", "canvas", "pants", "but", "it"]
|
|
|
|
for word_text in words_text:
|
|
word = Word(word_text, font)
|
|
paragraph.add_word(word)
|
|
|
|
# Layout the paragraph with narrow lines to force wrapping
|
|
layout = ParagraphLayout(
|
|
line_width=60, # Narrow to force wrapping
|
|
line_height=20,
|
|
word_spacing=(3, 6)
|
|
)
|
|
|
|
lines = layout.layout_paragraph(paragraph)
|
|
|
|
print(f" Created paragraph with words: {words_text}")
|
|
print(f" Rendered into {len(lines)} lines:")
|
|
|
|
all_rendered_text = []
|
|
for i, line in enumerate(lines):
|
|
line_words = [word.word.text for word in line.renderable_words]
|
|
line_text = ' '.join(line_words)
|
|
all_rendered_text.extend(line_words)
|
|
print(f" Line {i+1}: {line_text}")
|
|
|
|
# Check that no text was lost
|
|
original_text_parts = []
|
|
for word in words_text:
|
|
if word == "canvas":
|
|
# Should be split into "can-" and "vas"
|
|
original_text_parts.extend(["can-", "vas"])
|
|
else:
|
|
original_text_parts.append(word)
|
|
|
|
print(f" Expected text parts: {original_text_parts}")
|
|
print(f" Actual text parts: {all_rendered_text}")
|
|
|
|
# Reconstruct text by removing hyphens and joining
|
|
expected_clean = ''.join(word.rstrip('-') for word in original_text_parts)
|
|
actual_clean = ''.join(word.rstrip('-') for word in all_rendered_text)
|
|
|
|
print(f" Expected clean text: '{expected_clean}'")
|
|
print(f" Actual clean text: '{actual_clean}'")
|
|
|
|
if expected_clean == actual_clean:
|
|
print(" ✓ Paragraph-level fix working: no text lost in overflow")
|
|
else:
|
|
print(" ✗ Paragraph-level fix failed: text was lost")
|
|
return False
|
|
|
|
# Test 3: Real-world scenario with the specific "canvas" case
|
|
print("\n3. Testing real-world canvas scenario:")
|
|
|
|
with patch('pyWebLayout.abstract.inline.pyphen') as mock_pyphen_module:
|
|
mock_dic = Mock()
|
|
mock_pyphen_module.Pyphen.return_value = mock_dic
|
|
mock_dic.inserted.return_value = "can-vas"
|
|
|
|
# Test the specific reported issue
|
|
paragraph = Paragraph(style=font)
|
|
sentence = "and a pair of canvas pants but"
|
|
words = sentence.split()
|
|
|
|
for word_text in words:
|
|
word = Word(word_text, font)
|
|
paragraph.add_word(word)
|
|
|
|
layout = ParagraphLayout(
|
|
line_width=120, # Width that causes "canvas" to hyphenate at line end
|
|
line_height=20,
|
|
word_spacing=(3, 6)
|
|
)
|
|
|
|
lines = layout.layout_paragraph(paragraph)
|
|
|
|
print(f" Original sentence: '{sentence}'")
|
|
print(f" Rendered into {len(lines)} lines:")
|
|
|
|
rendered_lines_text = []
|
|
for i, line in enumerate(lines):
|
|
line_words = [word.word.text for word in line.renderable_words]
|
|
line_text = ' '.join(line_words)
|
|
rendered_lines_text.append(line_text)
|
|
print(f" Line {i+1}: '{line_text}'")
|
|
|
|
# Check if we see the pattern "can-" at end of line and "vas" at start of next
|
|
found_proper_split = False
|
|
for i in range(len(rendered_lines_text) - 1):
|
|
current_line = rendered_lines_text[i]
|
|
next_line = rendered_lines_text[i + 1]
|
|
|
|
if "can-" in current_line and ("vas" in next_line or next_line.startswith("vas")):
|
|
found_proper_split = True
|
|
print(f" ✓ Found proper canvas split: '{current_line}' -> '{next_line}'")
|
|
break
|
|
|
|
if found_proper_split:
|
|
print(" ✓ Real-world scenario working: 'vas' is preserved")
|
|
else:
|
|
# Check if all original words are preserved (even without hyphenation)
|
|
all_words_preserved = True
|
|
for word in words:
|
|
found = False
|
|
for line_text in rendered_lines_text:
|
|
if word in line_text or word.rstrip('-') in line_text.replace('-', ''):
|
|
found = True
|
|
break
|
|
if not found:
|
|
print(f" ✗ Word '{word}' not found in rendered output")
|
|
all_words_preserved = False
|
|
|
|
if all_words_preserved:
|
|
print(" ✓ All words preserved (even if hyphenation pattern differs)")
|
|
else:
|
|
print(" ✗ Some words were lost")
|
|
return False
|
|
|
|
print("\n" + "="*60)
|
|
print("ALL TESTS PASSED - COMPLETE LINE SPLITTING FIX WORKS!")
|
|
print("="*60)
|
|
print("✓ Line-level hyphenation returns only next part")
|
|
print("✓ Paragraph-level overflow handling preserves all text")
|
|
print("✓ Real-world scenarios work correctly")
|
|
return True
|
|
|
|
if __name__ == "__main__":
|
|
test_complete_fix()
|