Various test fixes, mainly Windows issues
This commit is contained in:
@@ -194,6 +194,7 @@ jobs:
|
||||
choco install --yes --no-progress tesseract
|
||||
choco install --yes --no-progress --ignore-checksums ghostscript --version 9.56.1
|
||||
choco install --yes --no-progress poppler --version=25.11.0
|
||||
choco install --yes --no-progress noto
|
||||
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import multiprocessing
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from pathlib import Path, PurePath
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -98,8 +98,8 @@ def test_json_serialization_multiprocessing():
|
||||
|
||||
for result_json in results:
|
||||
result = json.loads(result_json)
|
||||
assert result['input_file'] == '/test/input.pdf'
|
||||
assert result['output_file'] == '/test/output.pdf'
|
||||
assert PurePath(result['input_file']) == PurePath('/test/input.pdf')
|
||||
assert PurePath(result['output_file']) == PurePath('/test/output.pdf')
|
||||
assert result['languages'] == ['eng', 'deu']
|
||||
assert result['optimize'] == 2
|
||||
assert result['tesseract_timeout'] == 120.0
|
||||
|
||||
@@ -11,6 +11,7 @@ This tests the fpdf2 renderer with various language groups:
|
||||
- Devanagari (Hindi, Sanskrit)
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
@@ -23,6 +24,26 @@ from ocrmypdf.hocrtransform.hocr_parser import HocrParser
|
||||
RESOURCES = Path(__file__).parent / "resources"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pdftotext():
|
||||
"""Return a function to extract text from PDF using pdftotext.
|
||||
|
||||
Skips the test if pdftotext is not available.
|
||||
"""
|
||||
pdftotext_path = shutil.which('pdftotext')
|
||||
if pdftotext_path is None:
|
||||
pytest.skip("pdftotext not available")
|
||||
|
||||
def extract_text(pdf_path: Path) -> str:
|
||||
return subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(pdf_path), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
|
||||
return extract_text
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def font_dir():
|
||||
"""Return path to font directory."""
|
||||
@@ -48,7 +69,9 @@ class TestLatinScript:
|
||||
"""Return path to Latin HOCR test file."""
|
||||
return RESOURCES / "latin.hocr"
|
||||
|
||||
def test_render_latin_basic(self, latin_hocr, multi_font_manager, tmp_path):
|
||||
def test_render_latin_basic(
|
||||
self, latin_hocr, multi_font_manager, tmp_path, pdftotext
|
||||
):
|
||||
"""Test rendering Latin script with various diacritics."""
|
||||
parser = HocrParser(latin_hocr)
|
||||
page = parser.parse()
|
||||
@@ -76,11 +99,7 @@ class TestLatinScript:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
# Extract text and verify
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
|
||||
# English words
|
||||
assert 'quick' in text or 'brown' in text or 'fox' in text
|
||||
@@ -122,7 +141,9 @@ class TestArabicScript:
|
||||
"""Return path to Arabic HOCR test file."""
|
||||
return RESOURCES / "arabic.hocr"
|
||||
|
||||
def test_render_arabic_basic(self, arabic_hocr, multi_font_manager, tmp_path):
|
||||
def test_render_arabic_basic(
|
||||
self, arabic_hocr, multi_font_manager, tmp_path, pdftotext
|
||||
):
|
||||
"""Test rendering Arabic script text."""
|
||||
parser = HocrParser(arabic_hocr)
|
||||
page = parser.parse()
|
||||
@@ -145,11 +166,7 @@ class TestArabicScript:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
# Extract text and verify Arabic content
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
|
||||
# Arabic words: مرحبا بالعالم (Hello world)
|
||||
assert 'مرحبا' in text or 'بالعالم' in text
|
||||
@@ -204,7 +221,7 @@ class TestCJKScript:
|
||||
"""Return path to CJK HOCR test file."""
|
||||
return RESOURCES / "cjk.hocr"
|
||||
|
||||
def test_render_cjk_basic(self, cjk_hocr, multi_font_manager, tmp_path):
|
||||
def test_render_cjk_basic(self, cjk_hocr, multi_font_manager, tmp_path, pdftotext):
|
||||
"""Test rendering CJK script text."""
|
||||
if not _cjk_font_works(multi_font_manager):
|
||||
pytest.skip("CJK font not available or corrupted")
|
||||
@@ -237,11 +254,7 @@ class TestCJKScript:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
# Extract text and verify CJK content
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
|
||||
# Chinese: 你好 世界 (Hello world)
|
||||
assert '你好' in text or '世界' in text
|
||||
@@ -287,7 +300,7 @@ class TestDevanagariScript:
|
||||
return RESOURCES / "devanagari.hocr"
|
||||
|
||||
def test_render_devanagari_basic(
|
||||
self, devanagari_hocr, multi_font_manager, tmp_path
|
||||
self, devanagari_hocr, multi_font_manager, tmp_path, pdftotext
|
||||
):
|
||||
"""Test rendering Devanagari script text."""
|
||||
parser = HocrParser(devanagari_hocr)
|
||||
@@ -311,11 +324,7 @@ class TestDevanagariScript:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
# Extract text and verify Devanagari content
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
|
||||
# Hindi: नमस्ते दुनिया (Hello world)
|
||||
assert 'नमस्ते' in text or 'दुनिया' in text
|
||||
@@ -356,7 +365,7 @@ class TestMultilingual:
|
||||
return RESOURCES / "multilingual.hocr"
|
||||
|
||||
def test_render_multilingual_hocr_basic(
|
||||
self, multilingual_hocr, multi_font_manager, tmp_path
|
||||
self, multilingual_hocr, multi_font_manager, tmp_path, pdftotext
|
||||
):
|
||||
"""Test rendering multilingual HOCR file with English and Arabic text."""
|
||||
parser = HocrParser(multilingual_hocr)
|
||||
@@ -384,11 +393,7 @@ class TestMultilingual:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
# Extract text from PDF
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
|
||||
# Verify both English and Arabic text are present
|
||||
assert 'English' in text or 'Text' in text or 'Here' in text
|
||||
@@ -422,7 +427,7 @@ class TestMultilingual:
|
||||
assert output_pdf.stat().st_size > 0
|
||||
|
||||
def test_multilingual_invisible_text(
|
||||
self, multilingual_hocr, multi_font_manager, tmp_path
|
||||
self, multilingual_hocr, multi_font_manager, tmp_path, pdftotext
|
||||
):
|
||||
"""Test rendering with invisible text (default OCR mode)."""
|
||||
parser = HocrParser(multilingual_hocr)
|
||||
@@ -441,11 +446,7 @@ class TestMultilingual:
|
||||
assert output_pdf.exists()
|
||||
|
||||
# Text should still be extractable even though invisible
|
||||
text = subprocess.check_output(
|
||||
['pdftotext', '-enc', 'UTF-8', str(output_pdf), '-'],
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
)
|
||||
text = pdftotext(output_pdf)
|
||||
assert len(text.strip()) > 0
|
||||
|
||||
def test_multilingual_font_selection(self, multilingual_hocr, multi_font_manager):
|
||||
|
||||
@@ -68,7 +68,7 @@ def test_media_box(
|
||||
|
||||
with pikepdf.open(outdir / 'processed.pdf') as pdf:
|
||||
page = pdf.pages[0]
|
||||
assert page['/MediaBox'] == crop_expected
|
||||
assert page.mediabox == crop_expected
|
||||
|
||||
|
||||
cropbox_testdata = [
|
||||
@@ -122,4 +122,4 @@ def test_crop_box(
|
||||
|
||||
with pikepdf.open(outdir / 'processed.pdf') as pdf:
|
||||
page = pdf.pages[0]
|
||||
assert page.CropBox == crop_expected
|
||||
assert page.cropbox == crop_expected
|
||||
|
||||
@@ -13,7 +13,7 @@ import dataclasses
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from ocrmypdf import OcrElement
|
||||
from ocrmypdf import BoundingBox, OcrElement
|
||||
|
||||
|
||||
class TestOcrEngineDirect:
|
||||
@@ -25,7 +25,7 @@ class TestOcrEngineDirect:
|
||||
|
||||
assert hasattr(_pipeline, 'ocr_engine_direct')
|
||||
|
||||
def test_ocr_engine_direct_returns_tuple(self):
|
||||
def test_ocr_engine_direct_returns_tuple(self, tmp_path):
|
||||
"""ocr_engine_direct should return (OcrElement, Path) tuple."""
|
||||
from ocrmypdf._pipeline import ocr_engine_direct
|
||||
|
||||
@@ -34,11 +34,11 @@ class TestOcrEngineDirect:
|
||||
mock_engine = MagicMock()
|
||||
mock_engine.supports_generate_ocr.return_value = True
|
||||
mock_engine.generate_ocr.return_value = (
|
||||
OcrElement(ocr_class='ocr_page', bbox=(0, 0, 100, 100)),
|
||||
OcrElement(ocr_class='ocr_page', bbox=BoundingBox(0, 0, 100, 100)),
|
||||
"test text",
|
||||
)
|
||||
mock_context.plugin_manager.get_ocr_engine.return_value = mock_engine
|
||||
mock_context.get_path.return_value = Path("/tmp/test.txt")
|
||||
mock_context.get_path.return_value = tmp_path / Path("test.txt")
|
||||
mock_context.pageno = 0
|
||||
|
||||
with patch('builtins.open', MagicMock()):
|
||||
|
||||
Reference in New Issue
Block a user