import sys import unittest from unittest.mock import MagicMock from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parent.parent sys.path.append(str(PROJECT_ROOT.parent)) # Mock bpy and dependencies for unit testing class DummyObject: def __init__(self, name="TestObj"): self.name = name class DummyMesh: pass class DummyBase: pass mock_types = MagicMock() mock_types.NodeSocket = type("NodeSocket", (DummyBase,), {}) mock_types.Node = type("Node", (DummyBase,), {}) mock_types.NodeCustomGroup = type("NodeCustomGroup", (DummyBase,), {}) mock_types.NodeTree = type("NodeTree", (DummyBase,), {}) mock_types.PropertyGroup = type("PropertyGroup", (DummyBase,), {}) mock_types.Operator = type("Operator", (DummyBase,), {}) mock_types.Panel = type("Panel", (DummyBase,), {}) mock_types.Object = DummyObject mock_types.Mesh = DummyMesh mock_bpy = MagicMock() mock_bpy.context.scene = MagicMock() mock_bpy.context.scene.unit_settings.scale_length = 0.001 mock_bpy.types = mock_types mock_bpy.path.abspath = lambda path: path.replace("//", "/abs/") 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() from NodeSlicer.infra.blender.blender_mesh_capture import SlicingObject, SlicingCollection, SlicingGroup from NodeSlicer.core.nodeslicer.nodes.mesh import _rename_slicing_item class TestRenameMesh(unittest.TestCase): def test_rename_slicing_object(self): so = SlicingObject() so.name = "OldName" renamed = _rename_slicing_item(so, "NewName") self.assertEqual(renamed.name, "NewName") def test_rename_slicing_collection(self): so1 = SlicingObject() so1.name = "Part1" sc = SlicingCollection([], "OldCollection") sc.objects = [so1] renamed = _rename_slicing_item(sc, "NewColl") self.assertEqual(renamed.name, "NewColl") self.assertEqual(renamed.objects[0].name, "NewColl") self.assertEqual(renamed.objects[0].parent, "NewColl") def test_rename_slicing_group(self): sc = SlicingCollection([], "Coll1") sg = SlicingGroup([]) sg.collections = {"Coll1": sc} renamed = _rename_slicing_item(sg, "NewGroup") self.assertIn("NewGroup", renamed.collections) self.assertEqual(renamed.collections["NewGroup"].name, "NewGroup") def test_rename_with_attribute_template(self): import numpy as np so = SlicingObject() so.name = "OriginalBar" so.attributes = { "Rebar Length": {"domain": "face", "type": "float", "values": np.array([12.5, 12.5])} } renamed = _rename_slicing_item(so, "Rebar-L{Rebar Length}M") self.assertEqual(renamed.name, "Rebar-L12.5M") def test_rename_with_multiple_attribute_placeholders(self): import numpy as np so = SlicingObject() so.name = "Piece" so.attributes = { "Material": ["Steel", "Steel"], "Length": {"domain": "face", "type": "float", "values": np.array([500.0, 500.0])} } sc = SlicingCollection([], "Coll1") sc.objects = [so] renamed_sc = _rename_slicing_item(sc, "Part-{Material}-{Length}mm") self.assertEqual(renamed_sc.name, "Part-Steel-500mm") self.assertEqual(renamed_sc.objects[0].name, "Part-Steel-500mm") def test_rename_with_old_name_placeholder(self): import numpy as np so = SlicingObject() so.name = "OriginalBracket" so.attributes = { "Thickness": {"domain": "face", "type": "float", "values": np.array([3.5, 3.5])} } renamed = _rename_slicing_item(so, "{Name}_T{Thickness}mm") self.assertEqual(renamed.name, "OriginalBracket_T3.5mm") if __name__ == '__main__': unittest.main()