feat: pdf2cad
This commit is contained in:
162
tests/test_cli.py
Normal file
162
tests/test_cli.py
Normal file
@@ -0,0 +1,162 @@
|
||||
"""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")
|
||||
Reference in New Issue
Block a user