import tempfile import unittest from pathlib import Path from unittest.mock import Mock import pymupdf from copienator.commands.page_splitter import CM_TO_POINTS, PDFPreviewer class SecondarySplitterTests(unittest.TestCase): def preview(self): preview = PDFPreviewer.__new__(PDFPreviewer) preview.doc = pymupdf.open() self.addCleanup(lambda: None if preview.doc.is_closed else preview.doc.close()) for number in range(2): page = preview.doc.new_page(width=400, height=100) for column in range(4): page.insert_text((column * 100 + 30, 50), f'{number}{column}') preview.current_page_index = 0 preview.file_rotation = preview.global_rotation = 0 preview.page_settings = [] preview.load_page = Mock() preview._initialize_current_page_settings() return preview def export(self, preview): with tempfile.TemporaryDirectory() as directory: preview.base_name = 'copy' preview.split_dir = Path(directory) / 'split' preview.reorder_dir = Path(directory) / 'reorder' preview.final_file = Path(directory) / 'result.pdf' preview.output_dir = None preview.split_pdf() preview.reorder_pdfs() preview.concate_files() with pymupdf.open(preview.final_file) as output: return [(page.get_text().strip(), page.rect.width) for page in output] def settings(self, keep='both', cuts=None, rotation=0, line=200): return dict(keep=keep, secondary_splitters=cuts or [], rotation=rotation, line_x=line) def test_newest_line_moves_and_deletes_and_settings_are_page_local(self): preview = self.preview() preview.add_secondary_splitter() self.assertEqual(preview.secondary_splitters, [100]) preview.add_secondary_splitter() self.assertEqual(preview.secondary_splitters, [100, 300]) preview.move_line_left() self.assertAlmostEqual(preview.secondary_splitters[-1], 300 - CM_TO_POINTS / 2) self.assertEqual(preview.current_line_x, 200) preview.delete_secondary_splitter() preview.move_line_right() self.assertAlmostEqual(preview.secondary_splitters[-1], 100 + CM_TO_POINTS / 2) saved = preview.secondary_splitters.copy() preview.confirm_and_next_page() self.assertEqual(preview.page_settings[0]['secondary_splitters'], saved) self.assertEqual(preview.secondary_splitters, []) preview.delete_secondary_splitter() preview.move_line_left() self.assertAlmostEqual(preview.current_line_x, 200 - CM_TO_POINTS / 2) def test_subpages_replace_each_side_in_booklet_order(self): preview = self.preview() preview.page_settings = [self.settings(cuts=[300, 100]), self.settings(cuts=[100, 300])] self.assertEqual(self.export(preview), [(label, 100) for label in ['02', '03', '10', '11', '12', '13', '00', '01']]) def test_discarded_sides_and_duplicate_boundary_cuts(self): preview = self.preview() preview.page_settings = [self.settings('left', [0, 100, 100, 200, 300, 400]), self.settings('none', [100])] self.assertEqual(self.export(preview), [('00', 100), ('01', 100)]) def test_keep_as_is_ignores_main_splitter_but_applies_secondary_cuts(self): preview = self.preview() preview.page_settings = [self.settings('as_is', [100, 300]), self.settings('right', [300])] self.assertEqual(self.export(preview), [('00', 100), ('01\n02', 200), ('03', 100), ('12', 100), ('13', 100)]) def test_rotated_preview_orders_subpages_visually_left_to_right(self): preview = self.preview() preview.page_settings = [self.settings(cuts=[100, 300], rotation=180), self.settings('none')] self.assertEqual(self.export(preview), [(label, 100) for label in ['01', '00', '03', '02']]) def test_source_rotation_matches_preview(self): preview = self.preview() preview.doc[0].set_rotation(180) preview.page_settings = [self.settings(cuts=[100, 300]), self.settings('none')] self.assertEqual(self.export(preview), [(label, 100) for label in ['01', '00', '03', '02']]) def test_main_splitter_at_edge_does_not_break_reordering(self): preview = self.preview() preview.page_settings = [self.settings(cuts=[100, 200, 300], line=0), self.settings('none')] self.assertEqual(self.export(preview), [(label, 100) for label in ['00', '01', '02', '03']])