This commit is contained in:
sebastien committed 2026-10-21 22:28:27 +02:00
1 parent 0d8970061e
commit c30aac0572
14 files changed
+343 -48

No files matched your search

+39 -9
View File
@@ -1,6 +1,6 @@
import unittest
from pathlib import Path
from unittest.mock import patch
from unittest.mock import Mock, patch
import numpy as np
from PIL import Image, ImageDraw, ImageFont
@@ -10,6 +10,34 @@ from copienator.commands import cutleft
class LeftMarginTests(unittest.TestCase):
def test_review_previous_restores_settings_and_respects_navigation_guards(self):
reviewer = cutleft.ImageReviewer.__new__(cutleft.ImageReviewer)
reviewer.files = [Path('Copie01.pdf'), Path('Copie02.pdf')]
reviewer.index = 0
reviewer.is_processing = False
reviewer.current_shift = -50
reviewer.current_width_offset = 100
reviewer.current_max_per_file = 1
reviewer.default_max_per_file = 5
reviewer.review_settings = {}
reviewer.trigger_processing = Mock()
reviewer.on_previous()
reviewer.trigger_processing.assert_not_called()
reviewer._advance()
self.assertEqual(reviewer.index, 1)
self.assertEqual((reviewer.current_shift, reviewer.current_width_offset, reviewer.current_max_per_file), (0, 0, 5))
reviewer.current_shift = 50
reviewer.is_processing = True
reviewer.on_previous()
self.assertEqual(reviewer.index, 1)
reviewer.is_processing = False
reviewer.on_previous()
self.assertEqual(reviewer.index, 0)
self.assertEqual((reviewer.current_shift, reviewer.current_width_offset, reviewer.current_max_per_file), (-50, 100, 1))
reviewer.trigger_processing.assert_called_with(Path('Copie01.pdf'), -50)
reviewer._advance()
self.assertEqual(reviewer.current_shift, 50)
def test_trim_discards_exactly_ten_percent_without_interpolation(self):
self.assertEqual(left_margin.trimmed_left_edge([100, 1, 9, 8, 7, 6, 5, 4, 3, 2]), 2)
self.assertEqual(left_margin.trimmed_left_edge([5] * 9), 5)
@@ -24,14 +52,14 @@ class LeftMarginTests(unittest.TestCase):
result = left_margin.analyse_margins(images, 200, 1654)
group = result['groups'][0]
self.assertEqual(group['edge_mm'], 42)
self.assertEqual(group['left_mm'], 21)
self.assertEqual(group['left_mm'], 22)
self.assertEqual(group['discarded_bands'], 14)
self.assertEqual(result['starts_px'], [round(21 * 200 / 25.4)] * 4)
self.assertEqual(result['starts_px'], [round(22 * 200 / 25.4)] * 4)
def test_repeated_left_writing_beyond_ten_percent_is_retained(self):
self.assertEqual(left_margin.trimmed_left_edge([10] * 20 + [42] * 80), 10)
def test_disagreeing_pages_use_half_the_trimmed_margin(self):
def test_disagreeing_pages_use_half_margin_when_it_removes_more(self):
result = self.analyse([25, 31, 68, 49])
self.assertEqual(result['groups'][0]['left_mm'], 12.5)
self.assertEqual(result['starts_px'][1:], [round(12.5 * 200 / 25.4)] * 3)
@@ -52,9 +80,9 @@ class LeftMarginTests(unittest.TestCase):
return {'edge_mm': edge, 'bands': bands, 'band_starts_mm': [edge] * bands}
with patch.object(left_margin, 'estimate_page', side_effect=estimate):
result = left_margin.analyse_margins(images, 200, 1654)
self.assertEqual(result['groups'][0]['left_mm'], 21)
self.assertEqual(result['groups'][0]['left_mm'], 22)
self.assertEqual(result['no_margin_from_page'], 3)
self.assertEqual(result['starts_px'], [round(21 * 200 / 25.4)] * 2 + [0] * 6)
self.assertEqual(result['starts_px'], [round(22 * 200 / 25.4)] * 2 + [0] * 6)
def test_isolated_low_or_blank_pages_do_not_trigger_no_margin_rule(self):
for edges in ([42, 10, 42, 12], [42, 10, None, 12]):
@@ -70,11 +98,13 @@ class LeftMarginTests(unittest.TestCase):
self.assertGreater(result['starts_px'][0], 0)
self.assertEqual(result['starts_px'][2:], [0] * 4)
def test_half_standard_margin_threshold(self):
for edge, expected in ((19.9, 0), (20, 10), (20.1, 10.05), (40, 20)):
def test_larger_cut_distance_and_no_margin_threshold(self):
for edge, expected in ((0, 0), (19.9, 0), (20, 10), (20.1, 10.05), (28.4, 14.2), (40, 20), (60, 40)):
with self.subTest(edge=edge):
result = self.analyse([edge] * 4)
self.assertEqual(result['starts_px'][1:], [round(expected * 200 / 25.4)] * 3)
self.assertEqual(result['groups'][0]['status'], 'near-edge' if edge < 20 else 'margin')
self.assertEqual(result['margin_clearance_mm'], 20)
def test_body_bands_ignore_header_footer_and_abstain_on_sparse_ink(self):
mask = np.zeros((1169, 827), bool)
@@ -119,7 +149,7 @@ class LeftMarginTests(unittest.TestCase):
def test_clear_margin_uses_same_conservative_edge_on_every_page(self):
result = self.analyse([43, 41, 46, 44])
self.assertEqual(result['groups'][0]['status'], 'margin')
self.assertEqual(result['starts_px'], [round(20.5 * 200 / 25.4)] * 4)
self.assertEqual(result['starts_px'], [round(21 * 200 / 25.4)] * 4)
self.assertNotIn('first_page_body_start_px', result)
def test_sparse_groups_stay_at_left(self):