migrate to pytest & test_docs -> tests/test_docs

Use pytest instead of unittest to have greater flexibility in test
parametrization.
This commit is contained in:
deeplow 2022-08-25 18:40:23 +01:00
parent 4251d824ab
commit d3f478b17f
No known key found for this signature in database
GPG key ID: 577982871529A52A
19 changed files with 80 additions and 93 deletions

3
.gitignore vendored
View file

@ -132,9 +132,8 @@ dmypy.json
*.tar.gz *.tar.gz
deb_dist deb_dist
.DS_Store .DS_Store
tests/test_docs/**/*-safe.pdf
install/windows/Dangerzone.wxs install/windows/Dangerzone.wxs
**/*-safe.pdf
test_docs/out/
share/container.tar share/container.tar
share/container.tar.gz share/container.tar.gz
share/image-id.txt share/image-id.txt

View file

@ -0,0 +1,22 @@
import sys
from pathlib import Path
import pytest
sys.dangerzone_dev = True
SAMPLE_DIRECTORY = "test_docs"
BASIC_SAMPLE = "sample.pdf"
test_docs_dir = Path(__file__).parent.joinpath(SAMPLE_DIRECTORY)
test_docs = [
p
for p in test_docs_dir.rglob("*")
if p.is_file() and not p.name.endswith("-safe.pdf")
]
# Pytest parameter decorators
for_each_doc = pytest.mark.parametrize("doc", test_docs)
class TestBase:
sample_doc = str(test_docs_dir.joinpath(BASIC_SAMPLE))

View file

@ -1,14 +1,13 @@
from __future__ import annotations from __future__ import annotations
import os.path import tempfile
import sys
from pathlib import Path
from unittest import TestCase
import pytest
from click.testing import CliRunner, Result from click.testing import CliRunner, Result
from dangerzone.cli import cli_main from dangerzone.cli import cli_main
from . import TestBase, for_each_doc
# TODO --output-filename with spaces # TODO --output-filename with spaces
# TODO explore any symlink edge cases # TODO explore any symlink edge cases
@ -22,65 +21,50 @@ from dangerzone.cli import cli_main
# FIXME "/" path separator is platform-dependent, use pathlib instead # FIXME "/" path separator is platform-dependent, use pathlib instead
class CliTestCase(TestCase): class TestCli(TestBase):
SAMPLE_DIRECTORY = "test_docs" def run_cli(self, *args, **kwargs) -> Result:
BASIC_SAMPLE = f"{SAMPLE_DIRECTORY}/sample.pdf" return CliRunner().invoke(cli_main, *args, **kwargs)
SAFE_SUFFIX = "-safe.pdf"
def setUp(self):
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.dangerzone_dev = True
self.runner = CliRunner()
# TODO Use pathlib or similar for safer file handling here
samples_dir = Path(self.SAMPLE_DIRECTORY)
self.samples: list[Path | str] = [
p
for p in samples_dir.rglob("*")
if p.is_file() and not p.name.endswith(self.SAFE_SUFFIX)
]
print(f"{self.BASIC_SAMPLE} --output-filename {self.SAMPLE_DIRECTORY}/out/my-output.pdf")
if len(self.samples) < 10:
raise RuntimeWarning(f"Only {len(self.samples)} samples found.")
def invoke_runner(self, *args, **kwargs) -> Result:
return self.runner.invoke(cli_main, *args, **kwargs)
class CliBasicTestCase(CliTestCase): class TestCliBasic(TestCli):
def test_no_args(self): def test_no_args(self):
"""``$ dangerzone-cli``""" """``$ dangerzone-cli``"""
result = self.invoke_runner() result = self.run_cli()
self.assertNotEqual(result.exit_code, 0) assert result.exit_code != 0
def test_help(self): def test_help(self):
"""``$ dangerzone-cli --help``""" """``$ dangerzone-cli --help``"""
result = self.invoke_runner("--help") result = self.run_cli("--help")
self.assertEqual(result.exit_code, 0) assert result.exit_code == 0
class CliConversionTestCase(CliTestCase):
class TestCliConversion(TestCliBasic):
def test_invalid_lang(self): def test_invalid_lang(self):
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --ocr-lang piglatin") result = self.run_cli(f"{self.sample_doc} --ocr-lang piglatin")
self.assertNotEqual(result.exit_code, 0) assert result.exit_code != 0
def test_samples(self): @for_each_doc
for sample in self.samples: def test_formats(self, doc):
with self.subTest(f"Convert {sample}"): result = self.run_cli(f'"{doc}"')
result = self.invoke_runner(f'"{sample}"') assert result.exit_code == 0
self.assertEqual(result.exit_code, 0)
def test_output_filename(self): def test_output_filename(self):
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --output-filename {self.SAMPLE_DIRECTORY}/out/my-output.pdf") temp_dir = tempfile.mkdtemp(prefix="dangerzone-")
self.assertEqual(result.exit_code, 0) result = self.run_cli(
f"{self.sample_doc} --output-filename {temp_dir}/safe.pdf"
)
assert result.exit_code == 0
def test_output_filename_new_dir(self): def test_output_filename_new_dir(self):
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --output-filename fake-directory/my-output.pdf") result = self.run_cli(
self.assertEqual(result.exit_code, 0) f"{self.sample_doc} --output-filename fake-directory/my-output.pdf"
)
assert result.exit_code != 0
def test_sample_not_found(self): def test_sample_not_found(self):
result = self.invoke_runner("fake-directory/fake-file.pdf") result = self.run_cli("fake-directory/fake-file.pdf")
self.assertEquals(result.exit_code, 1) assert result.exit_code != 0
def test_lang_eng(self): def test_lang_eng(self):
# Rewrite this case if samples in other languages or scripts are added. result = self.run_cli(f'"{self.sample_doc}" --ocr-lang eng')
result = self.invoke_runner(f'"{self.BASIC_SAMPLE}" --ocr-lang eng') assert result.exit_code == 0
self.assertEqual(result.exit_code, 0)

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,58 +1,40 @@
import io
import os import os
import platform import platform
import subprocess
import sys
import unittest
from io import StringIO
from pathlib import Path from pathlib import Path
from unittest import TestCase, mock
import pytest
from strip_ansi import strip_ansi # type: ignore from strip_ansi import strip_ansi # type: ignore
import dangerzone.global_common as global_common import dangerzone.global_common
class TestGlobalCommon(TestCase):
VERSION_FILE_NAME = "version.txt" VERSION_FILE_NAME = "version.txt"
def setUp(self):
self.global_common = global_common.GlobalCommon()
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.dangerzone_dev = True
def test_get_resource_path(self): @pytest.fixture
def global_common():
return dangerzone.global_common.GlobalCommon()
class TestGlobalCommon:
def test_get_resource_path(self, global_common):
share_dir = Path("share").resolve() share_dir = Path("share").resolve()
resource_path = Path( resource_path = Path(global_common.get_resource_path(VERSION_FILE_NAME)).parent
self.global_common.get_resource_path(self.VERSION_FILE_NAME) assert share_dir.samefile(
).parent resource_path
self.assertTrue( ), f"{share_dir} is not the same file as {resource_path}"
share_dir.samefile(resource_path),
msg=f"{share_dir} is not the same file as {resource_path}",
)
@unittest.skipUnless(platform.system() == "Windows", "STARTUPINFO is for Windows") @pytest.mark.skipif(platform.system() != "Windows", reason="Windows-specific")
def test_get_subprocess_startupinfo(self): def test_get_subprocess_startupinfo(self, global_common):
startupinfo = self.global_common.get_subprocess_startupinfo() startupinfo = global_common.get_subprocess_startupinfo()
self.assertIsInstance(startupinfo, subprocess.STARTUPINFO) self.assertIsInstance(startupinfo, subprocess.STARTUPINFO)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_display_banner(self, global_common, capfd):
def test_display_banner(self, mock_stdout: StringIO): global_common.display_banner() # call the test subject
self.global_common.display_banner() # call the test subject (out, err) = capfd.readouterr()
banner = mock_stdout.getvalue() plain_lines = [strip_ansi(line) for line in out.splitlines()]
plain_lines = [strip_ansi(line) for line in banner.splitlines()] assert "╭──────────────────────────╮" in plain_lines, "missing top border"
with self.subTest("banner top border"): assert "╰──────────────────────────╯" in plain_lines, "missing bottom border"
self.assertEqual("╭──────────────────────────╮", plain_lines[0])
with self.subTest("banner bottom border"):
self.assertEqual("╰──────────────────────────╯", plain_lines[14])
with self.subTest("banner consistent dimensions"):
width = len(plain_lines[0])
for line in plain_lines:
self.assertEqual(len(line), width)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO) banner_width = len(plain_lines[0])
def test_display_banner_dims(self, mock_stdout: StringIO): for line in plain_lines:
self.global_common.display_banner() # call the test subject assert len(line) == banner_width, "banner has inconsistent width"
banner = mock_stdout.getvalue()
banner_lines = banner.splitlines()