tests: simplify run_ocrmypdf API
This commit is contained in:
@@ -55,7 +55,6 @@ install_requires =
|
||||
tqdm>=4
|
||||
importlib-metadata>=4;python_version<'3.8' # until Python 3.8
|
||||
importlib-resources>=5;python_version<'3.9' # until Python 3.9
|
||||
typing-extensions;python_version<'3.8' # until Python 3.8
|
||||
python_requires = >=3.7
|
||||
include_package_data = True
|
||||
package_dir =
|
||||
|
||||
+4
-21
@@ -10,7 +10,7 @@ import platform
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, CompletedProcess, run
|
||||
from typing import AnyStr, List, Tuple, overload
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -19,11 +19,6 @@ from ocrmypdf._exec import unpaper
|
||||
from ocrmypdf._plugin_manager import get_parser_options_plugins
|
||||
from ocrmypdf.exceptions import ExitCode
|
||||
|
||||
try:
|
||||
from typing import Literal
|
||||
except ImportError:
|
||||
from typing_extensions import Literal
|
||||
|
||||
|
||||
def is_linux():
|
||||
return platform.system() == 'Linux'
|
||||
@@ -122,21 +117,9 @@ def run_ocrmypdf_api(input_file: Path, output_file: Path, *args) -> ExitCode:
|
||||
return api.run_pipeline(options, plugin_manager=None, api=False)
|
||||
|
||||
|
||||
@overload
|
||||
def run_ocrmypdf(
|
||||
input_file: Path, output_file: Path, *args, text: Literal[True] = True
|
||||
) -> Tuple[CompletedProcess, str, str]:
|
||||
...
|
||||
|
||||
|
||||
@overload
|
||||
def run_ocrmypdf(
|
||||
input_file: Path, output_file: Path, *args, text: Literal[False]
|
||||
) -> Tuple[CompletedProcess, bytes, bytes]:
|
||||
...
|
||||
|
||||
|
||||
def run_ocrmypdf(input_file: Path, output_file: Path, *args, text: bool = True):
|
||||
input_file: Path, output_file: Path, *args, text: bool = True
|
||||
) -> CompletedProcess:
|
||||
"""Run ocrmypdf in a subprocess and let test deal with results.
|
||||
|
||||
If an exception is thrown this fact will be returned as part of the result
|
||||
@@ -157,7 +140,7 @@ def run_ocrmypdf(input_file: Path, output_file: Path, *args, text: bool = True):
|
||||
check=False,
|
||||
)
|
||||
# print(p.stderr)
|
||||
return p, p.stdout, p.stderr
|
||||
return p
|
||||
|
||||
|
||||
def first_page_dimensions(pdf: Path):
|
||||
|
||||
@@ -76,7 +76,7 @@ def test_rasterize_rotated(francais, outdir, caplog):
|
||||
|
||||
|
||||
def test_gs_render_failure(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'blank.pdf',
|
||||
outpdf,
|
||||
'--plugin',
|
||||
@@ -84,12 +84,12 @@ def test_gs_render_failure(resources, outpdf):
|
||||
'--plugin',
|
||||
'tests/plugins/gs_render_failure.py',
|
||||
)
|
||||
assert 'Casper is not a friendly ghost' in err
|
||||
assert 'Casper is not a friendly ghost' in p.stderr
|
||||
assert p.returncode == ExitCode.child_process_error
|
||||
|
||||
|
||||
def test_gs_raster_failure(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'francais.pdf',
|
||||
outpdf,
|
||||
'--plugin',
|
||||
@@ -97,12 +97,12 @@ def test_gs_raster_failure(resources, outpdf):
|
||||
'--plugin',
|
||||
'tests/plugins/gs_raster_failure.py',
|
||||
)
|
||||
assert 'Ghost story archive not found' in err
|
||||
assert 'Ghost story archive not found' in p.stderr
|
||||
assert p.returncode == ExitCode.child_process_error
|
||||
|
||||
|
||||
def test_ghostscript_pdfa_failure(resources, outpdf):
|
||||
p, _out, _err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'francais.pdf',
|
||||
outpdf,
|
||||
'--plugin',
|
||||
|
||||
+25
-27
@@ -203,7 +203,7 @@ def test_force_ocr_on_pdf_with_no_images(resources, no_outpdf):
|
||||
# As a correctness test, make sure that --force-ocr on a PDF with no
|
||||
# content still triggers tesseract. If tesseract crashes, then it was
|
||||
# called.
|
||||
p, _, _ = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'blank.pdf',
|
||||
no_outpdf,
|
||||
'--force-ocr',
|
||||
@@ -241,7 +241,7 @@ def test_german(resources, outdir):
|
||||
|
||||
|
||||
def test_klingon(resources, outpdf):
|
||||
p, _, _ = run_ocrmypdf(resources / 'francais.pdf', outpdf, '-l', 'klz')
|
||||
p = run_ocrmypdf(resources / 'francais.pdf', outpdf, '-l', 'klz')
|
||||
assert p.returncode == ExitCode.missing_dependency
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ def test_tesseract_thresholding_invalid(value, resources, no_outpdf):
|
||||
|
||||
@pytest.mark.parametrize('renderer', RENDERERS)
|
||||
def test_tesseract_crash(renderer, resources, no_outpdf):
|
||||
p, _, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'ccitt.pdf',
|
||||
no_outpdf,
|
||||
'-v',
|
||||
@@ -366,11 +366,11 @@ def test_tesseract_crash(renderer, resources, no_outpdf):
|
||||
)
|
||||
assert p.returncode == ExitCode.child_process_error
|
||||
assert not no_outpdf.exists()
|
||||
assert "SubprocessOutputError" in err
|
||||
assert "SubprocessOutputError" in p.stderr
|
||||
|
||||
|
||||
def test_tesseract_crash_autorotate(resources, no_outpdf):
|
||||
p, out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'ccitt.pdf',
|
||||
no_outpdf,
|
||||
'-r',
|
||||
@@ -379,9 +379,9 @@ def test_tesseract_crash_autorotate(resources, no_outpdf):
|
||||
)
|
||||
assert p.returncode == ExitCode.child_process_error
|
||||
assert not no_outpdf.exists()
|
||||
assert "uncaught exception" in err
|
||||
print(out)
|
||||
print(err)
|
||||
assert "uncaught exception" in p.stderr
|
||||
print(p.stdout)
|
||||
print(p.stderr)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('renderer', RENDERERS)
|
||||
@@ -401,7 +401,7 @@ def test_tesseract_image_too_big(renderer, resources, outpdf):
|
||||
|
||||
|
||||
def test_algo4(resources, outpdf):
|
||||
p, _, _ = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'encrypted_algo4.pdf',
|
||||
outpdf,
|
||||
'--plugin',
|
||||
@@ -471,7 +471,7 @@ def test_destination_not_writable(resources, outdir):
|
||||
protected_file = outdir / 'protected.pdf'
|
||||
protected_file.touch()
|
||||
protected_file.chmod(0o400) # Read-only
|
||||
p, _out, _err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'jbig2.pdf',
|
||||
protected_file,
|
||||
'--plugin',
|
||||
@@ -512,7 +512,7 @@ THIS FILE IS INVALID
|
||||
'''
|
||||
)
|
||||
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'ccitt.pdf',
|
||||
outdir / 'out.pdf',
|
||||
'--pdf-renderer',
|
||||
@@ -521,8 +521,8 @@ THIS FILE IS INVALID
|
||||
cfg_file,
|
||||
)
|
||||
assert (
|
||||
"parameter not found" in err.lower()
|
||||
or "error occurred while parsing" in err.lower()
|
||||
"parameter not found" in p.stderr.lower()
|
||||
or "error occurred while parsing" in p.stderr.lower()
|
||||
), "No error message"
|
||||
assert p.returncode == ExitCode.invalid_config
|
||||
|
||||
@@ -781,15 +781,13 @@ def test_pdfa_n(pdfa_level, resources, outpdf):
|
||||
|
||||
|
||||
def test_decompression_bomb_error(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf)
|
||||
assert 'decompression bomb' in err and '--max-image-mpixels' in err
|
||||
p = run_ocrmypdf(resources / 'hugemono.pdf', outpdf)
|
||||
assert 'decompression bomb' in p.stderr and '--max-image-mpixels' in p.stderr
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_decompression_bomb_succeeds(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000'
|
||||
)
|
||||
p = run_ocrmypdf(resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000')
|
||||
assert p.returncode == 0
|
||||
|
||||
|
||||
@@ -818,7 +816,7 @@ def test_text_curves(resources, outpdf):
|
||||
|
||||
|
||||
def test_output_is_dir(resources, outdir):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'trivial.pdf',
|
||||
outdir,
|
||||
'--force-ocr',
|
||||
@@ -826,28 +824,28 @@ def test_output_is_dir(resources, outdir):
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert p.returncode == ExitCode.file_access_error
|
||||
assert 'is not a writable file' in err
|
||||
assert 'is not a writable file' in p.stderr
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name == 'nt', reason="symlink needs admin permissions")
|
||||
def test_output_is_symlink(resources, outdir):
|
||||
sym = Path(outdir / 'this_is_a_symlink')
|
||||
sym.symlink_to(outdir / 'out.pdf')
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'trivial.pdf',
|
||||
sym,
|
||||
'--force-ocr',
|
||||
'--plugin',
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert p.returncode == ExitCode.ok, err
|
||||
assert p.returncode == ExitCode.ok, p.stderr
|
||||
assert (outdir / 'out.pdf').stat().st_size > 0, 'target file not created'
|
||||
|
||||
|
||||
def test_livecycle(resources, no_outpdf):
|
||||
p, _, err = run_ocrmypdf(resources / 'livecycle.pdf', no_outpdf)
|
||||
p = run_ocrmypdf(resources / 'livecycle.pdf', no_outpdf)
|
||||
|
||||
assert p.returncode == ExitCode.input_file, err
|
||||
assert p.returncode == ExitCode.input_file, p.stderr
|
||||
|
||||
|
||||
def test_version_check():
|
||||
@@ -904,7 +902,7 @@ def test_image_dpi_not_image(caplog, resources, outpdf):
|
||||
|
||||
|
||||
def test_outputtype_none_bad_setup(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'trivial.pdf',
|
||||
outpdf,
|
||||
'--output-type=none',
|
||||
@@ -912,11 +910,11 @@ def test_outputtype_none_bad_setup(resources, outpdf):
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert p.returncode == ExitCode.bad_args
|
||||
assert 'Set the output file to' in err
|
||||
assert 'Set the output file to' in p.stderr
|
||||
|
||||
|
||||
def test_outputtype_none(resources, outtxt):
|
||||
p, out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'trivial.pdf',
|
||||
'-',
|
||||
'--output-type=none',
|
||||
|
||||
@@ -62,7 +62,7 @@ def test_override_metadata(output_type, resources, outpdf):
|
||||
german = 'Du siehst den Wald vor lauter Bäumen nicht.'
|
||||
chinese = '孔子'
|
||||
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
input_file,
|
||||
outpdf,
|
||||
'--title',
|
||||
@@ -75,7 +75,7 @@ def test_override_metadata(output_type, resources, outpdf):
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
|
||||
assert p.returncode == ExitCode.ok, err
|
||||
assert p.returncode == ExitCode.ok, p.stderr
|
||||
|
||||
before = pikepdf.open(input_file)
|
||||
after = pikepdf.open(outpdf)
|
||||
@@ -99,7 +99,7 @@ def test_high_unicode(resources, no_outpdf):
|
||||
input_file = resources / 'c02-22.pdf'
|
||||
high_unicode = 'U+1030C is: 𐌌'
|
||||
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
input_file,
|
||||
no_outpdf,
|
||||
'--subject',
|
||||
@@ -110,7 +110,7 @@ def test_high_unicode(resources, no_outpdf):
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
|
||||
assert p.returncode == ExitCode.bad_args, err
|
||||
assert p.returncode == ExitCode.bad_args, p.stderr
|
||||
|
||||
|
||||
@pytest.mark.skipif(not fitz, reason="test uses fitz")
|
||||
|
||||
@@ -242,7 +242,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir):
|
||||
test = make_rotate_test('test', image_angle, page_angle)
|
||||
out = test.with_suffix('.out.pdf')
|
||||
|
||||
p, _, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
test,
|
||||
out,
|
||||
'-O0',
|
||||
@@ -251,7 +251,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir):
|
||||
'0.001',
|
||||
text=False,
|
||||
)
|
||||
err = err.decode('utf-8', errors='replace')
|
||||
err = p.stderr.decode('utf-8', errors='replace')
|
||||
assert p.returncode == 0, err
|
||||
|
||||
assert compare_images_monochrome(outdir, reference, 1, out, 1) > 0.2
|
||||
|
||||
+5
-5
@@ -60,10 +60,10 @@ def test_stdout(ocrmypdf_exec, resources, outpdf):
|
||||
@pytest.mark.skipif(os.name == 'nt', reason="invalid test on Windows")
|
||||
def test_bad_locale(monkeypatch):
|
||||
monkeypatch.setenv('LC_ALL', 'C')
|
||||
p, out, err = run_ocrmypdf('a', 'b')
|
||||
assert out == '', "stdout not clean"
|
||||
p = run_ocrmypdf('a', 'b')
|
||||
assert p.stdout == '', "stdout not clean"
|
||||
assert p.returncode != 0
|
||||
assert 'configured to use ASCII as encoding' in err, "should whine"
|
||||
assert 'configured to use ASCII as encoding' in p.stderr, "should whine"
|
||||
|
||||
|
||||
@pytest.mark.xfail(
|
||||
@@ -74,7 +74,7 @@ def test_dev_null(resources):
|
||||
if 'COV_CORE_DATAFILE' in os.environ:
|
||||
pytest.skip(msg="Coverage uses stdout")
|
||||
|
||||
p, out, _err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / 'trivial.pdf',
|
||||
os.devnull,
|
||||
'--force-ocr',
|
||||
@@ -82,4 +82,4 @@ def test_dev_null(resources):
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert p.returncode == 0, "could not send output to /dev/null"
|
||||
assert len(out) == 0, "wrote to stdout"
|
||||
assert len(p.stdout) == 0, "wrote to stdout"
|
||||
|
||||
@@ -71,7 +71,7 @@ def test_unpaper_args_valid(resources, outpdf):
|
||||
|
||||
@pytest.mark.skipif(not have_unpaper(), reason="requires unpaper")
|
||||
def test_unpaper_args_invalid_filename(resources, outpdf):
|
||||
p, _out, err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / "skew.pdf",
|
||||
outpdf,
|
||||
"-c",
|
||||
@@ -80,13 +80,13 @@ def test_unpaper_args_invalid_filename(resources, outpdf):
|
||||
'--plugin',
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert "No filenames allowed" in err
|
||||
assert "No filenames allowed" in p.stderr
|
||||
assert p.returncode == ExitCode.bad_args
|
||||
|
||||
|
||||
@pytest.mark.skipif(not have_unpaper(), reason="requires unpaper")
|
||||
def test_unpaper_args_invalid(resources, outpdf):
|
||||
p, _out, _err = run_ocrmypdf(
|
||||
p = run_ocrmypdf(
|
||||
resources / "skew.pdf",
|
||||
outpdf,
|
||||
"-c",
|
||||
|
||||
Reference in New Issue
Block a user