688 lines
24 KiB
Python
688 lines
24 KiB
Python
"""
|
|
Unit tests for abstract document elements.
|
|
|
|
Tests the Document, Chapter, Book, and MetadataType classes that handle
|
|
document structure and metadata management.
|
|
"""
|
|
|
|
import unittest
|
|
from pyWebLayout.abstract.document import Document, Chapter, Book, MetadataType
|
|
from pyWebLayout.abstract.block import Paragraph, Heading, HeadingLevel, BlockType
|
|
from pyWebLayout.abstract.inline import Word, FormattedSpan
|
|
from pyWebLayout.style import Font, FontWeight, FontStyle, TextDecoration
|
|
|
|
|
|
class TestMetadataType(unittest.TestCase):
|
|
"""Test cases for MetadataType enum."""
|
|
|
|
def test_metadata_types(self):
|
|
"""Test that all expected metadata types exist."""
|
|
expected_types = [
|
|
'TITLE', 'AUTHOR', 'DESCRIPTION', 'KEYWORDS', 'LANGUAGE',
|
|
'PUBLICATION_DATE', 'MODIFIED_DATE', 'PUBLISHER', 'IDENTIFIER',
|
|
'COVER_IMAGE', 'CUSTOM'
|
|
]
|
|
|
|
for type_name in expected_types:
|
|
self.assertTrue(hasattr(MetadataType, type_name))
|
|
|
|
# Test custom type has expected value
|
|
self.assertEqual(MetadataType.CUSTOM.value, 100)
|
|
|
|
|
|
class TestDocument(unittest.TestCase):
|
|
"""Test cases for Document class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.doc = Document("Test Document", "en-US")
|
|
self.font = Font()
|
|
|
|
def test_document_creation(self):
|
|
"""Test document creation with basic parameters."""
|
|
self.assertEqual(self.doc.get_title(), "Test Document")
|
|
self.assertEqual(self.doc.get_metadata(MetadataType.LANGUAGE), "en-US")
|
|
self.assertEqual(len(self.doc.blocks), 0)
|
|
|
|
def test_document_creation_minimal(self):
|
|
"""Test document creation with minimal parameters."""
|
|
doc = Document()
|
|
self.assertIsNone(doc.get_title())
|
|
self.assertEqual(doc.get_metadata(MetadataType.LANGUAGE), "en-US")
|
|
|
|
def test_metadata_management(self):
|
|
"""Test setting and getting metadata."""
|
|
# Set various metadata types
|
|
self.doc.set_metadata(MetadataType.AUTHOR, "John Doe")
|
|
self.doc.set_metadata(MetadataType.DESCRIPTION, "A test document")
|
|
self.doc.set_metadata(MetadataType.KEYWORDS, ["test", "document"])
|
|
|
|
# Test retrieval
|
|
self.assertEqual(self.doc.get_metadata(MetadataType.AUTHOR), "John Doe")
|
|
self.assertEqual(self.doc.get_metadata(MetadataType.DESCRIPTION), "A test document")
|
|
self.assertEqual(self.doc.get_metadata(MetadataType.KEYWORDS), ["test", "document"])
|
|
|
|
# Test non-existent metadata
|
|
self.assertIsNone(self.doc.get_metadata(MetadataType.PUBLISHER))
|
|
|
|
def test_title_convenience_methods(self):
|
|
"""Test title getter and setter convenience methods."""
|
|
# Test setting title
|
|
self.doc.set_title("New Title")
|
|
self.assertEqual(self.doc.get_title(), "New Title")
|
|
|
|
# Test that it's also in metadata
|
|
self.assertEqual(self.doc.get_metadata(MetadataType.TITLE), "New Title")
|
|
|
|
def test_block_management(self):
|
|
"""Test adding and managing blocks."""
|
|
# Create some blocks
|
|
para1 = Paragraph()
|
|
para2 = Paragraph()
|
|
heading = Heading(HeadingLevel.H1)
|
|
|
|
# Add blocks
|
|
self.doc.add_block(para1)
|
|
self.doc.add_block(heading)
|
|
self.doc.add_block(para2)
|
|
|
|
# Test blocks list
|
|
self.assertEqual(len(self.doc.blocks), 3)
|
|
self.assertEqual(self.doc.blocks[0], para1)
|
|
self.assertEqual(self.doc.blocks[1], heading)
|
|
self.assertEqual(self.doc.blocks[2], para2)
|
|
|
|
def test_anchor_management(self):
|
|
"""Test named anchor functionality."""
|
|
heading = Heading(HeadingLevel.H1)
|
|
para = Paragraph()
|
|
|
|
# Add anchors
|
|
self.doc.add_anchor("intro", heading)
|
|
self.doc.add_anchor("content", para)
|
|
|
|
# Test retrieval
|
|
self.assertEqual(self.doc.get_anchor("intro"), heading)
|
|
self.assertEqual(self.doc.get_anchor("content"), para)
|
|
self.assertIsNone(self.doc.get_anchor("nonexistent"))
|
|
|
|
def test_resource_management(self):
|
|
"""Test document resource management."""
|
|
# Add various resources
|
|
self.doc.add_resource("image1", {"type": "image", "path": "test.jpg"})
|
|
self.doc.add_resource("style1", {"type": "css", "content": "body {}"})
|
|
|
|
# Test retrieval
|
|
image = self.doc.get_resource("image1")
|
|
self.assertEqual(image["type"], "image")
|
|
self.assertEqual(image["path"], "test.jpg")
|
|
|
|
style = self.doc.get_resource("style1")
|
|
self.assertEqual(style["type"], "css")
|
|
|
|
# Test non-existent resource
|
|
self.assertIsNone(self.doc.get_resource("nonexistent"))
|
|
|
|
def test_stylesheet_management(self):
|
|
"""Test stylesheet addition."""
|
|
# Add stylesheets
|
|
css1 = {"href": "style.css", "type": "text/css"}
|
|
css2 = {"href": "theme.css", "type": "text/css"}
|
|
|
|
self.doc.add_stylesheet(css1)
|
|
self.doc.add_stylesheet(css2)
|
|
|
|
# Test that stylesheets are stored
|
|
self.assertEqual(len(self.doc._stylesheets), 2)
|
|
self.assertEqual(self.doc._stylesheets[0], css1)
|
|
self.assertEqual(self.doc._stylesheets[1], css2)
|
|
|
|
def test_script_management(self):
|
|
"""Test script addition."""
|
|
# Add scripts
|
|
script1 = "console.log('Hello');"
|
|
script2 = "document.ready(function(){});"
|
|
|
|
self.doc.add_script(script1)
|
|
self.doc.add_script(script2)
|
|
|
|
# Test that scripts are stored
|
|
self.assertEqual(len(self.doc._scripts), 2)
|
|
self.assertEqual(self.doc._scripts[0], script1)
|
|
self.assertEqual(self.doc._scripts[1], script2)
|
|
|
|
def test_find_blocks_by_type(self):
|
|
"""Test finding blocks by type."""
|
|
# Create blocks of different types
|
|
para1 = Paragraph()
|
|
para2 = Paragraph()
|
|
heading1 = Heading(HeadingLevel.H1)
|
|
heading2 = Heading(HeadingLevel.H2)
|
|
|
|
# Add blocks to document
|
|
self.doc.add_block(para1)
|
|
self.doc.add_block(heading1)
|
|
self.doc.add_block(para2)
|
|
self.doc.add_block(heading2)
|
|
|
|
# Test finding paragraphs
|
|
paragraphs = self.doc.find_blocks_by_type(BlockType.PARAGRAPH)
|
|
self.assertEqual(len(paragraphs), 2)
|
|
self.assertIn(para1, paragraphs)
|
|
self.assertIn(para2, paragraphs)
|
|
|
|
# Test finding headings
|
|
headings = self.doc.find_blocks_by_type(BlockType.HEADING)
|
|
self.assertEqual(len(headings), 2)
|
|
self.assertIn(heading1, headings)
|
|
self.assertIn(heading2, headings)
|
|
|
|
def test_find_headings(self):
|
|
"""Test finding heading blocks specifically."""
|
|
# Create mixed blocks
|
|
para = Paragraph()
|
|
h1 = Heading(HeadingLevel.H1)
|
|
h2 = Heading(HeadingLevel.H2)
|
|
|
|
# Add words to headings for title extraction
|
|
word1 = Word("Chapter", self.font)
|
|
word2 = Word("One", self.font)
|
|
h1.add_word(word1)
|
|
h1.add_word(word2)
|
|
|
|
word3 = Word("Section", self.font)
|
|
h2.add_word(word3)
|
|
|
|
self.doc.add_block(para)
|
|
self.doc.add_block(h1)
|
|
self.doc.add_block(h2)
|
|
|
|
# Test finding headings
|
|
headings = self.doc.find_headings()
|
|
self.assertEqual(len(headings), 2)
|
|
self.assertIn(h1, headings)
|
|
self.assertIn(h2, headings)
|
|
self.assertNotIn(para, headings)
|
|
|
|
def test_generate_table_of_contents(self):
|
|
"""Test table of contents generation."""
|
|
# Create headings with content
|
|
h1 = Heading(HeadingLevel.H1)
|
|
h2 = Heading(HeadingLevel.H2)
|
|
h3 = Heading(HeadingLevel.H3)
|
|
|
|
# Add words to headings
|
|
h1.add_word(Word("Introduction", self.font))
|
|
h2.add_word(Word("Getting", self.font))
|
|
h2.add_word(Word("Started", self.font))
|
|
h3.add_word(Word("Installation", self.font))
|
|
|
|
self.doc.add_block(h1)
|
|
self.doc.add_block(h2)
|
|
self.doc.add_block(h3)
|
|
|
|
# Generate TOC
|
|
toc = self.doc.generate_table_of_contents()
|
|
|
|
# Test TOC structure
|
|
self.assertEqual(len(toc), 3)
|
|
|
|
# Test first entry
|
|
level, title, block = toc[0]
|
|
self.assertEqual(level, 1) # H1
|
|
self.assertEqual(title, "Introduction")
|
|
self.assertEqual(block, h1)
|
|
|
|
# Test second entry
|
|
level, title, block = toc[1]
|
|
self.assertEqual(level, 2) # H2
|
|
self.assertEqual(title, "Getting Started")
|
|
self.assertEqual(block, h2)
|
|
|
|
# Test third entry
|
|
level, title, block = toc[2]
|
|
self.assertEqual(level, 3) # H3
|
|
self.assertEqual(title, "Installation")
|
|
self.assertEqual(block, h3)
|
|
|
|
|
|
class TestChapter(unittest.TestCase):
|
|
"""Test cases for Chapter class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.chapter = Chapter("Test Chapter", 1)
|
|
|
|
def test_chapter_creation(self):
|
|
"""Test chapter creation."""
|
|
self.assertEqual(self.chapter.title, "Test Chapter")
|
|
self.assertEqual(self.chapter.level, 1)
|
|
self.assertEqual(len(self.chapter.blocks), 0)
|
|
|
|
def test_chapter_creation_minimal(self):
|
|
"""Test chapter creation with minimal parameters."""
|
|
chapter = Chapter()
|
|
self.assertIsNone(chapter.title)
|
|
self.assertEqual(chapter.level, 1)
|
|
|
|
def test_title_property(self):
|
|
"""Test title property getter and setter."""
|
|
# Test setter
|
|
self.chapter.title = "New Chapter Title"
|
|
self.assertEqual(self.chapter.title, "New Chapter Title")
|
|
|
|
# Test setting to None
|
|
self.chapter.title = None
|
|
self.assertIsNone(self.chapter.title)
|
|
|
|
def test_level_property(self):
|
|
"""Test level property."""
|
|
self.assertEqual(self.chapter.level, 1)
|
|
|
|
# Level should be read-only (no setter test)
|
|
# This is by design based on the class definition
|
|
|
|
def test_block_management(self):
|
|
"""Test adding blocks to chapter."""
|
|
para1 = Paragraph()
|
|
para2 = Paragraph()
|
|
heading = Heading(HeadingLevel.H2)
|
|
|
|
# Add blocks
|
|
self.chapter.add_block(para1)
|
|
self.chapter.add_block(heading)
|
|
self.chapter.add_block(para2)
|
|
|
|
# Test blocks list
|
|
self.assertEqual(len(self.chapter.blocks), 3)
|
|
self.assertEqual(self.chapter.blocks[0], para1)
|
|
self.assertEqual(self.chapter.blocks[1], heading)
|
|
self.assertEqual(self.chapter.blocks[2], para2)
|
|
|
|
def test_metadata_management(self):
|
|
"""Test chapter metadata."""
|
|
# Set metadata
|
|
self.chapter.set_metadata("author", "Jane Doe")
|
|
self.chapter.set_metadata("word_count", 1500)
|
|
self.chapter.set_metadata("tags", ["intro", "basics"])
|
|
|
|
# Test retrieval
|
|
self.assertEqual(self.chapter.get_metadata("author"), "Jane Doe")
|
|
self.assertEqual(self.chapter.get_metadata("word_count"), 1500)
|
|
self.assertEqual(self.chapter.get_metadata("tags"), ["intro", "basics"])
|
|
|
|
# Test non-existent metadata
|
|
self.assertIsNone(self.chapter.get_metadata("nonexistent"))
|
|
|
|
|
|
class TestBook(unittest.TestCase):
|
|
"""Test cases for Book class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.book = Book("Test Book", "Author Name", "en-US")
|
|
|
|
def test_book_creation(self):
|
|
"""Test book creation with all parameters."""
|
|
self.assertEqual(self.book.get_title(), "Test Book")
|
|
self.assertEqual(self.book.get_author(), "Author Name")
|
|
self.assertEqual(self.book.get_metadata(MetadataType.LANGUAGE), "en-US")
|
|
self.assertEqual(len(self.book.chapters), 0)
|
|
|
|
def test_book_creation_minimal(self):
|
|
"""Test book creation with minimal parameters."""
|
|
book = Book()
|
|
self.assertIsNone(book.get_title())
|
|
self.assertIsNone(book.get_author())
|
|
self.assertEqual(book.get_metadata(MetadataType.LANGUAGE), "en-US")
|
|
|
|
def test_book_creation_partial(self):
|
|
"""Test book creation with partial parameters."""
|
|
book = Book(title="Just Title")
|
|
self.assertEqual(book.get_title(), "Just Title")
|
|
self.assertIsNone(book.get_author())
|
|
|
|
def test_author_convenience_methods(self):
|
|
"""Test author getter and setter convenience methods."""
|
|
# Test setting author
|
|
self.book.set_author("New Author")
|
|
self.assertEqual(self.book.get_author(), "New Author")
|
|
|
|
# Test that it's also in metadata
|
|
self.assertEqual(self.book.get_metadata(MetadataType.AUTHOR), "New Author")
|
|
|
|
def test_chapter_management(self):
|
|
"""Test adding and managing chapters."""
|
|
# Create chapters
|
|
ch1 = Chapter("Introduction", 1)
|
|
ch2 = Chapter("Getting Started", 1)
|
|
ch3 = Chapter("Advanced Topics", 1)
|
|
|
|
# Add chapters
|
|
self.book.add_chapter(ch1)
|
|
self.book.add_chapter(ch2)
|
|
self.book.add_chapter(ch3)
|
|
|
|
# Test chapters list
|
|
self.assertEqual(len(self.book.chapters), 3)
|
|
self.assertEqual(self.book.chapters[0], ch1)
|
|
self.assertEqual(self.book.chapters[1], ch2)
|
|
self.assertEqual(self.book.chapters[2], ch3)
|
|
|
|
def test_create_chapter(self):
|
|
"""Test creating chapters through the book."""
|
|
# Create chapter with title and level
|
|
ch1 = self.book.create_chapter("Chapter 1", 1)
|
|
self.assertEqual(ch1.title, "Chapter 1")
|
|
self.assertEqual(ch1.level, 1)
|
|
self.assertEqual(len(self.book.chapters), 1)
|
|
self.assertEqual(self.book.chapters[0], ch1)
|
|
|
|
# Create chapter with minimal parameters
|
|
ch2 = self.book.create_chapter()
|
|
self.assertIsNone(ch2.title)
|
|
self.assertEqual(ch2.level, 1)
|
|
self.assertEqual(len(self.book.chapters), 2)
|
|
|
|
def test_generate_book_toc(self):
|
|
"""Test table of contents generation for book."""
|
|
# Create chapters with different levels
|
|
ch1 = Chapter("Introduction", 1)
|
|
ch2 = Chapter("Getting Started", 1)
|
|
ch3 = Chapter("Basic Concepts", 2)
|
|
ch4 = Chapter("Advanced Topics", 1)
|
|
ch5 = Chapter("Best Practices", 2)
|
|
|
|
# Add chapters to book
|
|
self.book.add_chapter(ch1)
|
|
self.book.add_chapter(ch2)
|
|
self.book.add_chapter(ch3)
|
|
self.book.add_chapter(ch4)
|
|
self.book.add_chapter(ch5)
|
|
|
|
# Generate TOC
|
|
toc = self.book.generate_table_of_contents()
|
|
|
|
# Test TOC structure
|
|
self.assertEqual(len(toc), 5)
|
|
|
|
# Test entries
|
|
expected = [
|
|
(1, "Introduction", ch1),
|
|
(1, "Getting Started", ch2),
|
|
(2, "Basic Concepts", ch3),
|
|
(1, "Advanced Topics", ch4),
|
|
(2, "Best Practices", ch5)
|
|
]
|
|
|
|
for i, (exp_level, exp_title, exp_chapter) in enumerate(expected):
|
|
level, title, chapter = toc[i]
|
|
self.assertEqual(level, exp_level)
|
|
self.assertEqual(title, exp_title)
|
|
self.assertEqual(chapter, exp_chapter)
|
|
|
|
def test_generate_book_toc_with_untitled_chapters(self):
|
|
"""Test TOC generation with chapters that have no title."""
|
|
# Create chapters, some without titles
|
|
ch1 = Chapter("Introduction", 1)
|
|
ch2 = Chapter(None, 1) # No title
|
|
ch3 = Chapter("Conclusion", 1)
|
|
|
|
self.book.add_chapter(ch1)
|
|
self.book.add_chapter(ch2)
|
|
self.book.add_chapter(ch3)
|
|
|
|
# Generate TOC
|
|
toc = self.book.generate_table_of_contents()
|
|
|
|
# Should only include chapters with titles
|
|
self.assertEqual(len(toc), 2)
|
|
|
|
level, title, chapter = toc[0]
|
|
self.assertEqual(title, "Introduction")
|
|
self.assertEqual(chapter, ch1)
|
|
|
|
level, title, chapter = toc[1]
|
|
self.assertEqual(title, "Conclusion")
|
|
self.assertEqual(chapter, ch3)
|
|
|
|
def test_book_inherits_document_features(self):
|
|
"""Test that Book inherits all Document functionality."""
|
|
# Test that book can use all document methods
|
|
# Add blocks directly to book
|
|
para = Paragraph()
|
|
self.book.add_block(para)
|
|
self.assertEqual(len(self.book.blocks), 1)
|
|
|
|
# Test metadata
|
|
self.book.set_metadata(MetadataType.PUBLISHER, "Test Publisher")
|
|
self.assertEqual(self.book.get_metadata(MetadataType.PUBLISHER), "Test Publisher")
|
|
|
|
# Test anchors
|
|
heading = Heading(HeadingLevel.H1)
|
|
self.book.add_anchor("preface", heading)
|
|
self.assertEqual(self.book.get_anchor("preface"), heading)
|
|
|
|
|
|
class TestDocumentFontRegistry(unittest.TestCase):
|
|
"""Test cases for Document font registry functionality."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.doc = Document("Test Document", "en-US")
|
|
|
|
def test_get_or_create_font_creates_new_font(self):
|
|
"""Test that get_or_create_font creates a new font when none exists."""
|
|
font = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
self.assertEqual(font.font_size, 14)
|
|
self.assertEqual(font.colour, (255, 0, 0))
|
|
self.assertEqual(font.weight, FontWeight.BOLD)
|
|
|
|
# Check that font is stored in registry
|
|
self.assertEqual(len(self.doc._fonts), 1)
|
|
|
|
def test_get_or_create_font_reuses_existing_font(self):
|
|
"""Test that get_or_create_font reuses existing fonts."""
|
|
# Create first font
|
|
font1 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create second font with same properties
|
|
font2 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Should return the same font object
|
|
self.assertIs(font1, font2)
|
|
|
|
# Should only have one font in registry
|
|
self.assertEqual(len(self.doc._fonts), 1)
|
|
|
|
def test_get_or_create_font_creates_different_fonts(self):
|
|
"""Test that different font properties create different fonts."""
|
|
# Create first font
|
|
font1 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create font with different size
|
|
font2 = self.doc.get_or_create_font(
|
|
font_size=16,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create font with different color
|
|
font3 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(0, 255, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create font with different weight
|
|
font4 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.NORMAL
|
|
)
|
|
|
|
# All should be different objects
|
|
self.assertIsNot(font1, font2)
|
|
self.assertIsNot(font1, font3)
|
|
self.assertIsNot(font1, font4)
|
|
self.assertIsNot(font2, font3)
|
|
self.assertIsNot(font2, font4)
|
|
self.assertIsNot(font3, font4)
|
|
|
|
# Should have four fonts in registry
|
|
self.assertEqual(len(self.doc._fonts), 4)
|
|
|
|
def test_get_or_create_font_with_all_parameters(self):
|
|
"""Test get_or_create_font with all parameters."""
|
|
font = self.doc.get_or_create_font(
|
|
font_path="path/to/font.ttf",
|
|
font_size=18,
|
|
colour=(128, 64, 192),
|
|
weight=FontWeight.BOLD,
|
|
style=FontStyle.ITALIC,
|
|
decoration=TextDecoration.UNDERLINE,
|
|
background=(255, 255, 255, 128),
|
|
language="fr_FR",
|
|
min_hyphenation_width=80
|
|
)
|
|
|
|
self.assertEqual(font._font_path, "path/to/font.ttf")
|
|
self.assertEqual(font.font_size, 18)
|
|
self.assertEqual(font.colour, (128, 64, 192))
|
|
self.assertEqual(font.weight, FontWeight.BOLD)
|
|
self.assertEqual(font.style, FontStyle.ITALIC)
|
|
self.assertEqual(font.decoration, TextDecoration.UNDERLINE)
|
|
self.assertEqual(font.background, (255, 255, 255, 128))
|
|
self.assertEqual(font.language, "fr_FR")
|
|
self.assertEqual(font.min_hyphenation_width, 80)
|
|
|
|
def test_get_or_create_font_with_defaults(self):
|
|
"""Test get_or_create_font with default values."""
|
|
font = self.doc.get_or_create_font()
|
|
|
|
# Should create font with default values
|
|
self.assertIsNotNone(font)
|
|
self.assertEqual(font.font_size, 16) # Default font size
|
|
self.assertEqual(font.colour, (0, 0, 0)) # Default black color
|
|
self.assertEqual(font.weight, FontWeight.NORMAL)
|
|
self.assertEqual(font.style, FontStyle.NORMAL)
|
|
self.assertEqual(font.decoration, TextDecoration.NONE)
|
|
|
|
|
|
class TestChapterFontRegistry(unittest.TestCase):
|
|
"""Test cases for Chapter font registry functionality."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.doc = Document("Test Document", "en-US")
|
|
self.chapter = Chapter("Test Chapter", 1, parent=self.doc)
|
|
|
|
def test_chapter_uses_parent_font_registry(self):
|
|
"""Test that chapter uses parent document's font registry."""
|
|
# Create font through chapter - should delegate to parent
|
|
font1 = self.chapter.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create same font through document - should return same object
|
|
font2 = self.doc.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Should be the same font object
|
|
self.assertIs(font1, font2)
|
|
|
|
# Should be stored in document's registry, not chapter's
|
|
self.assertEqual(len(self.doc._fonts), 1)
|
|
self.assertEqual(len(self.chapter._fonts), 0)
|
|
|
|
def test_chapter_without_parent_manages_own_fonts(self):
|
|
"""Test that chapter without parent manages its own fonts."""
|
|
# Create chapter without parent
|
|
standalone_chapter = Chapter("Standalone Chapter", 1)
|
|
|
|
# Create font through chapter
|
|
font1 = standalone_chapter.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create same font again - should reuse
|
|
font2 = standalone_chapter.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Should be the same font object
|
|
self.assertIs(font1, font2)
|
|
|
|
# Should be stored in chapter's own registry
|
|
self.assertEqual(len(standalone_chapter._fonts), 1)
|
|
|
|
def test_chapter_parent_assignment(self):
|
|
"""Test that chapter parent assignment works correctly."""
|
|
# Create chapter with parent
|
|
chapter_with_parent = Chapter("Chapter with Parent", 1, parent=self.doc)
|
|
self.assertEqual(chapter_with_parent._parent, self.doc)
|
|
|
|
# Create chapter without parent
|
|
chapter_without_parent = Chapter("Chapter without Parent", 1)
|
|
self.assertIsNone(chapter_without_parent._parent)
|
|
|
|
|
|
class TestBookFontRegistry(unittest.TestCase):
|
|
"""Test cases for Book font registry functionality."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.book = Book("Test Book", "Author Name", "en-US")
|
|
|
|
def test_book_inherits_document_font_registry(self):
|
|
"""Test that Book inherits Document's font registry functionality."""
|
|
# Create font through book
|
|
font1 = self.book.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Create same font again - should reuse
|
|
font2 = self.book.get_or_create_font(
|
|
font_size=14,
|
|
colour=(255, 0, 0),
|
|
weight=FontWeight.BOLD
|
|
)
|
|
|
|
# Should be the same font object
|
|
self.assertIs(font1, font2)
|
|
|
|
# Should have one font in registry
|
|
self.assertEqual(len(self.book._fonts), 1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|