172 lines
5.2 KiB
Python
172 lines
5.2 KiB
Python
"""Tests for JSON metadata writer."""
|
|
|
|
import json
|
|
|
|
import jsonschema
|
|
import pytest
|
|
from pathlib import Path
|
|
|
|
from pdf2imos.models import MaterialAnnotation, PartGeometry, PartMetadata
|
|
from pdf2imos.output.json_writer import build_metadata, write_metadata
|
|
from pdf2imos.schema.validator import validate_metadata
|
|
|
|
|
|
@pytest.fixture
|
|
def test_part():
|
|
return PartGeometry(
|
|
width_mm=600.0,
|
|
height_mm=720.0,
|
|
depth_mm=18.0,
|
|
origin=(0.0, 0.0, 0.0),
|
|
name="test_panel",
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def test_annotations():
|
|
return PartMetadata(
|
|
materials=(
|
|
MaterialAnnotation(
|
|
text="18mm white melamine MDF",
|
|
thickness_mm=18.0,
|
|
material_type="MDF",
|
|
finish="white",
|
|
),
|
|
),
|
|
edgebanding=(),
|
|
hardware=(),
|
|
drilling=(),
|
|
raw_annotations=("Scale: 1:1", "Part Name: test_panel"),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def test_title_info():
|
|
return {
|
|
"part_name": "test_panel",
|
|
"material": "18mm MDF",
|
|
"scale": "1:1",
|
|
"drawing_number": "",
|
|
}
|
|
|
|
|
|
class TestBuildMetadata:
|
|
def test_returns_dict(self, test_part, test_annotations, test_title_info):
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
assert isinstance(result, dict)
|
|
|
|
def test_required_fields_present(
|
|
self, test_part, test_annotations, test_title_info
|
|
):
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
assert "source_pdf" in result
|
|
assert "extraction_timestamp" in result
|
|
assert "part_name" in result
|
|
assert "overall_dimensions" in result
|
|
assert "parts" in result
|
|
assert "raw_annotations" in result
|
|
|
|
def test_dimensions_match_part(
|
|
self, test_part, test_annotations, test_title_info
|
|
):
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
dims = result["overall_dimensions"]
|
|
assert dims["width_mm"] == 600.0
|
|
assert dims["height_mm"] == 720.0
|
|
assert dims["depth_mm"] == 18.0
|
|
|
|
def test_source_pdf_is_filename(
|
|
self, test_part, test_annotations, test_title_info
|
|
):
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
assert result["source_pdf"] == "test.pdf"
|
|
|
|
def test_validates_against_schema(
|
|
self, test_part, test_annotations, test_title_info
|
|
):
|
|
"""Built metadata must pass schema validation."""
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
validate_metadata(result) # Should not raise
|
|
|
|
def test_raw_annotations_in_output(
|
|
self, test_part, test_annotations, test_title_info
|
|
):
|
|
result = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
assert "Scale: 1:1" in result["raw_annotations"] or len(
|
|
result["raw_annotations"]
|
|
) > 0
|
|
|
|
|
|
class TestWriteMetadata:
|
|
def test_returns_path(
|
|
self, test_part, test_annotations, test_title_info, tmp_path
|
|
):
|
|
metadata = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
output = tmp_path / "test.json"
|
|
result = write_metadata(metadata, output)
|
|
assert isinstance(result, Path)
|
|
|
|
def test_file_created(
|
|
self, test_part, test_annotations, test_title_info, tmp_path
|
|
):
|
|
metadata = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
output = tmp_path / "test.json"
|
|
write_metadata(metadata, output)
|
|
assert output.exists()
|
|
|
|
def test_file_is_valid_json(
|
|
self, test_part, test_annotations, test_title_info, tmp_path
|
|
):
|
|
metadata = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
output = tmp_path / "test.json"
|
|
write_metadata(metadata, output)
|
|
data = json.loads(output.read_text())
|
|
assert isinstance(data, dict)
|
|
|
|
def test_dimensions_in_output_file(
|
|
self, test_part, test_annotations, test_title_info, tmp_path
|
|
):
|
|
metadata = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
output = tmp_path / "test.json"
|
|
write_metadata(metadata, output)
|
|
data = json.loads(output.read_text())
|
|
assert data["overall_dimensions"]["width_mm"] == 600.0
|
|
|
|
def test_invalid_metadata_raises(self, tmp_path):
|
|
"""Invalid metadata should raise validation error."""
|
|
invalid = {"bad": "data"}
|
|
output = tmp_path / "bad.json"
|
|
with pytest.raises(jsonschema.ValidationError):
|
|
write_metadata(invalid, output)
|
|
|
|
def test_creates_parent_dirs(
|
|
self, test_part, test_annotations, test_title_info, tmp_path
|
|
):
|
|
"""Parent directories created if missing."""
|
|
metadata = build_metadata(
|
|
test_part, test_annotations, test_title_info, "test.pdf"
|
|
)
|
|
output = tmp_path / "nested" / "dir" / "test.json"
|
|
write_metadata(metadata, output)
|
|
assert output.exists()
|