from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from packing_benchmark.renderer import svg_markup # noqa: E402 from packing_benchmark.store import SolutionStore # noqa: E402 from packing_benchmark.verifier import load_solution_json, verify_record_solution, verify_solution # noqa: E402 def test_seed_records_verify() -> None: for path in sorted((ROOT / "data" / "solutions").glob("*.json")): result = verify_solution(json.loads(path.read_text())) assert result.ok, (path.name, result.errors) def test_rejects_overlapping_pair() -> None: solution = { "case": "squinsqu@2", "item": {"type": "regular_polygon", "sides": 4, "side_length": 1}, "container": {"type": "regular_polygon", "sides": 4, "side_length": 3}, "placements": [ {"x": 0, "y": 0, "rotation_radians": 0}, {"x": 0, "y": 0, "rotation_radians": 0}, ], } result = verify_solution(solution) assert not result.ok assert result.max_pair_overlap_depth > 0 def test_rejects_boundary_protrusion() -> None: solution = { "case": "squinsqu@1", "item": {"type": "regular_polygon", "sides": 4, "side_length": 1}, "container": {"type": "regular_polygon", "sides": 4, "side_length": 1}, "placements": [ {"x": 0.6, "y": 0.0, "rotation_radians": 0}, ], } result = verify_solution(solution) assert not result.ok assert result.max_boundary_excess > 0 def test_rejects_wrong_case_family() -> None: solution = { "case": "triintri@1", "item": {"type": "circle", "radius": 0.5}, "container": {"type": "regular_polygon", "sides": 4, "side_length": 2}, "placements": [ {"x": 0.0, "y": 0.0, "rotation_radians": 0}, ], } result = verify_solution(solution) assert not result.ok assert any("does not match item/container geometry" in error for error in result.errors) def test_rejects_wrong_setup_field() -> None: solution = { "case": "cirinsqu@1", "setup": "triintri", "item": {"type": "circle", "radius": 0.5}, "container": {"type": "rectangle", "width": 2.0, "height": 2.0}, "placements": [ {"x": 0.0, "y": 0.0, "rotation_radians": 0}, ], } result = verify_solution(solution) assert not result.ok assert any("setup" in error and "does not match" in error for error in result.errors) def test_circle_container_metric_is_radius() -> None: solution = { "case": "triincir@1", "item": {"type": "regular_polygon", "sides": 3, "side_length": 1}, "container": {"type": "circle", "radius": 1.0}, "placements": [ {"x": 0.0, "y": 0.0, "rotation_radians": 0}, ], } result = verify_solution(solution) assert result.ok assert result.side == 2.0 assert result.metric_symbol == "r" assert result.metric_value == 1.0 def test_rejects_non_finite_json_numbers() -> None: try: load_solution_json('{"case": "cirincir@1", "item": {"type": "circle", "radius": NaN}}') except ValueError as exc: assert "invalid JSON numeric constant" in str(exc) else: raise AssertionError("NaN JSON was accepted") def test_record_solution_mismatch_is_detected() -> None: solution = { "case": "cirinsqu@1", "item": {"type": "circle", "radius": 0.5}, "container": {"type": "rectangle", "width": 2.0, "height": 2.0}, "placements": [ {"x": 0.0, "y": 0.0, "rotation_radians": 0}, ], } errors = verify_record_solution( { "case": "cirinsqu@1", "setup": "cirinsqu", "n": 1, "side": 3.0, "metric_symbol": "s", "metric_value": 3.0, }, solution, ) assert any("record side" in error for error in errors) def test_store_and_svg_paths_exist() -> None: store = SolutionStore(ROOT / "data") records = store.best_records("All") assert records record = records[0] assert store.ensure_svg(record).exists() assert svg_markup(store.solution_for_record(record)).startswith("