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.
210 lines
6.7 KiB
Python
210 lines
6.7 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
|
|
self.Rotation = rotation
|
|
|
|
fake_freecad = types.ModuleType("FreeCAD")
|
|
fake_freecad.Vector = Vector
|
|
fake_freecad.Rotation = Rotation
|
|
fake_freecad.Placement = Placement
|
|
fake_freecad.ActiveDocument = None
|
|
fake_freecad.Console = types.SimpleNamespace(
|
|
PrintMessage=lambda *args, **kwargs: None,
|
|
PrintWarning=lambda *args, **kwargs: None,
|
|
PrintError=lambda *args, **kwargs: None,
|
|
)
|
|
sys.modules["FreeCAD"] = fake_freecad
|
|
|
|
fake_freecadgui = types.ModuleType("FreeCADGui")
|
|
fake_freecadgui.addCommand = lambda *args, **kwargs: None
|
|
fake_freecadgui.Selection = types.SimpleNamespace(getSelectionEx=lambda: [])
|
|
sys.modules["FreeCADGui"] = fake_freecadgui
|
|
|
|
|
|
def _install_fake_freecad_without_gui_commands():
|
|
_install_fake_freecad()
|
|
sys.modules["FreeCADGui"] = types.ModuleType("FreeCADGui")
|
|
|
|
|
|
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.ViewObject = FakeViewObject()
|
|
self.Placement = None
|
|
|
|
def isDerivedFrom(self, type_name):
|
|
if self.TypeId == type_name:
|
|
return True
|
|
if type_name == "App::DocumentObjectGroup":
|
|
return self.TypeId == "App::DocumentObjectGroup"
|
|
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)
|
|
|
|
|
|
class FakeDocument:
|
|
def __init__(self):
|
|
self.Name = "TemplateDoc"
|
|
self.Objects = []
|
|
self.recomputed = False
|
|
self.saved_path = ""
|
|
|
|
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 recompute(self):
|
|
self.recomputed = True
|
|
|
|
def saveAs(self, path):
|
|
self.saved_path = path
|
|
|
|
|
|
def _reload_modules():
|
|
for name in ["TerminalObjects", "TemplateAuthoring"]:
|
|
sys.modules.pop(name, None)
|
|
return importlib.import_module("TemplateAuthoring")
|
|
|
|
|
|
class TemplateAuthoringTest(unittest.TestCase):
|
|
def test_template_authoring_command_titles_are_chinese(self):
|
|
_install_fake_freecad()
|
|
template_authoring = _reload_modules()
|
|
|
|
self.assertEqual(
|
|
"添加模板端子",
|
|
template_authoring.CommandAddTemplateTerminal().GetResources()["MenuText"],
|
|
)
|
|
self.assertEqual(
|
|
"校验模板端子",
|
|
template_authoring.CommandValidateTemplateTerminals().GetResources()["MenuText"],
|
|
)
|
|
self.assertEqual(
|
|
"保存模板为 FCStd",
|
|
template_authoring.CommandSaveTemplateAsFCStd().GetResources()["MenuText"],
|
|
)
|
|
|
|
def test_import_skips_command_registration_when_gui_has_no_add_command(self):
|
|
_install_fake_freecad_without_gui_commands()
|
|
|
|
template_authoring = _reload_modules()
|
|
|
|
self.assertTrue(hasattr(template_authoring, "save_template_as_fcstd"))
|
|
|
|
def test_create_template_terminal_writes_lcs_semantics(self):
|
|
_install_fake_freecad()
|
|
template_authoring = _reload_modules()
|
|
app = sys.modules["FreeCAD"]
|
|
doc = FakeDocument()
|
|
|
|
terminal = template_authoring.create_template_terminal(
|
|
doc,
|
|
"P1",
|
|
app.Vector(10, 20, 30),
|
|
terminal_type="primary",
|
|
)
|
|
|
|
self.assertEqual("Terminal_P1", terminal.Name)
|
|
self.assertEqual("P1", terminal.Label)
|
|
self.assertEqual("Terminal", terminal.Role)
|
|
self.assertTrue(terminal.CanWire)
|
|
self.assertEqual("P1", terminal.QetTemplateSlotName)
|
|
self.assertEqual("P1", terminal.QetTerminalLabel)
|
|
self.assertEqual("primary", terminal.QetTerminalType)
|
|
self.assertEqual(10.0, terminal.Placement.Base.x)
|
|
self.assertEqual(20.0, terminal.Placement.Base.y)
|
|
self.assertEqual(30.0, terminal.Placement.Base.z)
|
|
self.assertTrue(doc.recomputed)
|
|
|
|
def test_validate_template_terminals_reports_missing_slot_name(self):
|
|
_install_fake_freecad()
|
|
template_authoring = _reload_modules()
|
|
doc = FakeDocument()
|
|
terminal = doc.addObject("Part::LocalCoordinateSystem", "BrokenTerminal")
|
|
terminal.addProperty("App::PropertyString", "Role", "QET Template", "role")
|
|
terminal.Role = "Terminal"
|
|
terminal.addProperty(
|
|
"App::PropertyBool",
|
|
"CanWire",
|
|
"QET Template",
|
|
"can wire",
|
|
)
|
|
terminal.CanWire = True
|
|
|
|
report = template_authoring.validate_template_terminals(doc)
|
|
|
|
self.assertEqual(1, report["total_terminals"])
|
|
self.assertEqual(0, report["valid_terminals"])
|
|
self.assertEqual(1, len(report["warnings"]))
|
|
self.assertIn("QetTemplateSlotName", report["warnings"][0])
|
|
|
|
def test_save_template_as_fcstd_adds_extension_and_saves_valid_template(self):
|
|
_install_fake_freecad()
|
|
template_authoring = _reload_modules()
|
|
app = sys.modules["FreeCAD"]
|
|
doc = FakeDocument()
|
|
template_authoring.create_template_terminal(doc, "P1", app.Vector(1, 2, 3))
|
|
|
|
report = template_authoring.save_template_as_fcstd(doc, "D:/tmp/current-transformer")
|
|
|
|
self.assertEqual("D:/tmp/current-transformer.FCStd", doc.saved_path)
|
|
self.assertEqual("D:/tmp/current-transformer.FCStd", report["path"])
|
|
self.assertEqual(1, report["valid_terminals"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|