improved library screen, fixed issues with image rendering and navigation
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
"""
|
||||
Test backward navigation after resuming from a saved position.
|
||||
|
||||
This test specifically checks if backward navigation works correctly
|
||||
after opening an epub, navigating forward, closing it, then resuming
|
||||
and attempting to navigate backward.
|
||||
|
||||
This may reveal issues with pyWebLayout's backward navigation handling.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
from dreader.application import EbookReader
|
||||
|
||||
|
||||
class TestBackwardNavigationAfterResume(unittest.TestCase):
|
||||
"""Test backward navigation behavior after resume"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test environment"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.epub_path = "tests/data/test.epub"
|
||||
|
||||
if not Path(self.epub_path).exists():
|
||||
self.skipTest(f"Test EPUB not found at {self.epub_path}")
|
||||
|
||||
def tearDown(self):
|
||||
"""Clean up test environment"""
|
||||
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
||||
|
||||
def compare_images(self, img1: Image.Image, img2: Image.Image) -> bool:
|
||||
"""
|
||||
Check if two PIL Images are pixel-perfect identical.
|
||||
"""
|
||||
if img1 is None or img2 is None:
|
||||
return False
|
||||
|
||||
if img1.size != img2.size:
|
||||
return False
|
||||
|
||||
arr1 = np.array(img1)
|
||||
arr2 = np.array(img2)
|
||||
|
||||
return np.array_equal(arr1, arr2)
|
||||
|
||||
def test_backward_navigation_after_resume(self):
|
||||
"""
|
||||
Test that backward navigation works after closing and resuming.
|
||||
|
||||
Steps:
|
||||
1. Open EPUB
|
||||
2. Navigate forward 3 pages
|
||||
3. Save positions and pages
|
||||
4. Close reader
|
||||
5. Open new reader (resume)
|
||||
6. Try to navigate backward
|
||||
7. Verify we can reach previous pages
|
||||
"""
|
||||
# Phase 1: Initial session - navigate forward
|
||||
reader1 = EbookReader(
|
||||
page_size=(800, 1000),
|
||||
bookmarks_dir=self.temp_dir,
|
||||
buffer_size=0 # Disable buffering for consistent testing
|
||||
)
|
||||
|
||||
success = reader1.load_epub(self.epub_path)
|
||||
self.assertTrue(success, "Failed to load test EPUB")
|
||||
|
||||
# Capture initial page
|
||||
page0 = reader1.get_current_page()
|
||||
self.assertIsNotNone(page0, "Initial page should not be None")
|
||||
pos0 = reader1.manager.current_position.copy()
|
||||
|
||||
print(f"\nInitial position: {pos0}")
|
||||
|
||||
# Navigate forward 3 pages, capturing each page
|
||||
pages = [page0]
|
||||
positions = [pos0]
|
||||
|
||||
for i in range(3):
|
||||
page = reader1.next_page()
|
||||
self.assertIsNotNone(page, f"Page {i+1} should not be None")
|
||||
pages.append(page)
|
||||
positions.append(reader1.manager.current_position.copy())
|
||||
print(f"Forward page {i+1} position: {positions[-1]}")
|
||||
|
||||
# We should now be at page 3 (0-indexed)
|
||||
self.assertEqual(len(pages), 4, "Should have 4 pages total (0-3)")
|
||||
|
||||
# Save the current position before closing
|
||||
final_position = reader1.manager.current_position.copy()
|
||||
print(f"Final position before close: {final_position}")
|
||||
|
||||
# Close reader (this should save the position)
|
||||
reader1.close()
|
||||
|
||||
# Phase 2: Resume session - navigate backward
|
||||
reader2 = EbookReader(
|
||||
page_size=(800, 1000),
|
||||
bookmarks_dir=self.temp_dir,
|
||||
buffer_size=0
|
||||
)
|
||||
|
||||
success = reader2.load_epub(self.epub_path)
|
||||
self.assertTrue(success, "Failed to load test EPUB on resume")
|
||||
|
||||
# Verify we resumed at the correct position
|
||||
resumed_position = reader2.manager.current_position.copy()
|
||||
print(f"Resumed at position: {resumed_position}")
|
||||
self.assertEqual(
|
||||
resumed_position,
|
||||
final_position,
|
||||
"Should resume at the last saved position"
|
||||
)
|
||||
|
||||
# Get the current page (should match page 3)
|
||||
resumed_page = reader2.get_current_page()
|
||||
self.assertIsNotNone(resumed_page, "Resumed page should not be None")
|
||||
|
||||
# Now try to navigate backward
|
||||
print("\nAttempting backward navigation...")
|
||||
|
||||
backward_pages = []
|
||||
backward_positions = []
|
||||
|
||||
# Try to go back 3 times
|
||||
for i in range(3):
|
||||
prev_page = reader2.previous_page()
|
||||
print(f"Backward step {i+1}: page={'Not None' if prev_page else 'None'}")
|
||||
|
||||
if prev_page is None:
|
||||
print(f"WARNING: previous_page() returned None at step {i+1}")
|
||||
# This is the bug we're testing for!
|
||||
self.fail(f"Backward navigation failed at step {i+1}: previous_page() returned None")
|
||||
|
||||
backward_pages.append(prev_page)
|
||||
backward_positions.append(reader2.manager.current_position.copy())
|
||||
print(f" Position after backward: {backward_positions[-1]}")
|
||||
|
||||
# We should have successfully gone back 3 pages
|
||||
self.assertEqual(len(backward_pages), 3, "Should have navigated back 3 pages")
|
||||
|
||||
# Verify final position matches original position
|
||||
final_backward_position = reader2.manager.current_position.copy()
|
||||
print(f"\nFinal position after backward navigation: {final_backward_position}")
|
||||
print(f"Original position (page 0): {pos0}")
|
||||
|
||||
self.assertEqual(
|
||||
final_backward_position,
|
||||
pos0,
|
||||
"After going forward 3 and back 3, should be at initial position"
|
||||
)
|
||||
|
||||
# Verify the page content matches
|
||||
final_page = reader2.get_current_page()
|
||||
self.assertTrue(
|
||||
self.compare_images(page0, final_page),
|
||||
"Final page should match initial page after forward/backward navigation"
|
||||
)
|
||||
|
||||
reader2.close()
|
||||
|
||||
print("\n✓ Test passed: Backward navigation works correctly after resume")
|
||||
|
||||
def test_backward_navigation_single_step(self):
|
||||
"""
|
||||
Simplified test: Open, go forward 1 page, close, resume, go back 1 page.
|
||||
This is a minimal reproduction case.
|
||||
"""
|
||||
# Session 1: Navigate forward one page
|
||||
reader1 = EbookReader(
|
||||
page_size=(800, 1000),
|
||||
bookmarks_dir=self.temp_dir,
|
||||
buffer_size=0
|
||||
)
|
||||
|
||||
reader1.load_epub(self.epub_path)
|
||||
|
||||
page0 = reader1.get_current_page()
|
||||
pos0 = reader1.manager.current_position.copy()
|
||||
|
||||
page1 = reader1.next_page()
|
||||
self.assertIsNotNone(page1, "Should be able to navigate forward")
|
||||
pos1 = reader1.manager.current_position.copy()
|
||||
|
||||
reader1.close()
|
||||
|
||||
# Session 2: Resume and navigate backward
|
||||
reader2 = EbookReader(
|
||||
page_size=(800, 1000),
|
||||
bookmarks_dir=self.temp_dir,
|
||||
buffer_size=0
|
||||
)
|
||||
|
||||
reader2.load_epub(self.epub_path)
|
||||
|
||||
# Verify we're at page 1
|
||||
self.assertEqual(
|
||||
reader2.manager.current_position,
|
||||
pos1,
|
||||
"Should resume at page 1"
|
||||
)
|
||||
|
||||
# Try to go back
|
||||
prev_page = reader2.previous_page()
|
||||
|
||||
# This is the critical assertion - if this fails, backward nav is broken
|
||||
self.assertIsNotNone(
|
||||
prev_page,
|
||||
"CRITICAL: previous_page() returned None after resume - this indicates a pyWebLayout bug"
|
||||
)
|
||||
|
||||
# Verify we're back at page 0
|
||||
final_pos = reader2.manager.current_position.copy()
|
||||
self.assertEqual(
|
||||
final_pos,
|
||||
pos0,
|
||||
"Should be back at initial position"
|
||||
)
|
||||
|
||||
reader2.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user