2017-01-26 13:22:01 -08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# © 2017 James R. Barlow: github.com/jbarlow83
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import platform
|
|
|
|
|
|
|
|
pytest_plugins = ['helpers_namespace']
|
|
|
|
|
|
|
|
import pytest
|
2017-01-26 16:38:59 -08:00
|
|
|
from pathlib import Path
|
|
|
|
from subprocess import Popen, PIPE
|
2017-01-26 13:22:01 -08:00
|
|
|
|
|
|
|
|
|
|
|
if sys.version_info.major < 3:
|
|
|
|
print("Requires Python 3.4+")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.helpers.register
|
|
|
|
def is_linux():
|
|
|
|
return platform.system() == 'Linux'
|
|
|
|
|
|
|
|
|
2017-03-02 22:27:06 -08:00
|
|
|
@pytest.helpers.register
|
|
|
|
def is_macos():
|
|
|
|
return platform.system() == 'Darwin'
|
|
|
|
|
|
|
|
|
2017-01-26 13:22:01 -08:00
|
|
|
@pytest.helpers.register
|
|
|
|
def running_in_docker():
|
2017-02-13 02:16:06 -08:00
|
|
|
# Docker creates a file named /.dockerenv (newer versions) or
|
|
|
|
# /.dockerinit (older) -- this is undocumented, not an offical test
|
|
|
|
return os.path.exists('/.dockerenv') or os.path.exists('/.dockerinit')
|
2017-01-26 16:38:59 -08:00
|
|
|
|
|
|
|
|
2017-03-02 22:27:06 -08:00
|
|
|
@pytest.helpers.register
|
|
|
|
def running_in_travis():
|
|
|
|
return os.environ.get('TRAVIS') == 'true'
|
|
|
|
|
|
|
|
|
2017-01-26 16:38:59 -08:00
|
|
|
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
SPOOF_PATH = os.path.join(TESTS_ROOT, 'spoof')
|
|
|
|
PROJECT_ROOT = os.path.dirname(TESTS_ROOT)
|
|
|
|
OCRMYPDF = [sys.executable, '-m', 'ocrmypdf']
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.helpers.register
|
|
|
|
def spoof(**kwargs):
|
|
|
|
"""Modify environment variables to override subprocess executables
|
|
|
|
|
|
|
|
spoof(program1='replacement', ...)
|
|
|
|
|
|
|
|
Before running any executable, ocrmypdf checks the environment variable
|
|
|
|
OCRMYPDF_PROGRAMNAME to override default program name/location, e.g.
|
|
|
|
OCRMYPDF_GS redirects from the system path Ghostscript ("gs") to elsewhere.
|
|
|
|
|
|
|
|
"""
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
|
|
|
for replace_program, with_spoof in kwargs.items():
|
|
|
|
spoofer = os.path.join(SPOOF_PATH, with_spoof)
|
|
|
|
if not os.access(spoofer, os.X_OK):
|
|
|
|
os.chmod(spoofer, 0o755)
|
|
|
|
env['OCRMYPDF_' + replace_program.upper()] = spoofer
|
|
|
|
return env
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def resources():
|
|
|
|
return Path(TESTS_ROOT) / 'resources'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def ocrmypdf_exec():
|
|
|
|
return OCRMYPDF
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
def outdir(tmpdir):
|
2017-01-26 17:19:15 -08:00
|
|
|
return Path(str(tmpdir))
|
2017-01-26 16:38:59 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
def outpdf(tmpdir):
|
2017-01-26 17:19:15 -08:00
|
|
|
return str(Path(str(tmpdir)) / 'out.pdf')
|
2017-01-26 16:38:59 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
def no_outpdf(tmpdir):
|
|
|
|
"""This just documents the fact that a test is not expected to produce
|
|
|
|
output. Unfortunately an assertion failure inside a test fixture produces
|
|
|
|
an error rather than a test failure, so no testing is done. It's up to
|
|
|
|
the test to confirm that no output file was created."""
|
2017-01-26 17:19:15 -08:00
|
|
|
return str(Path(str(tmpdir)) / 'no_output.pdf')
|
2017-01-26 16:38:59 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.helpers.register
|
|
|
|
def check_ocrmypdf(input_file, output_file, *args, env=None):
|
|
|
|
"Run ocrmypdf and confirmed that a valid file was created"
|
|
|
|
|
|
|
|
p, out, err = run_ocrmypdf(input_file, output_file, *args, env=env)
|
|
|
|
#print(err) # ensure py.test collects the output, use -s to view
|
2017-03-24 13:23:03 -07:00
|
|
|
assert p.returncode == 0, "<stderr>\n" + err + "\n</stderr>"
|
2017-01-26 16:38:59 -08:00
|
|
|
assert os.path.exists(str(output_file)), "Output file not created"
|
|
|
|
assert os.stat(str(output_file)).st_size > 100, "PDF too small or empty"
|
|
|
|
assert out == "", \
|
|
|
|
"The following was written to stdout and should not have been: \n" + \
|
|
|
|
"<stdout>\n" + out + "\n</stdout>"
|
|
|
|
return output_file
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.helpers.register
|
|
|
|
def run_ocrmypdf(input_file, output_file, *args, env=None):
|
|
|
|
"Run ocrmypdf and let caller deal with results"
|
|
|
|
|
|
|
|
if env is None:
|
|
|
|
env = os.environ
|
|
|
|
|
|
|
|
p_args = OCRMYPDF + list(args) + [str(input_file), str(output_file)]
|
|
|
|
p = Popen(
|
|
|
|
p_args, close_fds=True, stdout=PIPE, stderr=PIPE,
|
|
|
|
universal_newlines=True, env=env)
|
|
|
|
out, err = p.communicate()
|
|
|
|
#print(err)
|
|
|
|
|
|
|
|
return p, out, err
|
2017-03-24 13:23:03 -07:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.helpers.register
|
|
|
|
def first_page_dimensions(pdf):
|
|
|
|
from ocrmypdf import pageinfo
|
2017-05-18 16:43:50 -07:00
|
|
|
info = pageinfo.PdfInfo(pdf)
|
2017-03-24 13:23:03 -07:00
|
|
|
page0 = info[0]
|
|
|
|
return (page0['width_inches'], page0['height_inches'])
|