From eb5200d26aca2115ae5cc832d99954d00f83a48a Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Mon, 3 Jun 2019 01:45:27 -0700 Subject: [PATCH] Change most tests to use ocrmypdf API instead of subprocess The main benefit of this is code coverage gains can actually follow it. Also removes most ugly os.environ hacks. --- src/ocrmypdf/__main__.py | 2 - src/ocrmypdf/_pipeline.py | 3 + src/ocrmypdf/api.py | 28 +++++-- src/ocrmypdf/cli.py | 1 + src/ocrmypdf/exec/__init__.py | 3 +- src/ocrmypdf/exec/tesseract.py | 72 +++++++++++++----- .../pdf.bin | Bin 0 -> 3610 bytes .../stderr.bin | 1 + .../stdout.bin | 0 .../txt.bin | 13 ++++ .../pdf.bin | Bin 0 -> 3610 bytes .../stderr.bin | 1 + .../stdout.bin | 0 .../txt.bin | 13 ++++ tests/cache/manifest.jsonl | 2 + tests/conftest.py | 24 +++--- tests/test_filters.py | 1 - tests/test_main.py | 7 +- 18 files changed, 131 insertions(+), 40 deletions(-) create mode 100644 tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin create mode 100644 tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin create mode 100644 tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin create mode 100644 tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin create mode 100644 tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin create mode 100644 tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin create mode 100644 tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin create mode 100644 tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin diff --git a/src/ocrmypdf/__main__.py b/src/ocrmypdf/__main__.py index 0ec9050f..c24796af 100755 --- a/src/ocrmypdf/__main__.py +++ b/src/ocrmypdf/__main__.py @@ -35,8 +35,6 @@ def run(args=None): if not check_closed_streams(options): return ExitCode.bad_args - if os.environ.get('PYTEST_CURRENT_TEST'): - os.environ['_OCRMYPDF_TEST_INFILE'] = options.input_file if hasattr(os, 'nice'): os.nice(5) diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py index 592f2411..189e6fbc 100644 --- a/src/ocrmypdf/_pipeline.py +++ b/src/ocrmypdf/_pipeline.py @@ -348,6 +348,7 @@ def get_orientation_correction(preview, page_context): engine_mode=page_context.options.tesseract_oem, timeout=page_context.options.tesseract_timeout, log=page_context.log, + tesseract_env=page_context.options.tesseract_env, ) direction = {0: '⇧', 90: '⇨', 180: '⇩', 270: '⇦'} @@ -548,6 +549,7 @@ def ocr_tesseract_hocr(input_file, page_context): pagesegmode=options.tesseract_pagesegmode, user_words=options.user_words, user_patterns=options.user_patterns, + tesseract_env=options.tesseract_env, log=page_context.log, ) return (hocr_out, hocr_text_out) @@ -627,6 +629,7 @@ def ocr_tesseract_textonly_pdf(input_image, page_context): pagesegmode=options.tesseract_pagesegmode, user_words=options.user_words, user_patterns=options.user_patterns, + tesseract_env=options.tesseract_env, log=page_context.log, ) return (output_pdf, output_text) diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index ab648170..8e5c1e1b 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -16,6 +16,7 @@ # along with OCRmyPDF. If not, see . import logging +import os import sys from enum import IntEnum from pathlib import Path @@ -113,13 +114,16 @@ def configure_logging(verbosity, progress_bar_friendly=True, manage_root_logger= def create_options(*, input_file, output_file, **kwargs): cmdline = [] - filters = [] + deferred = [] for arg, val in kwargs.items(): if val is None: continue if arg.startswith('filter') and (callable(val) or isinstance(val, str)): - filters.append((arg, val)) + deferred.append((arg, val)) + continue + elif arg == 'tesseract_env': + deferred.append((arg, val)) continue cmd_style_arg = arg.replace('_', '-') cmdline.append(f"--{cmd_style_arg}") @@ -132,15 +136,20 @@ def create_options(*, input_file, output_file, **kwargs): elif isinstance(val, Path): cmdline.append(str(val)) else: - raise TypeError(f"{val} ({type(val)})") + raise TypeError(f"{arg}: {val} ({type(val)})") cmdline.append(str(input_file)) cmdline.append(str(output_file)) parser.api_mode = True options = parser.parse_args(cmdline) - for keyword, function in filters: - setattr(options, keyword, function) + for keyword, val in deferred: + setattr(options, keyword, val) + + # If we are running a Tesseract spoof, ensure it knows what the input file is + if os.environ.get('PYTEST_CURRENT_TEST') and options.tesseract_env: + options.tesseract_env['_OCRMYPDF_TEST_INFILE'] = input_file + return options @@ -190,9 +199,18 @@ def ocrmypdf( # pylint: disable=unused-argument keep_temporary_files=None, progress_bar=None, filter_ocr_image=None, + tesseract_env=None, ): """Run OCRmyPDF on one PDF or image. + For most arguments, see documentation for the equivalent command line parameter. + A few specific arguments are discussed here: + + Args: + use_threads (bool): Use worker threads instead of processes. This reduces + performance but may make debugging easier since it is easier to set + breakpoints. + tesseract_env (dict): Override environment variables for Tesseract Raises: ocrmypdf.PdfMergeFailedError: If the input PDF is malformed, preventing merging with the OCR layer. diff --git a/src/ocrmypdf/cli.py b/src/ocrmypdf/cli.py index 75833362..ac2f2713 100644 --- a/src/ocrmypdf/cli.py +++ b/src/ocrmypdf/cli.py @@ -482,3 +482,4 @@ debugging.add_argument( action='store_true', help="Keep temporary files (helpful for debugging)", ) +debugging.add_argument('--tesseract-env', type=str, help=argparse.SUPPRESS) diff --git a/src/ocrmypdf/exec/__init__.py b/src/ocrmypdf/exec/__init__.py index b09b516b..28193a01 100644 --- a/src/ocrmypdf/exec/__init__.py +++ b/src/ocrmypdf/exec/__init__.py @@ -28,7 +28,7 @@ from collections.abc import Mapping log = logging.Logger(__name__) -def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)'): +def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)', env=None): "Get the version of the specified program" args_prog = [program, version_arg] try: @@ -39,6 +39,7 @@ def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)'): stdout=PIPE, stderr=STDOUT, check=True, + env=env, ) output = proc.stdout except FileNotFoundError as e: diff --git a/src/ocrmypdf/exec/tesseract.py b/src/ocrmypdf/exec/tesseract.py index 110c49f3..467a9b7c 100644 --- a/src/ocrmypdf/exec/tesseract.py +++ b/src/ocrmypdf/exec/tesseract.py @@ -60,18 +60,16 @@ HOCR_TEMPLATE = """ """ -@lru_cache(maxsize=1) -def version(): - return get_version('tesseract', regex=r'tesseract\s(.+)') +def version(tesseract_env=None): + return get_version('tesseract', regex=r'tesseract\s(.+)', env=tesseract_env) -def v4(): +def v4(tesseract_env=None): "Is this Tesseract v4.0?" - return version() >= '4' + return version(tesseract_env) >= '4' -@lru_cache(maxsize=1) -def has_textonly_pdf(): +def has_textonly_pdf(tesseract_env=None): """Does Tesseract have textonly_pdf capability? Available in v4.00.00alpha since January 2017. Best to @@ -80,7 +78,15 @@ def has_textonly_pdf(): args_tess = ['tesseract', '--print-parameters', 'pdf'] params = '' try: - params = check_output(args_tess, universal_newlines=True, stderr=STDOUT) + proc = run( + args_tess, + check=True, + universal_newlines=True, + stdout=PIPE, + stderr=STDOUT, + env=tesseract_env, + ) + params = proc.stdout except CalledProcessError as e: print("Could not --print-parameters from tesseract", file=sys.stderr) raise MissingDependencyError from e @@ -89,8 +95,7 @@ def has_textonly_pdf(): return False -@lru_cache(maxsize=1) -def languages(): +def languages(tesseract_env=None): def lang_error(output): msg = dedent( """Tesseract failed to report available languages. @@ -104,7 +109,12 @@ def languages(): args_tess = ['tesseract', '--list-langs'] try: proc = run( - args_tess, universal_newlines=True, stdout=PIPE, stderr=STDOUT, check=True + args_tess, + universal_newlines=True, + stdout=PIPE, + stderr=STDOUT, + check=True, + env=tesseract_env, ) output = proc.stdout except CalledProcessError as e: @@ -127,7 +137,7 @@ def tess_base_args(langs, engine_mode): return args -def get_orientation(input_file, engine_mode, timeout: float, log): +def get_orientation(input_file, engine_mode, timeout: float, log, tesseract_env=None): args_tesseract = tess_base_args(['osd'], engine_mode) + [ '--psm', '0', @@ -136,7 +146,15 @@ def get_orientation(input_file, engine_mode, timeout: float, log): ] try: - stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout) + p = run( + args_tesseract, + stdout=PIPE, + stderr=STDOUT, + timeout=timeout, + check=True, + env=tesseract_env, + ) + stdout = p.stdout except TimeoutExpired: return OrientationConfidence(angle=0, confidence=0.0) except CalledProcessError as e: @@ -235,6 +253,7 @@ def generate_hocr( pagesegmode: int, user_words, user_patterns, + tesseract_env, log, ): @@ -258,7 +277,15 @@ def generate_hocr( args_tesseract.extend([input_file, prefix, 'hocr', 'txt'] + tessconfig) try: log.debug(args_tesseract) - stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout) + p = run( + args_tesseract, + stdout=PIPE, + stderr=STDOUT, + timeout=timeout, + check=True, + env=tesseract_env, + ) + stdout = p.stdout except TimeoutExpired: # Generate a HOCR file with no recognized text if tesseract times out # Temporary workaround to hocrTransform not being able to function if @@ -310,9 +337,10 @@ def generate_pdf( pagesegmode: int, user_words, user_patterns, + tesseract_env, log, ): - '''Use Tesseract to render a PDF. + """Use Tesseract to render a PDF. input_image -- image to analyze skip_pdf -- if we time out, use this file as output @@ -324,14 +352,14 @@ def generate_pdf( tessconfig -- tesseract configuration timeout -- timeout (seconds) log -- logger object - ''' + """ args_tesseract = tess_base_args(language, engine_mode) if pagesegmode is not None: args_tesseract.extend(['--psm', str(pagesegmode)]) - if text_only and has_textonly_pdf(): + if text_only and has_textonly_pdf(tesseract_env): args_tesseract.extend(['-c', 'textonly_pdf=1']) if user_words: @@ -348,7 +376,15 @@ def generate_pdf( args_tesseract.extend([input_image, prefix, 'pdf', 'txt'] + tessconfig) try: log.debug(args_tesseract) - stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout) + p = run( + args_tesseract, + stdout=PIPE, + stderr=STDOUT, + timeout=timeout, + check=True, + env=tesseract_env, + ) + stdout = p.stdout if os.path.exists(prefix + '.txt'): shutil.move(prefix + '.txt', output_text) except TimeoutExpired: diff --git a/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin new file mode 100644 index 0000000000000000000000000000000000000000..bd00d06d58aa38342d2146f3d8aabb668419456a GIT binary patch literal 3610 zcmbVP3s@6Z79L3O5%5#@Q_G_0ML}3CWF{d2Y>Gkx7++C>=&n^9l1Ug%CNVQ;5UEsK zAKfC@qOI0vaq(NXt&dti0Ux#fw74Q&QH!7}*6O;h)c5MH*s|wN62imJ{dO;8=ALuU zx%b?2&wuWjsOh@&SSn5>i@N&Ru{$yfk;sv|K&H{i5RzvVI2k0@(gJOBSTSQdZDn|* z0HI7-aHpUK{LfC#V5M;5f*dH#|DL7mx!MAM3c42)igLkID3Z1qHlx`MMkz}Vs zz;^pLJB8t_LLO33B&@{R1jYq#8!a$820ISxfuRg-m$|pJejU)4Ac(*n&z4t5tgQ@y z{!3bMp@bmX+d-)xNPUf3jvq`5eTlp{bO)aQpUzMJ<2voc0EjT}-n{XNqr~GHB=Om^BS!^)ik z#ekva22rdh$Sei1pyihkqX8@e4a#E@ zK3CpJn-~|(Ss9szgqDmn>Ci-^b{qF<+e~EXHop($0wtYt8d>Jc&aFL8eL&f$O0tgh_wQ5g2DOqL`2n$Y7K!vai;b6GT7^aOY!B!&p4f zWk3(N+6pX#N2WvqeHiG_Jcc$0yB{#n{}g`eJYa+bN&}&P1AdWtcEK%$4#=;8M<1KR zL=zz*y$_zf?6liSNQodA?*laAAlx3_8PW{&Ux1$MbnpV$2Nnhn!{fMzfBVW84an)Q z`KPouRwIb-Hb3X^`@%Q7AL6%^5cvZLYzc0l(+7Z$M{t8Do~d&S6ghz~KM^ z4pDJrcQ1LZgc-dJVAT~)NnOIvb5r2E8b|ze8spS^X#+i#F|#y=%p43D1*MJy%y?en zJ*)-LfC3LVf^iWvnchsu!+gGL5Z`ycY&i$Ix^%dr7&qily&YCg^}hAqw^l?X=wM93 zBuH+FC1Xj1YllqFl?d2?f7lxalDK#eL?tTK|NTDOkX^$Kqe5DL9{em|>?gy^rP2Uf zOVz|z=GUN^D}=cB6*(go%-R+6Q`4gP!xrD0GUJBRvMcA5BrIe3^XI?h9=q~7x8#KF zc)!;1Z>>F%OOWYxMJ&#}G`x8TM|KJ!sddmIVU-jPmc{-_9;vE-MS`H9YF<;6_QWoojQ_TT7R;UpRl#Jb8QCjEdr4?p;ZI7Iu8w`h@F? zS#|BoxjQZ_8t`^ZR2_X`&v(6Zo*XI|x+P*qN>y!W)+Y-?jhFtgBK-QF=lp4#wrrb$ zY1kaeqz50}`kwk!Rb6-knHpuq zTFZ%9mQ+Le7QuK;GxXXZ?Vym%prJ)cXa62n`e1uv+FW{B>DZ=!O?&5V+_kXm@SrVL z>P*w+I<@Zm0DDmM;z>ioBLmjtJ(&08K+IPstDL)w`yXlC_pN*5=8W}W3j=@H)pww| zLTk@gJU#cl=EvZQRa--UTVx2X$=$!9u+n(z;x>I#-Krz*;bYaTI;7pS_l=S{>!+WX|7m2Gz>RDCv5 z{l%V`dDSPfnIY2b_cyg%tCihNZo3pWz%}Zlj025@;lE?femOH*zT)$yhL)mxL#x@G zOPUWJZ#`r0b-Qv$ZNJ^RFn-zji03ya9DRNN_NVg}9W@uV>km~2RW$FeUwwSr>0acC{F=7lNh9B_>5*S>#qS5BKfmCFAfL>daVd{;khhfAI`Z*# z-WkqaKP(_|nDe1hK`~kIc>om))K&3uWE?4$MOr9K1;~Xus8>;pZk&Rol1MeFBq``A zV#$PPl8hE5vseKxYfX9@u5tXy!|j5y2nqp(3>QJ3hSVyRQiUw2gGWKhj2q&7JSBzG zPFEgDs^N0)##1PI%EhaosOct`5Z^&fD`d0bo@z!C=V%?B(zHqou*VI!lz(Vnju~GA8!>JlmGw# literal 0 HcmV?d00001 diff --git a/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin new file mode 100644 index 00000000..61f78d82 --- /dev/null +++ b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin @@ -0,0 +1 @@ +Tesseract Open Source OCR Engine v4.0.0 with Leptonica diff --git a/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin new file mode 100644 index 00000000..e69de29b diff --git a/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin new file mode 100644 index 00000000..25fdded2 --- /dev/null +++ b/tests/cache/cmyk/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin @@ -0,0 +1,13 @@ +Portez ce vieux whisky au juge +blond qui fume sur son Ile +interieure, a cöte de l'alcöve +ovoide, oU les büches se +consument dans l'ätre, ce qui +lui permet de penser & la +caenogenese de |'etre dont il +est question dans la cause +ambigu& entendue a MoY, dans +un capharnaüm qui, pense-t-il, +diminue ca et la la qualite de son +ceuvre. + \ No newline at end of file diff --git a/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin new file mode 100644 index 0000000000000000000000000000000000000000..7d8ac39f02fe6b90b1dcdac74080f96a3944ada3 GIT binary patch literal 3610 zcmbVP3s@6Z79L3O5%5#@Q_G_0ML}3CWF{d2Y>Gkx7++C>=&n^9l1Ug%CNVQ;5UEsK zAKfC@qOI0vaq(NXt&dti0Ux#fw74Q&QH!7}*6O;h)c5MH*s|wN62imJ{dO;8=ALuU zx%b?2&wuWjsOh@&SSn5>i@N&Ru{$yfk;sv|K&H{i5RzvVI2k0@(gJOBSTSQdZDn|* z0HI7-aHpUK{LfC#V5M;5f*dH#|DL7mx!MAM3c42)igLkID3Z1qHlx`MMkz}Vs zz;^pLJB8t_LLO33B&@{R1jYq#8!a$820ISxfuRg-m$|pJejU)4Ac(*n&z4t5tgQ@y z{!3bMp@bmX+d-)xNPUf3jvq`5eTlp{bO)aQpUzMJ<2voc0EjT}-n{XNqr~GHB=Om^BS!^)ik z#ekva22rdh$Sei1pyihkqX8@e4a#E@ zK3CpJn-~|(Ss9szgqDmn>Ci-^b{qF<+e~EXHop($0wtYt8d>Jc&aFL8eL&f$O0tgh_wQ5g2DOqL`2n$Y7K!vai;b6GT7^aOY!B!&p4f zWk3(N+6pX#N2WvqeHiG_Jcc$0yB{#n{}g`eJYa+bN&}&P1AdWtcEK%$4#=;8M<1KR zL=zz*y$_zf?6liSNQodA?*laAAlx3_8PW{&Ux1$MbnpV$2Nnhn!{fMzfBVW84an)Q z`KPouRwIb-Hb3X^`@%Q7AL6%^5cvZLYzc0l(+7Z$M{t8Do~d&S6ghz~KM^ z4pDJrcQ1LZgc-dJVAT~)NnOIvb5r2E8b|ze8spS^X#+i#F|#y=%p43D1*MJy%y?en zJ*)-LfC3LVf^iWvnchsu!+gGL5Z`ycY&i$Ix^%dr7&qily&YCg^}hAqw^l?X=wM93 zBuH+FC1Xj1YllqFl?d2?f7lxalDK#eL?tTK|NTDOkX^$Kqe5DL9{em|>?gy^rP2Uf zOVz|z=GUN^D}=cB6*(go%-R+6Q`4gP!xrD0GUJBRvMcA5BrIe3^XI?h9=q~7x8#KF zc)!;1Z>>F%OOWYxMJ&#}G`x8TM|KJ!sddmIVU-jPmc{-_9;vE-MS`H9YF<;6_QWoojQ_TT7R;UpRl#Jb8QCjEdr4?p;ZI7Iu8w`h@F? zS#|BoxjQZ_8t`^ZR2_X`&v(6Zo*XI|x+P*qN>y!W)+Y-?jhFtgBK-QF=lp4#wrrb$ zY1kaeqz50}`kwk!Rb6-knHpuq zTFZ%9mQ+Le7QuK;GxXXZ?Vym%prJ)cXa62n`e1uv+FW{B>DZ=!O?&5V+_kXm@SrVL z>P*w+I<@Zm0DDmM;z>ioBLmjtJ(&08K+IPstDL)w`yXlC_pN*5=8W}W3j=@H)pww| zLTk@gJU#cl=EvZQRa--UTVx2X$=$!9u+n(z;x>I#-Krz*;bYaTI;7pS_l=S{>!+WX|7m2Gz>RDCv5 z{l%V`dDSPfnIY2b_cyg%tCihNZo3pWz%}Zlj025@;lE?femOH*zT)$yhL)mxL#x@G zOPUWJZ#`r0b-Qv$ZNJ^RFn-zji03ya9DRNN_NVg}9W@uV>km~2RW$FeUwwSr>0acC{F=7lNh9B_>5*S>#qS5BKfmCFAfL>daVd{;khhfAI`Z*# z-WkqaKP(_|nDe1hK`~kIc>om))K&3uWE?4$MOr9K1;~Xus8>;pZk&Rol1MeFB&m3X zLK#aYM3ZE+D4E3ya9L~8({PRBPabX;ltoYoC}g+@@-(DYsgx>YK^;5_N@m;;=i@0U zoOZhMNKy@#dpDj!(Niv71w~CaxrF#0augL0Ij^f6rBs1`y77{ddg#KkJ$Ongq0>GD y7Y+4}%lrLiWS2773vfu84hNiwFQMa48bo literal 0 HcmV?d00001 diff --git a/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin new file mode 100644 index 00000000..61f78d82 --- /dev/null +++ b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin @@ -0,0 +1 @@ +Tesseract Open Source OCR Engine v4.0.0 with Leptonica diff --git a/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin new file mode 100644 index 00000000..e69de29b diff --git a/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin new file mode 100644 index 00000000..25fdded2 --- /dev/null +++ b/tests/cache/lichtenstein/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin @@ -0,0 +1,13 @@ +Portez ce vieux whisky au juge +blond qui fume sur son Ile +interieure, a cöte de l'alcöve +ovoide, oU les büches se +consument dans l'ätre, ce qui +lui permet de penser & la +caenogenese de |'etre dont il +est question dans la cause +ambigu& entendue a MoY, dans +un capharnaüm qui, pense-t-il, +diminue ca et la la qualite de son +ceuvre. + \ No newline at end of file diff --git a/tests/cache/manifest.jsonl b/tests/cache/manifest.jsonl index 325350eb..c9a1fc25 100644 --- a/tests/cache/manifest.jsonl +++ b/tests/cache/manifest.jsonl @@ -63,3 +63,5 @@ {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.5.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]} {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.5.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/poster.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.5.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/poster.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} +{"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.6.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/cmyk.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} +{"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.6.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} diff --git a/tests/conftest.py b/tests/conftest.py index 6ff87b4b..e386bdac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,6 +21,7 @@ import sys from contextlib import contextmanager from pathlib import Path from subprocess import PIPE, run +from ocrmypdf import api, cli import pytest @@ -185,18 +186,21 @@ def no_outpdf(tmp_path): 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) - # ensure py.test collects the output, use -s to view - print(err, file=sys.stderr) - assert p.returncode == 0 + # p, out, err = run_ocrmypdf(input_file, output_file, *args, env=env) + + options = cli.parser.parse_args( + [str(input_file), str(output_file)] + [str(arg) for arg in args] + ) + api.check_options(options) + if env: + options.tesseract_env = env + options.tesseract_env['_OCRMYPDF_TEST_INFILE'] = input_file + result = api.run_pipeline(options, api=True) + + assert result == 0 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" - + "\n" - + out - + "\n" - ) + return output_file diff --git a/tests/test_filters.py b/tests/test_filters.py index 12628e80..89c34a25 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -26,7 +26,6 @@ from ocrmypdf.filters import invert, whiteout from ocrmypdf._plugins import load_plugin -os_environ = pytest.helpers.os_environ check_ocrmypdf = pytest.helpers.check_ocrmypdf diff --git a/tests/test_main.py b/tests/test_main.py index 10b6eb5b..86f52b21 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -40,7 +40,6 @@ from ocrmypdf.pdfinfo import Colorspace, Encoding, PdfInfo check_ocrmypdf = pytest.helpers.check_ocrmypdf run_ocrmypdf = pytest.helpers.run_ocrmypdf spoof = pytest.helpers.spoof -os_environ = pytest.helpers.os_environ RENDERERS = ['hocr', 'sandwich'] @@ -614,8 +613,10 @@ def test_closed_streams(spoof_tesseract_noop, ocrmypdf_exec, resources, outpdf): def test_masks(spoof_tesseract_noop, resources, outpdf): - with os_environ(spoof_tesseract_noop): - assert ocrmypdf(resources / 'masks.pdf', outpdf) == ExitCode.ok + assert ( + ocrmypdf(resources / 'masks.pdf', outpdf, tesseract_env=spoof_tesseract_noop) + == ExitCode.ok + ) def test_linearized_pdf_and_indirect_object(spoof_tesseract_noop, resources, outpdf):