pyWebLayout/tests/concrete/test_linkedword_hyphenation.py

141 lines
4.9 KiB
Python

"""
Test that LinkedWord objects remain as LinkText even when hyphenated.
This is a regression test for the bug where hyphenated LinkedWords
were being converted to regular Text objects instead of LinkText.
"""
import unittest
from PIL import Image, ImageDraw
from pyWebLayout.concrete.text import Line
from pyWebLayout.concrete.functional import LinkText
from pyWebLayout.abstract.inline import LinkedWord
from pyWebLayout.abstract.functional import LinkType
from pyWebLayout.style import Font, Alignment
class TestLinkedWordHyphenation(unittest.TestCase):
"""Test that LinkedWords become LinkText objects even when hyphenated."""
def setUp(self):
"""Set up test canvas and drawing context."""
self.canvas = Image.new('RGB', (800, 600), color='white')
self.draw = ImageDraw.Draw(self.canvas)
self.font = Font(font_size=12)
def test_short_linkedword_no_hyphenation(self):
"""Test that a short LinkedWord that fits becomes a LinkText."""
# Create a line with enough space
line = Line(
spacing=(5, 15),
origin=(0, 0),
size=(200, 30),
draw=self.draw,
halign=Alignment.LEFT
)
# Create a LinkedWord that will fit without hyphenation
linked_word = LinkedWord(
text="click",
style=self.font,
location="action:test",
link_type=LinkType.API
)
# Add the word to the line
success, overflow = line.add_word(linked_word)
# Verify it was added successfully
self.assertTrue(success)
self.assertIsNone(overflow)
# Verify it became a LinkText object
self.assertEqual(len(line._text_objects), 1)
self.assertIsInstance(line._text_objects[0], LinkText)
self.assertEqual(line._text_objects[0].link.location, "action:test")
def test_long_linkedword_with_hyphenation(self):
"""Test that a long LinkedWord that needs hyphenation preserves LinkText."""
# Create a narrow line to force hyphenation
line = Line(
spacing=(5, 15),
origin=(0, 0),
size=(80, 30),
draw=self.draw,
halign=Alignment.LEFT
)
# Create a long LinkedWord that will need hyphenation
linked_word = LinkedWord(
text="https://example.com/very-long-url",
style=self.font,
location="https://example.com/very-long-url",
link_type=LinkType.EXTERNAL
)
# Add the word to the line
success, overflow = line.add_word(linked_word)
# The word should either:
# 1. Fit completely and be a LinkText
# 2. Be hyphenated, and BOTH parts should be LinkText
if overflow is not None:
# Word was hyphenated
# The first part should be in the line
self.assertTrue(success)
self.assertGreater(len(line._text_objects), 0)
# Both parts should be LinkText (this is the bug we're testing for)
for text_obj in line._text_objects:
self.assertIsInstance(
text_obj,
LinkText,
f"Hyphenated LinkedWord part should be LinkText, got {
type(text_obj)}")
self.assertEqual(text_obj.link.location, linked_word.location)
# The overflow should also be LinkText if it's hyphenated
if isinstance(overflow, LinkText):
self.assertEqual(overflow.link.location, linked_word.location)
else:
# Word fit without hyphenation
self.assertTrue(success)
self.assertEqual(len(line._text_objects), 1)
self.assertIsInstance(line._text_objects[0], LinkText)
def test_linkedword_title_preserved_after_hyphenation(self):
"""Test that link metadata (title) is preserved when hyphenated."""
# Create a narrow line
line = Line(
spacing=(5, 15),
origin=(0, 0),
size=(60, 30),
draw=self.draw,
halign=Alignment.LEFT
)
# Create a LinkedWord with title that will likely be hyphenated
linked_word = LinkedWord(
text="documentation",
style=self.font,
location="https://docs.example.com",
link_type=LinkType.EXTERNAL,
title="View Documentation"
)
# Add the word
success, overflow = line.add_word(linked_word)
# Verify metadata is preserved
if overflow is not None:
# If hyphenated, both parts should have link metadata
for text_obj in line._text_objects:
if isinstance(text_obj, LinkText):
self.assertEqual(text_obj.link.location, "https://docs.example.com")
self.assertEqual(text_obj.link.title, "View Documentation")
if __name__ == '__main__':
unittest.main()