tests: simplify run_ocrmypdf API

This commit is contained in:
James R. Barlow
2021-12-06 17:00:25 -08:00
parent 0528867e0b
commit 13af3252ff
8 changed files with 48 additions and 68 deletions
-1
View File
@@ -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
View File
@@ -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):
+5 -5
View File
@@ -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
View File
@@ -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',
+4 -4
View File
@@ -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")
+2 -2
View File
@@ -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
View File
@@ -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"
+3 -3
View File
@@ -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",