"""Unit tests for model_compile."""
import asyncio
import shutil
import pytest
from app.config import Settings
from app.model_compile import _collect_diagnostics, compile_scad
HAS_OPENSCAD = shutil.which("openscad") is not None
def test_collect_diagnostics_keeps_actionable_lines():
stderr = (
"Geometries in cache: 1\n"
"Geometry cache size in bytes: 728\n"
"ECHO: \"bbox_x\", 52\n"
"WARNING: Object may not be a valid 2-manifold and may need repair!\n"
"CGAL Polyhedrons in cache: 0\n"
"CGAL cache size in bytes: 0\n"
"CGAL Cache insert: difference(){cube(size=[40,20,4],center= (46928 bytes)\n"
"CGAL Cache hit: difference(){cube(size=[40,20,4],center= (46928 bytes)\n"
"Total rendering time: 0:00:00.123\n"
" Top level object is a 3D object:\n"
" Facets: 6\n"
)
text = _collect_diagnostics(stderr)
assert 'ECHO: "bbox_x", 52' in text
assert "WARNING" in text
assert "Top level object is a 3D object" in text
assert "Facets:" in text
for noise in (
"Geometries in cache",
"cache size in bytes",
"CGAL Cache insert",
"CGAL Cache hit",
"Total rendering time",
):
assert noise not in text
def test_collect_diagnostics_truncates():
text = _collect_diagnostics("ECHO: \"x\", 1\n" * 1000, limit=100)
assert len(text) <= 100 + len("\n… (diagnostics truncated)")
assert text.endswith("(diagnostics truncated)")
@pytest.mark.skipif(not HAS_OPENSCAD, reason="openscad is not installed")
def test_compile_surfaces_echo_and_facets(tmp_path, monkeypatch):
monkeypatch.setenv("SESSION_FILES_DIR", str(tmp_path))
session = tmp_path / "s"
session.mkdir()
(session / "part.scad").write_text(
'echo("bbox_x", 12);\ncube([12, 8, 4]);\n',
encoding="utf-8",
)
result = asyncio.run(compile_scad(Settings(), "s", "part.scad", "part.stl"))
assert result["success"] is True
assert 'ECHO: "bbox_x", 12' in result["output"]
assert "Facets:" in result["output"]
assert "ECHO" in result["metadata"]["diagnostics"]
@pytest.mark.skipif(not HAS_OPENSCAD, reason="openscad is not installed")
def test_failed_assert_stops_compile_with_its_message(tmp_path, monkeypatch):
monkeypatch.setenv("SESSION_FILES_DIR", str(tmp_path))
session = tmp_path / "s"
session.mkdir()
(session / "part.scad").write_text(
"assert(52 <= 50, \"interface does not fit: 52 > 50\");\ncube([10, 10, 10]);\n",
encoding="utf-8",
)
result = asyncio.run(compile_scad(Settings(), "s", "part.scad", "part.stl"))
assert result["success"] is False
assert result["error"] == "openscad_compile_error"
assert "interface does not fit: 52 > 50" in result["output"]
assert not (session / "part.stl").exists()