"""Tests for embedded bridge implementation.""" from unittest import mock import pytest from freecad_mcp.bridge.embedded import EmbeddedBridge class TestEmbeddedBridge: """Tests for EmbeddedBridge class.""" def test_initialization(self): """Bridge should initialize with correct defaults.""" bridge = EmbeddedBridge() assert bridge._freecad_path is None assert bridge._fc_module is None assert bridge._connected is False def test_initialization_with_path(self): """Bridge should accept custom FreeCAD path.""" bridge = EmbeddedBridge(freecad_path="/custom/path") assert bridge._freecad_path == "/custom/path" @pytest.mark.asyncio async def test_is_connected_before_connect(self): """is_connected should return False before connect.""" bridge = EmbeddedBridge() assert await bridge.is_connected() is False @pytest.mark.asyncio async def test_execute_python_when_not_connected(self): """execute_python should return error when not connected.""" bridge = EmbeddedBridge() result = await bridge.execute_python("x = 1") assert result.success is False assert result.error_type == "ConnectionError" assert "not connected" in result.stderr @pytest.mark.asyncio async def test_disconnect_when_not_connected(self): """disconnect should handle not being connected.""" bridge = EmbeddedBridge() # Should not raise await bridge.disconnect() assert bridge._connected is False class TestEmbeddedBridgeCodeExecution: """Tests for code execution in embedded bridge.""" @pytest.fixture def mock_freecad(self): """Create a mock FreeCAD module.""" mock_fc = mock.MagicMock() mock_fc.Version.return_value = ["0", "21", "2", "2024-01-01"] mock_fc.listDocuments.return_value = {} mock_fc.ActiveDocument = None return mock_fc @pytest.mark.asyncio async def test_execute_simple_code(self, mock_freecad): """execute_python should execute simple Python code.""" bridge = EmbeddedBridge() bridge._fc_module = mock_freecad bridge._connected = True result = await bridge.execute_python("_result_ = 1 + 1") assert result.success is True assert result.result == 2 @pytest.mark.asyncio async def test_execute_code_with_print(self, mock_freecad): """execute_python should capture stdout.""" bridge = EmbeddedBridge() bridge._fc_module = mock_freecad bridge._connected = True result = await bridge.execute_python("print('hello')") assert result.success is True assert "hello" in result.stdout @pytest.mark.asyncio async def test_execute_code_with_error(self, mock_freecad): """execute_python should capture exceptions.""" bridge = EmbeddedBridge() bridge._fc_module = mock_freecad bridge._connected = True result = await bridge.execute_python("raise ValueError('test error')") assert result.success is False assert result.error_type == "ValueError" assert result.error_traceback is not None assert "test error" in result.error_traceback @pytest.mark.asyncio async def test_execute_code_with_syntax_error(self, mock_freecad): """execute_python should handle syntax errors.""" bridge = EmbeddedBridge() bridge._fc_module = mock_freecad bridge._connected = True result = await bridge.execute_python("def bad syntax") assert result.success is False assert result.error_type == "SyntaxError" class TestEmbeddedBridgeDocuments: """Tests for document handling in embedded bridge.""" @pytest.fixture def mock_freecad_with_doc(self): """Create mock FreeCAD with a document.""" mock_doc = mock.MagicMock() mock_doc.Name = "TestDoc" mock_doc.Label = "Test Document" mock_doc.FileName = "/tmp/test.FCStd" mock_doc.Modified = False mock_doc.Objects = [] mock_fc = mock.MagicMock() mock_fc.listDocuments.return_value = {"TestDoc": mock_doc} mock_fc.ActiveDocument = mock_doc mock_fc.getDocument.return_value = mock_doc return mock_fc @pytest.mark.asyncio async def test_get_documents_empty(self): """get_documents should return empty list when no docs.""" mock_fc = mock.MagicMock() mock_fc.listDocuments.return_value = {} bridge = EmbeddedBridge() bridge._fc_module = mock_fc bridge._connected = True # Mock the execute_python to return empty list result = await bridge.get_documents() # Since we're not mocking exec properly, we expect empty assert isinstance(result, list)