163 lines
4.8 KiB
Python
163 lines
4.8 KiB
Python
"""Tests for pdf2imos CLI interface."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from typer.testing import CliRunner
|
|
|
|
from pdf2imos import __version__
|
|
from pdf2imos.cli import app
|
|
|
|
runner = CliRunner()
|
|
INPUT_DIR = Path(__file__).parent / "fixtures" / "input"
|
|
|
|
|
|
class TestVersion:
|
|
def test_prints_version_string(self):
|
|
result = runner.invoke(app, ["--version"])
|
|
assert result.exit_code == 0
|
|
assert __version__ in result.output
|
|
|
|
def test_version_before_args(self):
|
|
"""--version is eager, works without positional args."""
|
|
result = runner.invoke(app, ["--version"])
|
|
assert result.exit_code == 0
|
|
|
|
|
|
class TestHelp:
|
|
def test_help_exits_0(self):
|
|
result = runner.invoke(app, ["--help"])
|
|
assert result.exit_code == 0
|
|
|
|
def test_help_mentions_input_dir(self):
|
|
result = runner.invoke(app, ["--help"])
|
|
assert "INPUT_DIR" in result.output
|
|
|
|
|
|
class TestBatchProcessing:
|
|
def test_produces_dxf_and_json(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(INPUT_DIR), str(out)],
|
|
)
|
|
assert result.exit_code in (0, 1)
|
|
dxf_files = list(out.glob("*.dxf"))
|
|
json_files = list(out.glob("*.json"))
|
|
assert len(dxf_files) > 0
|
|
assert len(json_files) > 0
|
|
|
|
def test_output_names_match_pdfs(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(INPUT_DIR), str(out)],
|
|
)
|
|
if result.exit_code == 0:
|
|
for pdf in INPUT_DIR.glob("*.pdf"):
|
|
assert (out / f"{pdf.stem}.dxf").exists()
|
|
assert (out / f"{pdf.stem}.json").exists()
|
|
|
|
def test_verbose_accepted(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(INPUT_DIR), str(out), "--verbose"],
|
|
)
|
|
assert result.exit_code in (0, 1)
|
|
|
|
|
|
class TestStageProcessing:
|
|
def test_stage_extract_produces_json(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app,
|
|
[str(INPUT_DIR), str(out), "--stage=extract"],
|
|
)
|
|
assert result.exit_code == 0
|
|
intermediates = list(out.glob("*_extract.json"))
|
|
assert len(intermediates) > 0
|
|
|
|
def test_stage_extract_json_content(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
runner.invoke(
|
|
app,
|
|
[str(INPUT_DIR), str(out), "--stage=extract"],
|
|
)
|
|
for f in out.glob("*_extract.json"):
|
|
with open(f) as fh:
|
|
data = json.load(fh)
|
|
assert data["stage"] == "extract"
|
|
assert "data" in data
|
|
|
|
def test_stage_extract_no_dxf_output(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
runner.invoke(
|
|
app,
|
|
[str(INPUT_DIR), str(out), "--stage=extract"],
|
|
)
|
|
assert len(list(out.glob("*.dxf"))) == 0
|
|
|
|
def test_stage_segment(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app,
|
|
[str(INPUT_DIR), str(out), "--stage=segment"],
|
|
)
|
|
assert result.exit_code == 0
|
|
intermediates = list(out.glob("*_segment.json"))
|
|
assert len(intermediates) > 0
|
|
|
|
|
|
class TestExitCodes:
|
|
def test_exit_0_all_succeed(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(INPUT_DIR), str(out)],
|
|
)
|
|
assert result.exit_code == 0
|
|
|
|
def test_exit_2_no_pdfs(self, tmp_path):
|
|
empty = tmp_path / "empty"
|
|
empty.mkdir()
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(empty), str(out)],
|
|
)
|
|
assert result.exit_code == 2
|
|
|
|
def test_exit_2_nonexistent_input(self, tmp_path):
|
|
result = runner.invoke(
|
|
app,
|
|
["/nonexistent/path", str(tmp_path / "out")],
|
|
)
|
|
assert result.exit_code == 2
|
|
|
|
def test_exit_2_invalid_stage(self, tmp_path):
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app,
|
|
[str(INPUT_DIR), str(out), "--stage=bogus"],
|
|
)
|
|
assert result.exit_code == 2
|
|
|
|
|
|
class TestNonPdfSkipped:
|
|
def test_only_non_pdf_files_exit_2(self, tmp_path):
|
|
input_dir = tmp_path / "input"
|
|
input_dir.mkdir()
|
|
(input_dir / "readme.txt").write_text("hello")
|
|
(input_dir / "notes.md").write_text("# Notes")
|
|
out = tmp_path / "out"
|
|
result = runner.invoke(
|
|
app, [str(input_dir), str(out)],
|
|
)
|
|
assert result.exit_code == 2
|
|
|
|
def test_non_pdf_not_in_output(self, tmp_path):
|
|
"""Non-PDF files should not produce output."""
|
|
out = tmp_path / "out"
|
|
runner.invoke(
|
|
app, [str(INPUT_DIR), str(out)],
|
|
)
|
|
# No output file named after a non-pdf
|
|
for f in out.iterdir():
|
|
assert f.suffix in (".dxf", ".json", ".dwg")
|