276 lines
8.8 KiB
Python
276 lines
8.8 KiB
Python
"""
|
|
Unit tests for abstract block elements.
|
|
|
|
Tests the core abstract block classes that form the foundation of the document model.
|
|
"""
|
|
|
|
import unittest
|
|
from pyWebLayout.abstract.block import (
|
|
Block, BlockType, Parapgraph, Heading, HeadingLevel, Quote, CodeBlock,
|
|
HList, ListStyle, ListItem, Table, TableRow, TableCell,
|
|
HorizontalRule, LineBreak, Image
|
|
)
|
|
from pyWebLayout.abstract.inline import Word
|
|
from pyWebLayout.style import Font
|
|
|
|
|
|
class TestBlockElements(unittest.TestCase):
|
|
"""Test cases for basic block elements."""
|
|
|
|
def test_paragraph_creation(self):
|
|
"""Test creating and using paragraphs."""
|
|
paragraph = Parapgraph()
|
|
|
|
self.assertEqual(paragraph.block_type, BlockType.PARAGRAPH)
|
|
self.assertEqual(paragraph.word_count, 0)
|
|
self.assertIsNone(paragraph.parent)
|
|
|
|
# Add words
|
|
font = Font()
|
|
word1 = Word("Hello", font)
|
|
word2 = Word("World", font)
|
|
|
|
paragraph.add_word(word1)
|
|
paragraph.add_word(word2)
|
|
|
|
self.assertEqual(paragraph.word_count, 2)
|
|
|
|
# Test word iteration
|
|
words = list(paragraph.words())
|
|
self.assertEqual(len(words), 2)
|
|
self.assertEqual(words[0][1].text, "Hello")
|
|
self.assertEqual(words[1][1].text, "World")
|
|
|
|
def test_heading_levels(self):
|
|
"""Test heading creation with different levels."""
|
|
h1 = Heading(HeadingLevel.H1)
|
|
h3 = Heading(HeadingLevel.H3)
|
|
h6 = Heading(HeadingLevel.H6)
|
|
|
|
self.assertEqual(h1.level, HeadingLevel.H1)
|
|
self.assertEqual(h3.level, HeadingLevel.H3)
|
|
self.assertEqual(h6.level, HeadingLevel.H6)
|
|
|
|
self.assertEqual(h1.block_type, BlockType.HEADING)
|
|
|
|
# Test level modification
|
|
h1.level = HeadingLevel.H2
|
|
self.assertEqual(h1.level, HeadingLevel.H2)
|
|
|
|
def test_quote_nesting(self):
|
|
"""Test blockquote with nested content."""
|
|
quote = Quote()
|
|
|
|
# Add nested paragraphs
|
|
p1 = Parapgraph()
|
|
p2 = Parapgraph()
|
|
|
|
quote.add_block(p1)
|
|
quote.add_block(p2)
|
|
|
|
self.assertEqual(p1.parent, quote)
|
|
self.assertEqual(p2.parent, quote)
|
|
|
|
# Test block iteration
|
|
blocks = list(quote.blocks())
|
|
self.assertEqual(len(blocks), 2)
|
|
self.assertEqual(blocks[0], p1)
|
|
self.assertEqual(blocks[1], p2)
|
|
|
|
def test_code_block(self):
|
|
"""Test code block functionality."""
|
|
code = CodeBlock("python")
|
|
|
|
self.assertEqual(code.language, "python")
|
|
self.assertEqual(code.line_count, 0)
|
|
|
|
# Add code lines
|
|
code.add_line("def hello():")
|
|
code.add_line(" print('Hello!')")
|
|
|
|
self.assertEqual(code.line_count, 2)
|
|
|
|
# Test line iteration
|
|
lines = list(code.lines())
|
|
self.assertEqual(len(lines), 2)
|
|
self.assertEqual(lines[0][1], "def hello():")
|
|
self.assertEqual(lines[1][1], " print('Hello!')")
|
|
|
|
# Test language modification
|
|
code.language = "javascript"
|
|
self.assertEqual(code.language, "javascript")
|
|
|
|
def test_list_creation(self):
|
|
"""Test list creation and item management."""
|
|
# Unordered list
|
|
ul = HList(ListStyle.UNORDERED)
|
|
self.assertEqual(ul.style, ListStyle.UNORDERED)
|
|
self.assertEqual(ul.item_count, 0)
|
|
|
|
# Add list items
|
|
item1 = ListItem()
|
|
item2 = ListItem()
|
|
|
|
ul.add_item(item1)
|
|
ul.add_item(item2)
|
|
|
|
self.assertEqual(ul.item_count, 2)
|
|
self.assertEqual(item1.parent, ul)
|
|
self.assertEqual(item2.parent, ul)
|
|
|
|
# Test item iteration
|
|
items = list(ul.items())
|
|
self.assertEqual(len(items), 2)
|
|
|
|
# Test list style change
|
|
ul.style = ListStyle.ORDERED
|
|
self.assertEqual(ul.style, ListStyle.ORDERED)
|
|
|
|
def test_definition_list(self):
|
|
"""Test definition list with terms."""
|
|
dl = HList(ListStyle.DEFINITION)
|
|
|
|
# Add definition items with terms
|
|
dt1 = ListItem(term="Python")
|
|
dt2 = ListItem(term="JavaScript")
|
|
|
|
dl.add_item(dt1)
|
|
dl.add_item(dt2)
|
|
|
|
self.assertEqual(dt1.term, "Python")
|
|
self.assertEqual(dt2.term, "JavaScript")
|
|
|
|
# Test term modification
|
|
dt1.term = "Python 3"
|
|
self.assertEqual(dt1.term, "Python 3")
|
|
|
|
def test_table_structure(self):
|
|
"""Test table, row, and cell structure."""
|
|
table = Table(caption="Test Table")
|
|
|
|
self.assertEqual(table.caption, "Test Table")
|
|
self.assertEqual(table.row_count["total"], 0)
|
|
|
|
# Create rows and cells
|
|
header_row = TableRow()
|
|
data_row = TableRow()
|
|
|
|
# Header cells
|
|
h1 = TableCell(is_header=True)
|
|
h2 = TableCell(is_header=True)
|
|
header_row.add_cell(h1)
|
|
header_row.add_cell(h2)
|
|
|
|
# Data cells
|
|
d1 = TableCell(is_header=False)
|
|
d2 = TableCell(is_header=False, colspan=2)
|
|
data_row.add_cell(d1)
|
|
data_row.add_cell(d2)
|
|
|
|
# Add rows to table
|
|
table.add_row(header_row, "header")
|
|
table.add_row(data_row, "body")
|
|
|
|
# Test structure
|
|
self.assertEqual(table.row_count["header"], 1)
|
|
self.assertEqual(table.row_count["body"], 1)
|
|
self.assertEqual(table.row_count["total"], 2)
|
|
|
|
# Test cell properties
|
|
self.assertTrue(h1.is_header)
|
|
self.assertFalse(d1.is_header)
|
|
self.assertEqual(d2.colspan, 2)
|
|
self.assertEqual(d2.rowspan, 1) # Default
|
|
|
|
# Test row cell count
|
|
self.assertEqual(header_row.cell_count, 2)
|
|
self.assertEqual(data_row.cell_count, 2)
|
|
|
|
def test_table_sections(self):
|
|
"""Test table header, body, and footer sections."""
|
|
table = Table()
|
|
|
|
# Add rows to different sections
|
|
header = TableRow()
|
|
body1 = TableRow()
|
|
body2 = TableRow()
|
|
footer = TableRow()
|
|
|
|
table.add_row(header, "header")
|
|
table.add_row(body1, "body")
|
|
table.add_row(body2, "body")
|
|
table.add_row(footer, "footer")
|
|
|
|
# Test section iteration
|
|
header_rows = list(table.header_rows())
|
|
body_rows = list(table.body_rows())
|
|
footer_rows = list(table.footer_rows())
|
|
|
|
self.assertEqual(len(header_rows), 1)
|
|
self.assertEqual(len(body_rows), 2)
|
|
self.assertEqual(len(footer_rows), 1)
|
|
|
|
# Test all_rows iteration
|
|
all_rows = list(table.all_rows())
|
|
self.assertEqual(len(all_rows), 4)
|
|
|
|
# Check section labels
|
|
sections = [section for section, row in all_rows]
|
|
self.assertEqual(sections, ["header", "body", "body", "footer"])
|
|
|
|
def test_image_loading(self):
|
|
"""Test image element properties."""
|
|
# Test with basic properties
|
|
img = Image("test.jpg", "Test image", 100, 200)
|
|
|
|
self.assertEqual(img.source, "test.jpg")
|
|
self.assertEqual(img.alt_text, "Test image")
|
|
self.assertEqual(img.width, 100)
|
|
self.assertEqual(img.height, 200)
|
|
|
|
# Test property modification
|
|
img.source = "new.png"
|
|
img.alt_text = "New image"
|
|
img.width = 150
|
|
img.height = 300
|
|
|
|
self.assertEqual(img.source, "new.png")
|
|
self.assertEqual(img.alt_text, "New image")
|
|
self.assertEqual(img.width, 150)
|
|
self.assertEqual(img.height, 300)
|
|
|
|
# Test dimensions tuple
|
|
self.assertEqual(img.get_dimensions(), (150, 300))
|
|
|
|
def test_aspect_ratio_calculation(self):
|
|
"""Test image aspect ratio calculations."""
|
|
# Test with specified dimensions
|
|
img = Image("test.jpg", width=400, height=200)
|
|
self.assertEqual(img.get_aspect_ratio(), 2.0) # 400/200
|
|
|
|
# Test with only one dimension
|
|
img2 = Image("test.jpg", width=300)
|
|
self.assertIsNone(img2.get_aspect_ratio()) # No height specified
|
|
|
|
# Test scaled dimensions
|
|
scaled = img.calculate_scaled_dimensions(max_width=200, max_height=150)
|
|
# Should scale down proportionally
|
|
self.assertEqual(scaled[0], 200) # Width limited by max_width
|
|
self.assertEqual(scaled[1], 100) # Height scaled proportionally
|
|
|
|
def test_simple_elements(self):
|
|
"""Test simple block elements."""
|
|
hr = HorizontalRule()
|
|
br = LineBreak()
|
|
|
|
self.assertEqual(hr.block_type, BlockType.HORIZONTAL_RULE)
|
|
self.assertEqual(br.block_type, BlockType.LINE_BREAK)
|
|
|
|
# These elements have no additional properties
|
|
self.assertIsNone(hr.parent)
|
|
self.assertIsNone(br.parent)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|