From 504e4b71094615f9d6daaa01e96a979d21efffc9 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Tue, 22 Aug 2017 11:12:02 -0700 Subject: [PATCH] Added full unit test to make sure tool chain works correctly. --- .../Path/PathScripts/PathDressupDogbone.py | 7 +- .../Path/PathScripts/PathToolController.py | 2 +- src/Mod/Path/PathScripts/PathUtils.py | 15 ++-- .../Path/PathTests/TestPathDressupDogbone.py | 86 +++++++++++++++++-- src/Mod/Path/TestPathApp.py | 16 ++-- 5 files changed, 100 insertions(+), 26 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupDogbone.py b/src/Mod/Path/PathScripts/PathDressupDogbone.py index d696e7de79..dd18ff9b51 100644 --- a/src/Mod/Path/PathScripts/PathDressupDogbone.py +++ b/src/Mod/Path/PathScripts/PathDressupDogbone.py @@ -37,7 +37,9 @@ from PySide import QtCore, QtGui """Dogbone Dressup object and FreeCAD command""" LOG_MODULE = PathLog.thisModule() -PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE) + +if False: + PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE) # Qt tanslation handling def translate(context, text, disambig=None): @@ -1000,8 +1002,9 @@ def Create(base, name = 'DogboneDressup'): ViewProviderDressup(obj.ViewObject) obj.Base.ViewObject.Visibility = False - dbo.setup(obj, True) obj.ToolController = base.ToolController + dbo.setup(obj, True) + return obj class CommandDressupDogbone: diff --git a/src/Mod/Path/PathScripts/PathToolController.py b/src/Mod/Path/PathScripts/PathToolController.py index 3540bd545f..6cbed2fa57 100644 --- a/src/Mod/Path/PathScripts/PathToolController.py +++ b/src/Mod/Path/PathScripts/PathToolController.py @@ -236,7 +236,7 @@ class CommandPathToolController: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Default Tool") PathScripts.PathToolController.ToolController(obj) - if assignViewProvider: + if FreeCAD.GuiUp and assignViewProvider: PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject) if tool is None: diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index bb2d2db2ce..028c94144d 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -376,13 +376,14 @@ def findToolController(obj, name=None): PathLog.track('name: {}'.format(name)) c = None - # First check if a user has selected a tool controller in the tree. Return the first one and remove all from selection - for sel in FreeCADGui.Selection.getSelectionEx(): - if hasattr(sel.Object, 'Proxy'): - if isinstance(sel.Object.Proxy, PathScripts.PathToolController.ToolController): - if c is None: - c = sel.Object - FreeCADGui.Selection.removeSelection(sel.Object) + if FreeCAD.GuiUp: + # First check if a user has selected a tool controller in the tree. Return the first one and remove all from selection + for sel in FreeCADGui.Selection.getSelectionEx(): + if hasattr(sel.Object, 'Proxy'): + if isinstance(sel.Object.Proxy, PathScripts.PathToolController.ToolController): + if c is None: + c = sel.Object + FreeCADGui.Selection.removeSelection(sel.Object) if c is not None: return c diff --git a/src/Mod/Path/PathTests/TestPathDressupDogbone.py b/src/Mod/Path/PathTests/TestPathDressupDogbone.py index 1e01c45cf7..091ee6fc40 100644 --- a/src/Mod/Path/PathTests/TestPathDressupDogbone.py +++ b/src/Mod/Path/PathTests/TestPathDressupDogbone.py @@ -25,7 +25,9 @@ import FreeCAD import Path import PathScripts -import PathScripts.PathDressupDogbone as Dogbone +import PathScripts.PathDressupDogbone as PathDressupDogbone +import PathScripts.PathJob as PathJob +import PathScripts.PathProfileFaces as PathProfileFaces import math import unittest @@ -50,26 +52,94 @@ class TestFeature: def setEditorMode(self, prop, mode): pass -class TestDogbone(PathTestBase): +class TestDressupDogbone(PathTestBase): """Unit tests for the Dogbone dressup.""" + def formatBone(self, bone): + return "%d: (%.2f, %.2f)" % (bone[0], bone[1][0], bone[1][1]) + def test00(self): + '''Verify bones are inserted for simple moves.''' path = [] base = TestProfile('Inside', 'CW', 'G0 X10 Y10 Z10\nG1 Z0\nG1 Y100\nG1 X12\nG1 Y10\nG1 X10\nG1 Z10') obj = TestFeature() - db = Dogbone.ObjectDressup(obj, base) + db = PathDressupDogbone.ObjectDressup(obj, base) db.setup(obj, True) db.execute(obj, False) - for bone in db.bones: - print("%d: (%.2f, %.2f)" % (bone[0], bone[1][0], bone[1][1])) + self.assertEquals(len(db.bones), 4) + self.assertEquals("1: (10.00, 100.00)", self.formatBone(db.bones[0])) + self.assertEquals("2: (12.00, 100.00)", self.formatBone(db.bones[1])) + self.assertEquals("3: (12.00, 10.00)", self.formatBone(db.bones[2])) + self.assertEquals("4: (10.00, 10.00)", self.formatBone(db.bones[3])) def test01(self): + '''Verify bones are inserted if hole ends with rapid move out.''' path = [] base = TestProfile('Inside', 'CW', 'G0 X10 Y10 Z10\nG1 Z0\nG1 Y100\nG1 X12\nG1 Y10\nG1 X10\nG0 Z10') obj = TestFeature() - db = Dogbone.ObjectDressup(obj, base) + db = PathDressupDogbone.ObjectDressup(obj, base) db.setup(obj, True) db.execute(obj, False) - for bone in db.bones: - print("%d: (%.2f, %.2f)" % (bone[0], bone[1][0], bone[1][1])) + self.assertEquals(len(db.bones), 4) + self.assertEquals("1: (10.00, 100.00)", self.formatBone(db.bones[0])) + self.assertEquals("2: (12.00, 100.00)", self.formatBone(db.bones[1])) + self.assertEquals("3: (12.00, 10.00)", self.formatBone(db.bones[2])) + self.assertEquals("4: (10.00, 10.00)", self.formatBone(db.bones[3])) + def test02(self): + '''Verify bones are correctly generated for a Profile.''' + doc = FreeCAD.newDocument("TestDressupDogbone") + + # This is a real world test to make sure none of the tool chain broke + box0 = doc.addObject('Part::Box', 'Box') + box0.Width = 100 + box0.Length = 100 + box0.Height = 10 + box1 = doc.addObject('Part::Box', 'Box') + box1.Width = 50 + box1.Length = 50 + box1.Height = 20 + box1.Placement = FreeCAD.Placement(FreeCAD.Vector(25,25,-5), FreeCAD.Rotation(FreeCAD.Vector(0,0,1), 0)) + doc.recompute() + cut = doc.addObject('Part::Cut', 'Cut') + cut.Base = box0 + cut.Tool = box1 + doc.recompute() + + for i in range(11): + face = "Face%d" % (i+1) + f = cut.Shape.getElement(face) + if f.Surface.Axis == FreeCAD.Vector(0,0,1) and f.Orientation == 'Forward': + break + + job = doc.addObject("Path::FeatureCompoundPython", "Job") + PathJob.ObjectPathJob(job, cut, None) + + profile = PathProfileFaces.Create('Profile Faces') + profile.Base = (cut, face) + profile.StepDown = 5 + profile.processHoles = True + profile.processPerimeter = True + doc.recompute() + + dogbone = PathDressupDogbone.Create(profile) + doc.recompute() + + dog = dogbone.Proxy + locs = sorted([bone[1] for bone in dog.bones], key=lambda (x,y): x * 1000 + y) + + def formatBoneLoc((x, y)): + return "(%.2f, %.2f)" % (x, y) + + # Make sure we get 8 bones, 2 in each corner (different heights) + self.assertEquals(len(locs), 8) + self.assertEquals("(27.50, 27.50)", formatBoneLoc(locs[0])) + self.assertEquals("(27.50, 27.50)", formatBoneLoc(locs[1])) + self.assertEquals("(27.50, 72.50)", formatBoneLoc(locs[2])) + self.assertEquals("(27.50, 72.50)", formatBoneLoc(locs[3])) + self.assertEquals("(72.50, 27.50)", formatBoneLoc(locs[4])) + self.assertEquals("(72.50, 27.50)", formatBoneLoc(locs[5])) + self.assertEquals("(72.50, 72.50)", formatBoneLoc(locs[6])) + self.assertEquals("(72.50, 72.50)", formatBoneLoc(locs[7])) + + FreeCAD.closeDocument("TestDressupDogbone") diff --git a/src/Mod/Path/TestPathApp.py b/src/Mod/Path/TestPathApp.py index 2a31570ede..1b17e242f1 100644 --- a/src/Mod/Path/TestPathApp.py +++ b/src/Mod/Path/TestPathApp.py @@ -24,12 +24,12 @@ import TestApp -#from PathTests.TestPathLog import TestPathLog -#from PathTests.TestPathCore import TestPathCore -##from PathTests.TestPathPost import PathPostTestCases -#from PathTests.TestPathGeom import TestPathGeom -#from PathTests.TestPathUtil import TestPathUtil -#from PathTests.TestPathDepthParams import depthTestCases -#from PathTests.TestPathDressupHoldingTags import TestHoldingTags -from PathTests.TestPathDressupDogbone import TestDogbone +from PathTests.TestPathLog import TestPathLog +from PathTests.TestPathCore import TestPathCore +#from PathTests.TestPathPost import PathPostTestCases +from PathTests.TestPathGeom import TestPathGeom +from PathTests.TestPathUtil import TestPathUtil +from PathTests.TestPathDepthParams import depthTestCases +from PathTests.TestPathDressupHoldingTags import TestHoldingTags +from PathTests.TestPathDressupDogbone import TestDressupDogbone