neuralcad / tests /test_cam.py
CallMeDaniel's picture
refactor: add ToolConfig pydantic model, replace tool_config dicts
cdccbe3
"""Tests for core/cam.py — CAM engine."""
from core.cam import CAMResult, ToolConfig
class TestToolConfig:
def test_defaults(self):
tc = ToolConfig()
assert tc.diameter == 6.0
assert tc.h_feed == 800
assert tc.v_feed == 200
assert tc.speed == 18000
def test_custom_values(self):
tc = ToolConfig(diameter=3.0, h_feed=400, v_feed=100, speed=24000)
assert tc.diameter == 3.0
assert tc.h_feed == 400
assert tc.v_feed == 100
assert tc.speed == 24000
def test_model_dump(self):
tc = ToolConfig(diameter=10.0, h_feed=1000, v_feed=300, speed=12000)
d = tc.model_dump()
assert d == {"diameter": 10.0, "h_feed": 1000, "v_feed": 300, "speed": 12000}
class TestCAMResult:
def test_success_result(self):
r = CAMResult(
success=True,
gcode="G21 G90\nG00 X0 Y0 Z10\nM30",
operations=["pocket", "profile"],
tool_config=ToolConfig(diameter=6, h_feed=800),
post_processor="grbl",
)
assert r.success is True
assert "G21" in r.gcode
assert r.operations == ["pocket", "profile"]
assert r.error is None
def test_failure_result(self):
r = CAMResult(success=False, error="ocp-freecad-cam not available")
assert r.success is False
assert r.gcode is None
assert r.error == "ocp-freecad-cam not available"
def test_model_dump(self):
r = CAMResult(
success=True, gcode="G21 G90\nM30",
operations=["pocket"], tool_config=ToolConfig(diameter=6),
)
d = r.model_dump()
assert d["success"] is True
assert d["gcode"] == "G21 G90\nM30"
assert d["operations"] == ["pocket"]
assert d["tool_config"] == {"diameter": 6.0, "h_feed": 800, "v_feed": 200, "speed": 18000}
assert d["post_processor"] == "grbl"
assert d["error"] is None
def test_default_tool_config_is_toolconfig(self):
r = CAMResult(success=True)
assert isinstance(r.tool_config, ToolConfig)
from unittest.mock import patch, MagicMock
from core.cam import generate_gcode
class TestGenerateGcode:
def test_returns_failure_when_ocp_not_available(self):
"""When ocp-freecad-cam is not installed, return a failure CAMResult."""
mock_shape = MagicMock()
result = generate_gcode(
shape=mock_shape,
operations=["pocket"],
tool_config=ToolConfig(diameter=6, h_feed=800, v_feed=200, speed=18000),
post_processor="grbl",
)
assert result.success is False
assert "not available" in result.error.lower() or "not installed" in result.error.lower()
def test_returns_failure_on_empty_operations(self):
mock_shape = MagicMock()
result = generate_gcode(
shape=mock_shape,
operations=[],
)
assert result.success is False
assert "no operations" in result.error.lower()
def test_uses_default_tool_config_when_none(self):
mock_shape = MagicMock()
result = generate_gcode(
shape=mock_shape,
operations=["pocket"],
tool_config=None,
)
assert result.tool_config is not None
assert isinstance(result.tool_config, ToolConfig)
assert result.tool_config.diameter == 6.0
def test_uses_default_post_processor(self):
mock_shape = MagicMock()
result = generate_gcode(shape=mock_shape, operations=["pocket"])
assert result.post_processor == "grbl"
def test_tool_config_attribute_access(self):
mock_shape = MagicMock()
tc = ToolConfig(diameter=3.0, h_feed=400, v_feed=100, speed=24000)
result = generate_gcode(
shape=mock_shape,
operations=["pocket"],
tool_config=tc,
)
assert result.tool_config.diameter == 3.0
assert result.tool_config.h_feed == 400
from core.cam import CAMPlan
class TestCAMPlan:
def test_default_values(self):
plan = CAMPlan(operations=["pocket", "profile"])
assert plan.operations == ["pocket", "profile"]
assert plan.tool_diameter == 6.0
assert plan.tool_h_feed == 800
assert plan.tool_v_feed == 200
assert plan.tool_speed == 18000
assert plan.post_processor == "grbl"
def test_custom_values(self):
plan = CAMPlan(
operations=["adaptive", "surface"],
tool_diameter=3.0,
tool_h_feed=400,
tool_v_feed=100,
tool_speed=24000,
post_processor="linuxcnc",
)
assert plan.tool_diameter == 3.0
assert plan.post_processor == "linuxcnc"
def test_to_tool_config(self):
plan = CAMPlan(operations=["pocket"])
config = plan.to_tool_config()
assert isinstance(config, ToolConfig)
assert config.diameter == 6.0
assert config.h_feed == 800
assert config.v_feed == 200
assert config.speed == 18000