import numpy as np import unittest from unittest.mock import MagicMock import sys from pathlib import Path # Add workspace directory to sys.path to resolve root package name (NodeSlicer) PROJECT_ROOT = Path(__file__).resolve().parent.parent sys.path.append(str(PROJECT_ROOT.parent)) # Define dummy classes to avoid metaclass conflicts class DummyNodeSocket: pass class DummyNode: pass class DummyObject: pass class DummyMesh: pass class DummyNodeSocketShader: pass class DummyNodeCustomGroup: pass class DummyNodeTree: pass class DummyOperator: pass class DummyMenu: pass class DummyPanel: pass class DummyPropertyGroup: pass mock_types = MagicMock() mock_types.NodeSocket = DummyNodeSocket mock_types.Node = DummyNode mock_types.Object = DummyObject mock_types.Mesh = DummyMesh mock_types.NodeSocketShader = DummyNodeSocketShader mock_types.NodeCustomGroup = DummyNodeCustomGroup mock_types.NodeTree = DummyNodeTree mock_types.Operator = DummyOperator mock_types.Menu = DummyMenu mock_types.Panel = DummyPanel mock_types.PropertyGroup = DummyPropertyGroup mock_bpy = MagicMock() mock_bpy.context.scene = MagicMock() mock_bpy.context.scene.unit_settings.scale_length = 0.001 mock_bpy.types = mock_types sys.modules['bpy'] = mock_bpy sys.modules['bpy.types'] = mock_types sys.modules['bpy.props'] = MagicMock() sys.modules['bpy.utils'] = MagicMock() sys.modules['bpy.utils.previews'] = MagicMock() sys.modules['bpy.app'] = MagicMock() sys.modules['bpy.app.handlers'] = MagicMock() # Import the actual functions to test from NodeSlicer.core.slice import segments_to_slice, link_segments class TestSlice(unittest.TestCase): def test_link_segments_closed(self): # Closed triangle: A(0,0,10) -> B(10,0,10) -> C(0,10,10) -> A(0,0,10) segments = np.array([ [[0.0, 0.0, 10.0], [10.0, 0.0, 10.0]], [[10.0, 0.0, 10.0], [0.0, 10.0, 10.0]], [[0.0, 10.0, 10.0], [0.0, 0.0, 10.0]] ]) linked = link_segments(segments) self.assertEqual(len(linked), 1) path = linked[0] # Should start and end at the same point (A) self.assertTrue(np.allclose(path[0], path[-1])) # Verify segments_to_slice closes it sliced = segments_to_slice(segments) self.assertEqual(len(sliced), 1) sliced_path = sliced[0] self.assertTrue(np.allclose(sliced_path[0], sliced_path[-1])) def test_link_segments_open(self): # Open path: A(0,0,10) -> B(10,0,10) -> C(0,10,10) (no C->A segment) segments = np.array([ [[0.0, 0.0, 10.0], [10.0, 0.0, 10.0]], [[10.0, 0.0, 10.0], [0.0, 10.0, 10.0]] ]) linked = link_segments(segments) self.assertEqual(len(linked), 1) path = linked[0] # Should NOT start and end at the same point self.assertFalse(np.allclose(path[0], path[-1])) # Verify segments_to_slice does NOT close it sliced = segments_to_slice(segments) self.assertEqual(len(sliced), 1) sliced_path = sliced[0] self.assertFalse(np.allclose(sliced_path[0], sliced_path[-1]), f"Path was incorrectly closed: {sliced_path}") if __name__ == '__main__': unittest.main()