fixed word highlighting issue, added test for examples
This commit is contained in:
parent
4b4e9612a0
commit
5a573c901e
@ -18,8 +18,7 @@ This is useful for:
|
||||
from PIL import Image, ImageDraw
|
||||
import numpy as np
|
||||
|
||||
from dreader.application import EbookReader
|
||||
from pyWebLayout.io.gesture import TouchEvent, GestureType
|
||||
from dreader import EbookReader, TouchEvent, GestureType
|
||||
from pyWebLayout.core.query import QueryResult
|
||||
|
||||
|
||||
|
||||
228
tests/test_examples.py
Normal file
228
tests/test_examples.py
Normal file
@ -0,0 +1,228 @@
|
||||
"""
|
||||
Unit tests for example scripts.
|
||||
|
||||
This test suite validates that all example scripts:
|
||||
1. Can be imported without errors (syntax checks, import validation)
|
||||
2. Have valid import statements
|
||||
3. Can run their main functions without crashing (when applicable)
|
||||
|
||||
This helps catch issues like:
|
||||
- Incorrect import paths
|
||||
- Missing dependencies
|
||||
- API breakages that affect examples
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import importlib.util
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class TestExampleImports(unittest.TestCase):
|
||||
"""Test that all example scripts can be imported successfully"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures"""
|
||||
# Get the project root directory
|
||||
self.project_root = Path(__file__).parent.parent
|
||||
self.examples_dir = self.project_root / "examples"
|
||||
|
||||
# Add project root to Python path if not already there
|
||||
if str(self.project_root) not in sys.path:
|
||||
sys.path.insert(0, str(self.project_root))
|
||||
|
||||
def _import_module_from_file(self, file_path: Path):
|
||||
"""
|
||||
Import a Python module from a file path.
|
||||
|
||||
Args:
|
||||
file_path: Path to the Python file
|
||||
|
||||
Returns:
|
||||
The imported module
|
||||
|
||||
Raises:
|
||||
Any import errors that occur
|
||||
"""
|
||||
spec = importlib.util.spec_from_file_location(file_path.stem, file_path)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"Could not load spec for {file_path}")
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[file_path.stem] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
def test_word_selection_highlighting_imports(self):
|
||||
"""Test word_selection_highlighting.py can be imported"""
|
||||
example_file = self.examples_dir / "word_selection_highlighting.py"
|
||||
self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")
|
||||
|
||||
try:
|
||||
module = self._import_module_from_file(example_file)
|
||||
|
||||
# Verify key components are available
|
||||
self.assertTrue(hasattr(module, 'draw_highlight'))
|
||||
self.assertTrue(hasattr(module, 'example_1_single_word_selection'))
|
||||
self.assertTrue(hasattr(module, 'example_2_range_selection'))
|
||||
self.assertTrue(hasattr(module, 'example_3_interactive_word_lookup'))
|
||||
self.assertTrue(hasattr(module, 'example_4_multi_word_annotation'))
|
||||
self.assertTrue(hasattr(module, 'example_5_link_highlighting'))
|
||||
|
||||
except ImportError as e:
|
||||
self.fail(f"Failed to import word_selection_highlighting.py: {e}")
|
||||
|
||||
def test_demo_pagination_imports(self):
|
||||
"""Test demo_pagination.py can be imported"""
|
||||
example_file = self.examples_dir / "demo_pagination.py"
|
||||
self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")
|
||||
|
||||
try:
|
||||
module = self._import_module_from_file(example_file)
|
||||
self.assertTrue(hasattr(module, 'main'))
|
||||
except ImportError as e:
|
||||
self.fail(f"Failed to import demo_pagination.py: {e}")
|
||||
|
||||
def test_demo_toc_overlay_imports(self):
|
||||
"""Test demo_toc_overlay.py can be imported"""
|
||||
example_file = self.examples_dir / "demo_toc_overlay.py"
|
||||
self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")
|
||||
|
||||
try:
|
||||
module = self._import_module_from_file(example_file)
|
||||
self.assertTrue(hasattr(module, 'main'))
|
||||
except ImportError as e:
|
||||
self.fail(f"Failed to import demo_toc_overlay.py: {e}")
|
||||
|
||||
def test_demo_settings_overlay_imports(self):
|
||||
"""Test demo_settings_overlay.py can be imported"""
|
||||
example_file = self.examples_dir / "demo_settings_overlay.py"
|
||||
self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")
|
||||
|
||||
try:
|
||||
module = self._import_module_from_file(example_file)
|
||||
self.assertTrue(hasattr(module, 'main'))
|
||||
except ImportError as e:
|
||||
self.fail(f"Failed to import demo_settings_overlay.py: {e}")
|
||||
|
||||
def test_library_reading_integration_imports(self):
|
||||
"""Test library_reading_integration.py can be imported"""
|
||||
example_file = self.examples_dir / "library_reading_integration.py"
|
||||
self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")
|
||||
|
||||
try:
|
||||
module = self._import_module_from_file(example_file)
|
||||
self.assertTrue(hasattr(module, 'main'))
|
||||
self.assertTrue(hasattr(module, 'simulate_mode_transition_workflow'))
|
||||
except ImportError as e:
|
||||
self.fail(f"Failed to import library_reading_integration.py: {e}")
|
||||
|
||||
def test_all_examples_have_correct_dreader_imports(self):
|
||||
"""
|
||||
Verify all example scripts use correct import paths for dreader classes.
|
||||
|
||||
This test specifically checks that examples don't use outdated import paths
|
||||
like 'from dreader.application import' when they should use 'from dreader import'.
|
||||
"""
|
||||
# Get all Python files in examples directory
|
||||
example_files = list(self.examples_dir.glob("*.py"))
|
||||
|
||||
problematic_imports = []
|
||||
|
||||
for example_file in example_files:
|
||||
# Skip __init__.py and other special files
|
||||
if example_file.name.startswith('_'):
|
||||
continue
|
||||
|
||||
with open(example_file, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Check for problematic import patterns
|
||||
if 'from pyWebLayout.io.gesture import' in content:
|
||||
problematic_imports.append(
|
||||
f"{example_file.name}: Uses 'from pyWebLayout.io.gesture import' "
|
||||
f"(should be 'from dreader import')"
|
||||
)
|
||||
|
||||
if 'from dreader.application import EbookReader' in content:
|
||||
# This is acceptable, but check if TouchEvent/GestureType are also imported correctly
|
||||
if 'from pyWebLayout.io.gesture import TouchEvent' in content:
|
||||
problematic_imports.append(
|
||||
f"{example_file.name}: Mixes dreader.application and pyWebLayout.io.gesture imports"
|
||||
)
|
||||
|
||||
if problematic_imports:
|
||||
self.fail(
|
||||
"Found problematic imports in example files:\n" +
|
||||
"\n".join(f" - {issue}" for issue in problematic_imports)
|
||||
)
|
||||
|
||||
|
||||
class TestExampleFunctions(unittest.TestCase):
|
||||
"""Test key functionality in example scripts"""
|
||||
|
||||
def test_draw_highlight_function(self):
|
||||
"""Test the draw_highlight function from word_selection_highlighting"""
|
||||
from PIL import Image
|
||||
|
||||
# Import the module
|
||||
project_root = Path(__file__).parent.parent
|
||||
example_file = project_root / "examples" / "word_selection_highlighting.py"
|
||||
|
||||
spec = importlib.util.spec_from_file_location("word_selection_highlighting", example_file)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
# Create a test image
|
||||
test_image = Image.new('RGBA', (100, 100), (255, 255, 255, 255))
|
||||
|
||||
# Test the draw_highlight function
|
||||
bounds = (10, 10, 50, 20)
|
||||
result = module.draw_highlight(test_image, bounds)
|
||||
|
||||
# Verify the result is an image
|
||||
self.assertIsInstance(result, Image.Image)
|
||||
self.assertEqual(result.size, (100, 100))
|
||||
self.assertEqual(result.mode, 'RGBA')
|
||||
|
||||
|
||||
class TestExampleDocumentation(unittest.TestCase):
|
||||
"""Test that examples have proper documentation"""
|
||||
|
||||
def test_all_examples_have_docstrings(self):
|
||||
"""Verify all example scripts have module docstrings"""
|
||||
project_root = Path(__file__).parent.parent
|
||||
examples_dir = project_root / "examples"
|
||||
|
||||
example_files = [
|
||||
f for f in examples_dir.glob("*.py")
|
||||
if not f.name.startswith('_') and f.name not in ['__init__.py']
|
||||
]
|
||||
|
||||
missing_docstrings = []
|
||||
|
||||
for example_file in example_files:
|
||||
spec = importlib.util.spec_from_file_location(example_file.stem, example_file)
|
||||
if spec is None or spec.loader is None:
|
||||
continue
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
if not module.__doc__ or len(module.__doc__.strip()) < 10:
|
||||
missing_docstrings.append(example_file.name)
|
||||
except:
|
||||
# If module can't be loaded, skip docstring check
|
||||
# (import test will catch the error)
|
||||
pass
|
||||
|
||||
if missing_docstrings:
|
||||
self.fail(
|
||||
f"Examples missing proper docstrings: {', '.join(missing_docstrings)}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
x
Reference in New Issue
Block a user