""" 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 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) if __name__ == '__main__': unittest.main()