You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LightWork3D/tests/python/freecad_exchange_template_i...

195 lines
7.0 KiB
Python

import importlib
import sys
import types
import unittest
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[2]
MODULE_DIR = REPO_ROOT / "src" / "Mod" / "FreeCADExchange"
if str(MODULE_DIR) not in sys.path:
sys.path.insert(0, str(MODULE_DIR))
def _install_fake_freecad():
class Vector:
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = float(x)
self.y = float(y)
self.z = float(z)
class Rotation:
def __init__(self, axis=None, angle=None):
self.Axis = axis
self.Angle = angle
class Placement:
def __init__(self, base=None, rotation=None):
self.Base = base or Vector()
self.Rotation = rotation or Rotation()
fake_freecad = types.ModuleType("FreeCAD")
fake_freecad.Vector = Vector
fake_freecad.Rotation = Rotation
fake_freecad.Placement = Placement
fake_freecad.Console = types.SimpleNamespace(
PrintMessage=lambda *args, **kwargs: None,
PrintWarning=lambda *args, **kwargs: None,
PrintError=lambda *args, **kwargs: None,
)
fake_freecad.ActiveDocument = None
sys.modules["FreeCAD"] = fake_freecad
fake_freecadgui = types.ModuleType("FreeCADGui")
fake_freecadgui.SendMsgToActiveView = lambda *args, **kwargs: None
fake_freecadgui.addCommand = lambda *args, **kwargs: None
fake_freecadgui.Selection = types.SimpleNamespace(getSelection=lambda: [])
sys.modules["FreeCADGui"] = fake_freecadgui
fake_importgui = types.ModuleType("ImportGui")
fake_importgui.insert = lambda *args, **kwargs: None
sys.modules["ImportGui"] = fake_importgui
class FakeViewObject:
def __init__(self):
self.Visibility = True
self.ShapeColor = None
class FakeObject:
def __init__(self, name, type_id):
self.Name = name
self.Label = name
self.TypeId = type_id
self.PropertiesList = []
self.Group = []
self.InList = []
self.ViewObject = FakeViewObject()
self.Placement = sys.modules["FreeCAD"].Placement()
def isDerivedFrom(self, type_name):
if self.TypeId == type_name:
return True
if type_name == "App::DocumentObjectGroup":
return self.TypeId in {"App::DocumentObjectGroup", "App::Part"}
if type_name == "App::LocalCoordinateSystem":
return self.TypeId in {"Part::LocalCoordinateSystem", "PartDesign::CoordinateSystem"}
return False
def addProperty(self, prop_type, prop_name, group_name, description):
if prop_name not in self.PropertiesList:
self.PropertiesList.append(prop_name)
def addObject(self, child):
if child not in self.Group:
self.Group.append(child)
if self not in child.InList:
child.InList.append(self)
class FakeDocument:
def __init__(self):
self.Name = "QETScene"
self.Objects = []
def addObject(self, type_name, name):
obj = FakeObject(name, type_name)
self.Objects.append(obj)
return obj
def getObject(self, name):
for obj in self.Objects:
if obj.Name == name:
return obj
return None
def removeObject(self, name):
self.Objects = [obj for obj in self.Objects if obj.Name != name]
def recompute(self):
return None
def _reload_modules():
for name in [
"TerminalObjects",
"TemplateSemantics",
"DeviceImport",
"TemplateInstantiation",
]:
sys.modules.pop(name, None)
return importlib.import_module("TemplateInstantiation"), importlib.import_module("TerminalObjects")
class TemplateInstantiationTest(unittest.TestCase):
def test_template_lcs_slots_become_engineering_terminals(self):
_install_fake_freecad()
template_instantiation, terminal_objects = _reload_modules()
app = sys.modules["FreeCAD"]
doc = FakeDocument()
root = terminal_objects.ensure_root_group(doc, "project-1")
device = doc.addObject("App::Part", "QETDevice_ct_1")
root.addObject(device)
terminal_objects.ensure_string_property(device, "QetElementUuid", "QET Exchange", "", "ct-1")
terminal_objects.ensure_string_property(device, "QetInstanceId", "QET Exchange", "", "inst-1")
terminal_objects.ensure_string_property(device, "QetProjectUuid", "QET Exchange", "", "project-1")
p1 = doc.addObject("Part::LocalCoordinateSystem", "P1")
p1.Placement = app.Placement(app.Vector(10, 20, 30), app.Rotation())
p1.addProperty("App::PropertyString", "Role", "QET Template", "")
p1.Role = "Terminal"
p1.addProperty("App::PropertyBool", "CanWire", "QET Template", "")
p1.CanWire = True
p1.addProperty("App::PropertyString", "QetTemplateSlotName", "QET Template", "")
p1.QetTemplateSlotName = "P1"
device.addObject(p1)
report = template_instantiation.ensure_engineering_terminals_for_device(doc, device)
terminal_group = terminal_objects.find_child_group_by_kind(
device,
terminal_objects.TERMINAL_GROUP_KIND,
)
terminals = terminal_objects.collect_terminal_objects(terminal_group)
self.assertEqual(1, report["created_terminals"])
self.assertEqual(1, len(terminals))
self.assertEqual("local:inst-1:P1", terminals[0].QetTerminalUuid)
self.assertEqual("inst-1", terminals[0].QetInstanceId)
self.assertEqual("ct-1", terminals[0].QetElementUuid)
self.assertEqual("P1", terminals[0].QetTemplateSlotName)
self.assertEqual("local", terminals[0].QetTerminalBindingMode)
self.assertTrue(terminals[0].CanWire)
self.assertFalse(p1.ViewObject.Visibility)
def test_device_without_template_slots_reports_no_created_terminals(self):
_install_fake_freecad()
template_instantiation, terminal_objects = _reload_modules()
doc = FakeDocument()
root = terminal_objects.ensure_root_group(doc, "project-1")
device = doc.addObject("App::Part", "QETDevice_ct_1")
root.addObject(device)
terminal_objects.ensure_string_property(device, "QetElementUuid", "QET Exchange", "", "ct-1")
terminal_objects.ensure_string_property(device, "QetInstanceId", "QET Exchange", "", "inst-1")
terminal_objects.ensure_string_property(device, "QetProjectUuid", "QET Exchange", "", "project-1")
report = template_instantiation.ensure_engineering_terminals_for_device(doc, device)
terminal_group = terminal_objects.find_child_group_by_kind(
device,
terminal_objects.TERMINAL_GROUP_KIND,
)
self.assertEqual(0, report["slots"])
self.assertEqual(0, report["created_terminals"])
self.assertEqual(1, report["skipped_devices_without_template_slots"])
self.assertIn("没有模板端子", report["warnings"][0])
self.assertEqual([], terminal_objects.collect_terminal_objects(terminal_group))
if __name__ == "__main__":
unittest.main()