This commit is contained in:
@@ -287,7 +287,7 @@ class TestPage(unittest.TestCase):
|
||||
self.assertEqual(page._mode, 'RGBA')
|
||||
self.assertEqual(page._direction, 'vertical')
|
||||
self.assertEqual(page._spacing, 10)
|
||||
self.assertEqual(page._halign, Alignment.LEFT)
|
||||
self.assertEqual(page._halign, Alignment.CENTER)
|
||||
self.assertEqual(page._valign, Alignment.TOP)
|
||||
|
||||
def test_page_initialization_with_params(self):
|
||||
|
||||
+32
-135
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Unit tests for pyWebLayout.concrete.text module.
|
||||
Tests the Text, RenderableWord, and Line classes for text rendering functionality.
|
||||
Tests the Text and Line classes for text rendering functionality.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
@@ -8,7 +8,7 @@ import numpy as np
|
||||
from PIL import Image, ImageFont
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
|
||||
from pyWebLayout.concrete.text import Text, RenderableWord, Line
|
||||
from pyWebLayout.concrete.text import Text, Line
|
||||
from pyWebLayout.abstract.inline import Word
|
||||
from pyWebLayout.style import Font, FontStyle, FontWeight, TextDecoration
|
||||
from pyWebLayout.style.layout import Alignment
|
||||
@@ -175,135 +175,6 @@ class TestText(unittest.TestCase):
|
||||
self.assertEqual(size, text.size)
|
||||
|
||||
|
||||
class TestRenderableWord(unittest.TestCase):
|
||||
"""Test cases for the RenderableWord class"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures"""
|
||||
self.font = Font(
|
||||
font_path=None, # Use default font
|
||||
font_size=12,
|
||||
colour=(0, 0, 0)
|
||||
)
|
||||
self.abstract_word = Word("testing", self.font)
|
||||
|
||||
def test_renderable_word_initialization(self):
|
||||
"""Test basic RenderableWord initialization"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
self.assertEqual(renderable._word, self.abstract_word)
|
||||
self.assertEqual(len(renderable._text_parts), 1)
|
||||
self.assertEqual(renderable._text_parts[0].text, "testing")
|
||||
np.testing.assert_array_equal(renderable._origin, np.array([0, 0]))
|
||||
|
||||
def test_word_property(self):
|
||||
"""Test word property accessor"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
self.assertEqual(renderable.word, self.abstract_word)
|
||||
|
||||
def test_text_parts_property(self):
|
||||
"""Test text_parts property"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
self.assertIsInstance(renderable.text_parts, list)
|
||||
self.assertEqual(len(renderable.text_parts), 1)
|
||||
self.assertIsInstance(renderable.text_parts[0], Text)
|
||||
|
||||
def test_size_properties(self):
|
||||
"""Test width and height properties"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
self.assertGreater(renderable.width, 0)
|
||||
self.assertGreater(renderable.height, 0)
|
||||
self.assertEqual(renderable.width, renderable._size[0])
|
||||
self.assertEqual(renderable.height, renderable._size[1])
|
||||
|
||||
def test_set_origin(self):
|
||||
"""Test setting origin coordinates"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
renderable.set_origin(25, 30)
|
||||
|
||||
np.testing.assert_array_equal(renderable._origin, np.array([25, 30]))
|
||||
# Check that text parts also have updated origins
|
||||
self.assertEqual(renderable._text_parts[0]._origin[0], 25)
|
||||
self.assertEqual(renderable._text_parts[0]._origin[1], 30)
|
||||
|
||||
@patch.object(Word, 'hyphenate')
|
||||
def test_update_from_word_hyphenated(self, mock_hyphenate):
|
||||
"""Test updating from hyphenated word"""
|
||||
# Mock hyphenation
|
||||
mock_hyphenate.return_value = True
|
||||
self.abstract_word._hyphenated_parts = ["test-", "ing"]
|
||||
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
renderable.update_from_word()
|
||||
|
||||
self.assertEqual(len(renderable._text_parts), 2)
|
||||
self.assertEqual(renderable._text_parts[0].text, "test-")
|
||||
self.assertEqual(renderable._text_parts[1].text, "ing")
|
||||
|
||||
def test_get_part_size(self):
|
||||
"""Test getting size of specific text part"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
size = renderable.get_part_size(0)
|
||||
self.assertIsInstance(size, tuple)
|
||||
self.assertEqual(len(size), 2)
|
||||
|
||||
def test_get_part_size_invalid_index(self):
|
||||
"""Test getting size with invalid index"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
|
||||
with self.assertRaises(IndexError):
|
||||
renderable.get_part_size(5)
|
||||
|
||||
def test_render_single_part(self):
|
||||
"""Test rendering word with single part"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
result = renderable.render()
|
||||
|
||||
self.assertIsInstance(result, Image.Image)
|
||||
self.assertGreater(result.width, 0)
|
||||
self.assertGreater(result.height, 0)
|
||||
|
||||
@patch.object(Word, 'hyphenate')
|
||||
def test_render_multiple_parts(self, mock_hyphenate):
|
||||
"""Test rendering word with multiple parts"""
|
||||
# Mock hyphenation
|
||||
mock_hyphenate.return_value = True
|
||||
self.abstract_word._hyphenated_parts = ["test-", "ing"]
|
||||
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
renderable.update_from_word()
|
||||
result = renderable.render()
|
||||
|
||||
self.assertIsInstance(result, Image.Image)
|
||||
self.assertGreater(result.width, 0)
|
||||
self.assertGreater(result.height, 0)
|
||||
|
||||
def test_in_object_inside(self):
|
||||
"""Test in_object with point inside word"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
renderable.set_origin(10, 15)
|
||||
|
||||
# Point inside word bounds
|
||||
point = np.array([15, 20])
|
||||
# This test might fail if the actual size calculation differs
|
||||
# We'll check that the method returns a boolean
|
||||
result = renderable.in_object(point)
|
||||
self.assertIsInstance(result, (bool, np.bool_))
|
||||
|
||||
def test_in_object_outside(self):
|
||||
"""Test in_object with point outside word"""
|
||||
renderable = RenderableWord(self.abstract_word)
|
||||
renderable.set_origin(10, 15)
|
||||
|
||||
# Point clearly outside word bounds
|
||||
point = np.array([1000, 1000])
|
||||
self.assertFalse(renderable.in_object(point))
|
||||
|
||||
|
||||
class TestLine(unittest.TestCase):
|
||||
"""Test cases for the Line class"""
|
||||
|
||||
@@ -324,7 +195,7 @@ class TestLine(unittest.TestCase):
|
||||
|
||||
self.assertEqual(line._spacing, self.spacing)
|
||||
self.assertEqual(line._font, self.font)
|
||||
self.assertEqual(len(line._renderable_words), 0)
|
||||
self.assertEqual(len(line._text_objects), 0) # Updated to _text_objects
|
||||
self.assertEqual(line._current_width, 0)
|
||||
self.assertIsNone(line._previous)
|
||||
self.assertIsNone(line._next)
|
||||
@@ -337,11 +208,20 @@ class TestLine(unittest.TestCase):
|
||||
self.assertEqual(line._previous, previous_line)
|
||||
|
||||
def test_renderable_words_property(self):
|
||||
"""Test renderable_words property"""
|
||||
"""Test renderable_words property (compatibility)"""
|
||||
line = Line(self.spacing, self.origin, self.size, self.font)
|
||||
|
||||
self.assertIsInstance(line.renderable_words, list)
|
||||
self.assertEqual(len(line.renderable_words), 0)
|
||||
# Test that it returns the same as text_objects
|
||||
self.assertEqual(line.renderable_words, line.text_objects)
|
||||
|
||||
def test_text_objects_property(self):
|
||||
"""Test text_objects property"""
|
||||
line = Line(self.spacing, self.origin, self.size, self.font)
|
||||
|
||||
self.assertIsInstance(line.text_objects, list)
|
||||
self.assertEqual(len(line.text_objects), 0)
|
||||
|
||||
def test_set_next(self):
|
||||
"""Test setting next line"""
|
||||
@@ -357,7 +237,7 @@ class TestLine(unittest.TestCase):
|
||||
result = line.add_word("short")
|
||||
|
||||
self.assertIsNone(result) # Word fits, no overflow
|
||||
self.assertEqual(len(line._renderable_words), 1)
|
||||
self.assertEqual(len(line._text_objects), 1) # Updated to _text_objects
|
||||
self.assertGreater(line._current_width, 0)
|
||||
|
||||
def test_add_word_overflow(self):
|
||||
@@ -397,7 +277,7 @@ class TestLine(unittest.TestCase):
|
||||
line.add_word("second")
|
||||
line.add_word("third")
|
||||
|
||||
self.assertEqual(len(line._renderable_words), 3)
|
||||
self.assertEqual(len(line._text_objects), 3) # Updated to _text_objects
|
||||
self.assertGreater(line._current_width, 0)
|
||||
|
||||
def test_render_empty_line(self):
|
||||
@@ -462,6 +342,23 @@ class TestLine(unittest.TestCase):
|
||||
|
||||
self.assertIsInstance(result, Image.Image)
|
||||
self.assertEqual(result.size, tuple(self.size))
|
||||
|
||||
def test_text_objects_contain_text_instances(self):
|
||||
"""Test that text_objects contain Text instances"""
|
||||
line = Line(self.spacing, self.origin, self.size, self.font)
|
||||
line.add_word("test")
|
||||
|
||||
self.assertEqual(len(line.text_objects), 1)
|
||||
self.assertIsInstance(line.text_objects[0], Text)
|
||||
self.assertEqual(line.text_objects[0].text, "test")
|
||||
|
||||
def test_text_objects_linked_to_line(self):
|
||||
"""Test that Text objects are properly linked to the line"""
|
||||
line = Line(self.spacing, self.origin, self.size, self.font)
|
||||
line.add_word("test")
|
||||
|
||||
text_obj = line.text_objects[0]
|
||||
self.assertEqual(text_obj.line, line)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -49,7 +49,7 @@ class TestLineSplittingBug(unittest.TestCase):
|
||||
|
||||
# Check that the first part was added to the line
|
||||
self.assertEqual(len(line.renderable_words), 1)
|
||||
first_word_text = line.renderable_words[0].word.text
|
||||
first_word_text = line.renderable_words[0].text
|
||||
self.assertEqual(first_word_text, "super-")
|
||||
|
||||
# The overflow should be just the next part, not all parts joined
|
||||
@@ -75,7 +75,7 @@ class TestLineSplittingBug(unittest.TestCase):
|
||||
|
||||
# Check that the first part was added to the line
|
||||
self.assertEqual(len(line.renderable_words), 1)
|
||||
first_word_text = line.renderable_words[0].word.text
|
||||
first_word_text = line.renderable_words[0].text
|
||||
self.assertEqual(first_word_text, "very-")
|
||||
|
||||
# The overflow should be just the next part ("long"), not multiple parts joined
|
||||
@@ -99,7 +99,7 @@ class TestLineSplittingBug(unittest.TestCase):
|
||||
|
||||
# Only the first word should be in the line
|
||||
self.assertEqual(len(line.renderable_words), 1)
|
||||
self.assertEqual(line.renderable_words[0].word.text, "short")
|
||||
self.assertEqual(line.renderable_words[0].text, "short")
|
||||
|
||||
|
||||
def demonstrate_bug():
|
||||
@@ -123,7 +123,7 @@ def demonstrate_bug():
|
||||
|
||||
print(f"Original word: 'hyperlongexampleword'")
|
||||
print(f"Hyphenated to: 'hyper-long-example-word'")
|
||||
print(f"First part added to line: '{line.renderable_words[0].word.text if line.renderable_words else 'None'}'")
|
||||
print(f"First part added to line: '{line.renderable_words[0].text if line.renderable_words else 'None'}'")
|
||||
print(f"Overflow returned: '{overflow}'")
|
||||
print()
|
||||
print("PROBLEM: The overflow should be 'long-' (next part only)")
|
||||
|
||||
Reference in New Issue
Block a user