This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Unit tests for manager modules."""
|
||||
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Unit tests for DocumentManager.
|
||||
|
||||
Tests document loading in isolation without full EbookReader.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dreader.managers.document import DocumentManager
|
||||
|
||||
|
||||
class TestDocumentManager(unittest.TestCase):
|
||||
"""Test DocumentManager in isolation"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test environment"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.epub_path = "tests/data/test.epub"
|
||||
self.manager = DocumentManager()
|
||||
|
||||
def tearDown(self):
|
||||
"""Clean up"""
|
||||
import shutil
|
||||
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test manager initializes correctly"""
|
||||
manager = DocumentManager()
|
||||
|
||||
self.assertIsNone(manager.document_id)
|
||||
self.assertIsNone(manager.title)
|
||||
self.assertIsNone(manager.author)
|
||||
self.assertIsNone(manager.blocks)
|
||||
self.assertFalse(manager.is_loaded())
|
||||
|
||||
def test_load_valid_epub(self):
|
||||
"""Test loading a valid EPUB file"""
|
||||
if not Path(self.epub_path).exists():
|
||||
self.skipTest(f"Test EPUB not found at {self.epub_path}")
|
||||
|
||||
success = self.manager.load_epub(self.epub_path)
|
||||
|
||||
self.assertTrue(success)
|
||||
self.assertTrue(self.manager.is_loaded())
|
||||
self.assertIsNotNone(self.manager.document_id)
|
||||
self.assertIsNotNone(self.manager.title)
|
||||
self.assertIsNotNone(self.manager.author)
|
||||
self.assertIsNotNone(self.manager.blocks)
|
||||
self.assertGreater(len(self.manager.blocks), 0)
|
||||
|
||||
def test_load_nonexistent_epub(self):
|
||||
"""Test loading a non-existent EPUB file"""
|
||||
success = self.manager.load_epub("nonexistent.epub")
|
||||
|
||||
self.assertFalse(success)
|
||||
self.assertFalse(self.manager.is_loaded())
|
||||
|
||||
def test_load_invalid_epub(self):
|
||||
"""Test loading an invalid file as EPUB"""
|
||||
# Create a temporary invalid file
|
||||
invalid_path = os.path.join(self.temp_dir, "invalid.epub")
|
||||
with open(invalid_path, 'w') as f:
|
||||
f.write("This is not a valid EPUB file")
|
||||
|
||||
success = self.manager.load_epub(invalid_path)
|
||||
|
||||
self.assertFalse(success)
|
||||
self.assertFalse(self.manager.is_loaded())
|
||||
|
||||
def test_load_html_success(self):
|
||||
"""Test loading HTML content"""
|
||||
html = """
|
||||
<html>
|
||||
<body>
|
||||
<h1>Test Document</h1>
|
||||
<p>This is a test paragraph.</p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
success = self.manager.load_html(
|
||||
html,
|
||||
title="Test HTML",
|
||||
author="Test Author",
|
||||
document_id="test_html"
|
||||
)
|
||||
|
||||
self.assertTrue(success)
|
||||
self.assertTrue(self.manager.is_loaded())
|
||||
self.assertEqual(self.manager.title, "Test HTML")
|
||||
self.assertEqual(self.manager.author, "Test Author")
|
||||
self.assertEqual(self.manager.document_id, "test_html")
|
||||
self.assertGreater(len(self.manager.blocks), 0)
|
||||
|
||||
def test_load_empty_html(self):
|
||||
"""Test loading empty HTML"""
|
||||
success = self.manager.load_html("")
|
||||
|
||||
self.assertFalse(success)
|
||||
self.assertFalse(self.manager.is_loaded())
|
||||
|
||||
def test_get_metadata(self):
|
||||
"""Test getting document metadata"""
|
||||
if not Path(self.epub_path).exists():
|
||||
self.skipTest(f"Test EPUB not found at {self.epub_path}")
|
||||
|
||||
self.manager.load_epub(self.epub_path)
|
||||
metadata = self.manager.get_metadata()
|
||||
|
||||
self.assertIsInstance(metadata, dict)
|
||||
self.assertIn('title', metadata)
|
||||
self.assertIn('author', metadata)
|
||||
self.assertIn('document_id', metadata)
|
||||
self.assertIn('total_blocks', metadata)
|
||||
self.assertGreater(metadata['total_blocks'], 0)
|
||||
|
||||
def test_get_blocks(self):
|
||||
"""Test getting content blocks"""
|
||||
if not Path(self.epub_path).exists():
|
||||
self.skipTest(f"Test EPUB not found at {self.epub_path}")
|
||||
|
||||
self.manager.load_epub(self.epub_path)
|
||||
blocks = self.manager.get_blocks()
|
||||
|
||||
self.assertIsInstance(blocks, list)
|
||||
self.assertGreater(len(blocks), 0)
|
||||
|
||||
def test_clear(self):
|
||||
"""Test clearing loaded document"""
|
||||
if not Path(self.epub_path).exists():
|
||||
self.skipTest(f"Test EPUB not found at {self.epub_path}")
|
||||
|
||||
self.manager.load_epub(self.epub_path)
|
||||
self.assertTrue(self.manager.is_loaded())
|
||||
|
||||
self.manager.clear()
|
||||
|
||||
self.assertFalse(self.manager.is_loaded())
|
||||
self.assertIsNone(self.manager.document_id)
|
||||
self.assertIsNone(self.manager.title)
|
||||
self.assertIsNone(self.manager.author)
|
||||
self.assertIsNone(self.manager.blocks)
|
||||
|
||||
def test_multiple_loads(self):
|
||||
"""Test loading multiple documents sequentially"""
|
||||
html1 = "<html><body><h1>Document 1</h1></body></html>"
|
||||
html2 = "<html><body><h1>Document 2</h1></body></html>"
|
||||
|
||||
# Load first document
|
||||
self.manager.load_html(html1, title="Doc 1", document_id="doc1")
|
||||
self.assertEqual(self.manager.title, "Doc 1")
|
||||
self.assertEqual(self.manager.document_id, "doc1")
|
||||
|
||||
# Load second document (should replace first)
|
||||
self.manager.load_html(html2, title="Doc 2", document_id="doc2")
|
||||
self.assertEqual(self.manager.title, "Doc 2")
|
||||
self.assertEqual(self.manager.document_id, "doc2")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,220 @@
|
||||
"""
|
||||
Unit tests for SettingsManager.
|
||||
|
||||
Tests settings management in isolation using mocks.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from unittest.mock import Mock, MagicMock
|
||||
|
||||
from dreader.managers.settings import SettingsManager
|
||||
|
||||
|
||||
class TestSettingsManager(unittest.TestCase):
|
||||
"""Test SettingsManager in isolation"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test environment"""
|
||||
self.manager = SettingsManager()
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test manager initializes correctly"""
|
||||
manager = SettingsManager()
|
||||
|
||||
self.assertEqual(manager.font_scale, 1.0)
|
||||
self.assertEqual(manager.font_scale_step, 0.1)
|
||||
self.assertIsNone(manager.manager)
|
||||
|
||||
def test_get_font_size(self):
|
||||
"""Test getting current font size"""
|
||||
self.assertEqual(self.manager.get_font_size(), 1.0)
|
||||
|
||||
self.manager.font_scale = 1.5
|
||||
self.assertEqual(self.manager.get_font_size(), 1.5)
|
||||
|
||||
def test_set_font_size_without_manager(self):
|
||||
"""Test setting font size without layout manager returns None"""
|
||||
result = self.manager.set_font_size(1.5)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_font_size_with_manager(self):
|
||||
"""Test setting font size with layout manager"""
|
||||
# Create mock manager
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.set_font_scale.return_value = mock_page
|
||||
mock_layout_manager.font_scale = 1.0
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
# Set font size
|
||||
result = self.manager.set_font_size(1.5)
|
||||
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result, "rendered_page")
|
||||
self.assertEqual(self.manager.font_scale, 1.5)
|
||||
mock_layout_manager.set_font_scale.assert_called_once_with(1.5)
|
||||
|
||||
def test_font_size_clamping(self):
|
||||
"""Test font size is clamped between 0.5x and 3.0x"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.set_font_scale.return_value = mock_page
|
||||
mock_layout_manager.font_scale = 1.0
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
# Test upper bound
|
||||
self.manager.set_font_size(5.0)
|
||||
self.assertEqual(self.manager.font_scale, 3.0)
|
||||
|
||||
# Test lower bound
|
||||
self.manager.set_font_size(0.1)
|
||||
self.assertEqual(self.manager.font_scale, 0.5)
|
||||
|
||||
def test_increase_font_size(self):
|
||||
"""Test increasing font size by one step"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.set_font_scale.return_value = mock_page
|
||||
mock_layout_manager.font_scale = 1.0
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
initial_size = self.manager.font_scale
|
||||
self.manager.increase_font_size()
|
||||
|
||||
self.assertEqual(self.manager.font_scale, initial_size + 0.1)
|
||||
|
||||
def test_decrease_font_size(self):
|
||||
"""Test decreasing font size by one step"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.set_font_scale.return_value = mock_page
|
||||
mock_layout_manager.font_scale = 1.5
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
self.manager.font_scale = 1.5
|
||||
|
||||
self.manager.decrease_font_size()
|
||||
|
||||
self.assertAlmostEqual(self.manager.font_scale, 1.4, places=5)
|
||||
|
||||
def test_set_line_spacing(self):
|
||||
"""Test setting line spacing"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.get_current_page.return_value = mock_page
|
||||
mock_layout_manager.page_style = Mock()
|
||||
mock_layout_manager.page_style.line_spacing = 5
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
result = self.manager.set_line_spacing(10)
|
||||
|
||||
self.assertIsNotNone(result)
|
||||
mock_layout_manager.increase_line_spacing.assert_called_once_with(5)
|
||||
|
||||
def test_set_inter_block_spacing(self):
|
||||
"""Test setting inter-block spacing"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.get_current_page.return_value = mock_page
|
||||
mock_layout_manager.page_style = Mock()
|
||||
mock_layout_manager.page_style.inter_block_spacing = 15
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
result = self.manager.set_inter_block_spacing(25)
|
||||
|
||||
self.assertIsNotNone(result)
|
||||
mock_layout_manager.increase_inter_block_spacing.assert_called_once_with(10)
|
||||
|
||||
def test_set_word_spacing(self):
|
||||
"""Test setting word spacing"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.get_current_page.return_value = mock_page
|
||||
mock_layout_manager.page_style = Mock()
|
||||
mock_layout_manager.page_style.word_spacing = 0
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
result = self.manager.set_word_spacing(3)
|
||||
|
||||
self.assertIsNotNone(result)
|
||||
mock_layout_manager.increase_word_spacing.assert_called_once_with(3)
|
||||
|
||||
def test_get_current_settings_without_manager(self):
|
||||
"""Test getting settings without layout manager"""
|
||||
settings = self.manager.get_current_settings()
|
||||
|
||||
self.assertIsInstance(settings, dict)
|
||||
self.assertEqual(settings['font_scale'], 1.0)
|
||||
self.assertEqual(settings['line_spacing'], 5)
|
||||
self.assertEqual(settings['inter_block_spacing'], 15)
|
||||
self.assertEqual(settings['word_spacing'], 0)
|
||||
|
||||
def test_get_current_settings_with_manager(self):
|
||||
"""Test getting settings with layout manager"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_layout_manager.page_style = Mock()
|
||||
mock_layout_manager.page_style.line_spacing = 10
|
||||
mock_layout_manager.page_style.inter_block_spacing = 20
|
||||
mock_layout_manager.page_style.word_spacing = 3
|
||||
mock_layout_manager.font_scale = 1.5
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
self.manager.font_scale = 1.5
|
||||
|
||||
settings = self.manager.get_current_settings()
|
||||
|
||||
self.assertEqual(settings['font_scale'], 1.5)
|
||||
self.assertEqual(settings['line_spacing'], 10)
|
||||
self.assertEqual(settings['inter_block_spacing'], 20)
|
||||
self.assertEqual(settings['word_spacing'], 3)
|
||||
|
||||
def test_apply_settings(self):
|
||||
"""Test applying settings from dictionary"""
|
||||
mock_layout_manager = Mock()
|
||||
mock_page = Mock()
|
||||
mock_page.render.return_value = "rendered_page"
|
||||
mock_layout_manager.set_font_scale.return_value = mock_page
|
||||
mock_layout_manager.get_current_page.return_value = mock_page
|
||||
mock_layout_manager.page_style = Mock()
|
||||
mock_layout_manager.page_style.line_spacing = 5
|
||||
mock_layout_manager.page_style.inter_block_spacing = 15
|
||||
mock_layout_manager.page_style.word_spacing = 0
|
||||
mock_layout_manager.font_scale = 1.0
|
||||
|
||||
self.manager.set_manager(mock_layout_manager)
|
||||
|
||||
settings = {
|
||||
'font_scale': 1.5,
|
||||
'line_spacing': 10,
|
||||
'inter_block_spacing': 20,
|
||||
'word_spacing': 3
|
||||
}
|
||||
|
||||
success = self.manager.apply_settings(settings)
|
||||
|
||||
self.assertTrue(success)
|
||||
self.assertEqual(self.manager.font_scale, 1.5)
|
||||
|
||||
def test_apply_settings_without_manager(self):
|
||||
"""Test applying settings without layout manager returns False"""
|
||||
settings = {'font_scale': 1.5}
|
||||
success = self.manager.apply_settings(settings)
|
||||
|
||||
self.assertFalse(success)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user