""" 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()