diff --git a/src/Mod/Test/BaseTests.py b/src/Mod/Test/BaseTests.py index 41fa4324f5..76455b4533 100644 --- a/src/Mod/Test/BaseTests.py +++ b/src/Mod/Test/BaseTests.py @@ -1,29 +1,30 @@ -#*************************************************************************** -#* Copyright (c) 2004 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2004 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ import FreeCAD, os, unittest, tempfile, math from FreeCAD import Base + class ConsoleTestCase(unittest.TestCase): def setUp(self): self.count = 0 @@ -40,20 +41,21 @@ class ConsoleTestCase(unittest.TestCase): import _thread as thread, time except Exception: import thread, time + def adder(): lock.acquire() - self.count=self.count+1 + self.count = self.count + 1 # call of Console method is thread-safe - FreeCAD.Console.PrintMessage("Call from Python thread: count="+str(self.count)+"\n") + FreeCAD.Console.PrintMessage("Call from Python thread: count=" + str(self.count) + "\n") lock.release() - lock=thread.allocate_lock() + lock = thread.allocate_lock() for i in range(10): - thread.start_new(adder,()) + thread.start_new(adder, ()) time.sleep(3) self.assertEqual(self.count, 10, "Synchronization of threads failed") - FreeCAD.Console.PrintMessage(str(self.count)+"\n") + FreeCAD.Console.PrintMessage(str(self.count) + "\n") def testAsynchronPrintFromThread(self): # http://python-kurs.eu/threads.php @@ -61,43 +63,46 @@ class ConsoleTestCase(unittest.TestCase): import _thread as thread, time except Exception: import thread, time - def adder(): - self.count=self.count+1 - # call of Console method is thread-safe - FreeCAD.Console.PrintMessage("Call from Python thread (not synchronized): count="+str(self.count)+"\n") - lock=thread.allocate_lock() + def adder(): + self.count = self.count + 1 + # call of Console method is thread-safe + FreeCAD.Console.PrintMessage( + "Call from Python thread (not synchronized): count=" + str(self.count) + "\n" + ) + + lock = thread.allocate_lock() for i in range(10): - thread.start_new(adder,()) + thread.start_new(adder, ()) time.sleep(3) - FreeCAD.Console.PrintMessage(str(self.count)+"\n") + FreeCAD.Console.PrintMessage(str(self.count) + "\n") -# def testStatus(self): -# SLog = FreeCAD.GetStatus("Console","Log") -# SErr = FreeCAD.GetStatus("Console","Err") -# SWrn = FreeCAD.GetStatus("Console","Wrn") -# SMsg = FreeCAD.GetStatus("Console","Msg") -# FreeCAD.SetStatus("Console","Log",1) -# FreeCAD.SetStatus("Console","Err",1) -# FreeCAD.SetStatus("Console","Wrn",1) -# FreeCAD.SetStatus("Console","Msg",1) -# self.assertEqual(FreeCAD.GetStatus("Console","Msg"),1,"Set and read status failed (Console,Msg)") -# self.assertEqual(FreeCAD.GetStatus("Console","Err"),1,"Set and read status failed (Console,Err)") -# self.assertEqual(FreeCAD.GetStatus("Console","Wrn"),1,"Set and read status failed (Console,Wrn)") -# self.assertEqual(FreeCAD.GetStatus("Console","Log"),1,"Set and read status failed (Console,Log)") -# FreeCAD.SetStatus("Console","Log",0) -# FreeCAD.SetStatus("Console","Err",0) -# FreeCAD.SetStatus("Console","Wrn",0) -# FreeCAD.SetStatus("Console","Msg",0) -# self.assertEqual(FreeCAD.GetStatus("Console","Msg"),0,"Set and read status failed (Console,Msg)") -# self.assertEqual(FreeCAD.GetStatus("Console","Err"),0,"Set and read status failed (Console,Err)") -# self.assertEqual(FreeCAD.GetStatus("Console","Wrn"),0,"Set and read status failed (Console,Wrn)") -# self.assertEqual(FreeCAD.GetStatus("Console","Log"),0,"Set and read status failed (Console,Log)") -# FreeCAD.SetStatus("Console","Log",SLog) -# FreeCAD.SetStatus("Console","Err",SErr) -# FreeCAD.SetStatus("Console","Wrn",SWrn) -# FreeCAD.SetStatus("Console","Msg",SMsg) + # def testStatus(self): + # SLog = FreeCAD.GetStatus("Console","Log") + # SErr = FreeCAD.GetStatus("Console","Err") + # SWrn = FreeCAD.GetStatus("Console","Wrn") + # SMsg = FreeCAD.GetStatus("Console","Msg") + # FreeCAD.SetStatus("Console","Log",1) + # FreeCAD.SetStatus("Console","Err",1) + # FreeCAD.SetStatus("Console","Wrn",1) + # FreeCAD.SetStatus("Console","Msg",1) + # self.assertEqual(FreeCAD.GetStatus("Console","Msg"),1,"Set and read status failed (Console,Msg)") + # self.assertEqual(FreeCAD.GetStatus("Console","Err"),1,"Set and read status failed (Console,Err)") + # self.assertEqual(FreeCAD.GetStatus("Console","Wrn"),1,"Set and read status failed (Console,Wrn)") + # self.assertEqual(FreeCAD.GetStatus("Console","Log"),1,"Set and read status failed (Console,Log)") + # FreeCAD.SetStatus("Console","Log",0) + # FreeCAD.SetStatus("Console","Err",0) + # FreeCAD.SetStatus("Console","Wrn",0) + # FreeCAD.SetStatus("Console","Msg",0) + # self.assertEqual(FreeCAD.GetStatus("Console","Msg"),0,"Set and read status failed (Console,Msg)") + # self.assertEqual(FreeCAD.GetStatus("Console","Err"),0,"Set and read status failed (Console,Err)") + # self.assertEqual(FreeCAD.GetStatus("Console","Wrn"),0,"Set and read status failed (Console,Wrn)") + # self.assertEqual(FreeCAD.GetStatus("Console","Log"),0,"Set and read status failed (Console,Log)") + # FreeCAD.SetStatus("Console","Log",SLog) + # FreeCAD.SetStatus("Console","Err",SErr) + # FreeCAD.SetStatus("Console","Wrn",SWrn) + # FreeCAD.SetStatus("Console","Msg",SMsg) def tearDown(self): pass @@ -105,20 +110,22 @@ class ConsoleTestCase(unittest.TestCase): def testILoggerBlocker(self): if FreeCAD.GuiUp: import QtUnitGui + QtUnitGui.testILoggerBlocker() + class ParameterTestCase(unittest.TestCase): def setUp(self): self.TestPar = FreeCAD.ParamGet("System parameter:Test") def testGroup(self): - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testGroup\n") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testGroup\n") # check on Group creation Temp = self.TestPar.GetGroup("44") - self.assertTrue(self.TestPar.HasGroup("44"),"Test on created group failed") + self.assertTrue(self.TestPar.HasGroup("44"), "Test on created group failed") # check on Deletion self.TestPar.RemGroup("44") - self.assertTrue(self.TestPar.HasGroup("44"),"A referenced group must not be deleted") + self.assertTrue(self.TestPar.HasGroup("44"), "A referenced group must not be deleted") Temp = 0 def testGroupNames(self): @@ -132,205 +139,203 @@ class ParameterTestCase(unittest.TestCase): # check on special conditions def testInt(self): - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testInt\n") - #Temp = FreeCAD.ParamGet("System parameter:Test/44") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testInt\n") + # Temp = FreeCAD.ParamGet("System parameter:Test/44") # check on Int - self.TestPar.SetInt("44",4711) - self.assertEqual(self.TestPar.GetInt("44"), 4711,"In and out error at Int") + self.TestPar.SetInt("44", 4711) + self.assertEqual(self.TestPar.GetInt("44"), 4711, "In and out error at Int") # check on Deletion self.TestPar.RemInt("44") - self.assertEqual(self.TestPar.GetInt("44",1), 1,"Deletion error at Int") - + self.assertEqual(self.TestPar.GetInt("44", 1), 1, "Deletion error at Int") def testBool(self): - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testBool\n") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testBool\n") # check on Int - self.TestPar.SetBool("44",1) - self.assertEqual(self.TestPar.GetBool("44"), 1,"In and out error at Bool") + self.TestPar.SetBool("44", 1) + self.assertEqual(self.TestPar.GetBool("44"), 1, "In and out error at Bool") # check on Deletion self.TestPar.RemBool("44") - self.assertEqual(self.TestPar.GetBool("44",0), 0,"Deletion error at Bool") + self.assertEqual(self.TestPar.GetBool("44", 0), 0, "Deletion error at Bool") def testFloat(self): - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testFloat\n") - #Temp = FreeCAD.ParamGet("System parameter:Test/44") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testFloat\n") + # Temp = FreeCAD.ParamGet("System parameter:Test/44") # check on Int - self.TestPar.SetFloat("44",4711.4711) - self.assertEqual(self.TestPar.GetFloat("44"), 4711.4711,"In and out error at Float") + self.TestPar.SetFloat("44", 4711.4711) + self.assertEqual(self.TestPar.GetFloat("44"), 4711.4711, "In and out error at Float") # check on Deletion self.TestPar.RemFloat("44") - self.assertEqual(self.TestPar.GetFloat("44",1.1), 1.1,"Deletion error at Float") + self.assertEqual(self.TestPar.GetFloat("44", 1.1), 1.1, "Deletion error at Float") def testString(self): - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testFloat\n") - #Temp = FreeCAD.ParamGet("System parameter:Test/44") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testFloat\n") + # Temp = FreeCAD.ParamGet("System parameter:Test/44") # check on Int - self.TestPar.SetString("44","abcdefgh") - self.assertEqual(self.TestPar.GetString("44"), "abcdefgh","In and out error at String") + self.TestPar.SetString("44", "abcdefgh") + self.assertEqual(self.TestPar.GetString("44"), "abcdefgh", "In and out error at String") # check on Deletion self.TestPar.RemString("44") - self.assertEqual(self.TestPar.GetString("44","hallo"), "hallo","Deletion error at String") + self.assertEqual(self.TestPar.GetString("44", "hallo"), "hallo", "Deletion error at String") def testNesting(self): # Parameter testing - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n") + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n") for i in range(50): - self.TestPar.SetFloat(str(i),4711.4711) - self.TestPar.SetInt(str(i),4711) - self.TestPar.SetBool(str(i),1) + self.TestPar.SetFloat(str(i), 4711.4711) + self.TestPar.SetInt(str(i), 4711) + self.TestPar.SetBool(str(i), 1) Temp = self.TestPar.GetGroup(str(i)) for l in range(50): - Temp.SetFloat(str(l),4711.4711) - Temp.SetInt(str(l),4711) - Temp.SetBool(str(l),1) + Temp.SetFloat(str(l), 4711.4711) + Temp.SetInt(str(l), 4711) + Temp.SetBool(str(l), 1) Temp = 0 def testExportImport(self): # Parameter testing - #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n") - self.TestPar.SetFloat("ExTest",4711.4711) - self.TestPar.SetInt("ExTest",4711) - self.TestPar.SetString("ExTest","4711") - self.TestPar.SetBool("ExTest",1) + # FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n") + self.TestPar.SetFloat("ExTest", 4711.4711) + self.TestPar.SetInt("ExTest", 4711) + self.TestPar.SetString("ExTest", "4711") + self.TestPar.SetBool("ExTest", 1) Temp = self.TestPar.GetGroup("ExTest") - Temp.SetFloat("ExTest",4711.4711) - Temp.SetInt("ExTest",4711) - Temp.SetString("ExTest","4711") - Temp.SetBool("ExTest",1) + Temp.SetFloat("ExTest", 4711.4711) + Temp.SetInt("ExTest", 4711) + Temp.SetString("ExTest", "4711") + Temp.SetBool("ExTest", 1) TempPath = tempfile.gettempdir() + os.sep + "ExportTest.FCExport" self.TestPar.Export(TempPath) Temp = self.TestPar.GetGroup("ImportTest") Temp.Import(TempPath) - self.assertEqual(Temp.GetFloat("ExTest"), 4711.4711,"ExportImport error") + self.assertEqual(Temp.GetFloat("ExTest"), 4711.4711, "ExportImport error") Temp = 0 def tearDown(self): - #remove all + # remove all TestPar = FreeCAD.ParamGet("System parameter:Test") TestPar.Clear() + class AlgebraTestCase(unittest.TestCase): def setUp(self): pass def testAngle(self): - v1 = FreeCAD.Vector(0,0,0.000001) - v2 = FreeCAD.Vector(0,0.000001,0) - self.assertAlmostEqual(v1.getAngle(v2), math.pi/2) - self.assertAlmostEqual(v2.getAngle(v1), math.pi/2) + v1 = FreeCAD.Vector(0, 0, 0.000001) + v2 = FreeCAD.Vector(0, 0.000001, 0) + self.assertAlmostEqual(v1.getAngle(v2), math.pi / 2) + self.assertAlmostEqual(v2.getAngle(v1), math.pi / 2) def testVector2d(self): v = FreeCAD.Base.Vector2d(1.0, 1.0) - v.rotate(math.pi/2) + v.rotate(math.pi / 2) self.assertAlmostEqual(v.x, -1.0) self.assertAlmostEqual(v.y, 1.0) def testAngleWithNullVector(self): - v1 = FreeCAD.Vector(0,0,0) - v2 = FreeCAD.Vector(0,1,0) + v1 = FreeCAD.Vector(0, 0, 0) + v2 = FreeCAD.Vector(0, 1, 0) self.assertTrue(math.isnan(v1.getAngle(v2))) self.assertTrue(math.isnan(v2.getAngle(v1))) def testMatrix(self): - m=FreeCAD.Matrix(4,2,1,0,1,1,1,0,0,0,1,0,0,0,0,1) - u=m.multiply(m.inverse()) - self.assertEqual(u, FreeCAD.Matrix(),"Invalid inverse of matrix") + m = FreeCAD.Matrix(4, 2, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1) + u = m.multiply(m.inverse()) + self.assertEqual(u, FreeCAD.Matrix(), "Invalid inverse of matrix") def testRotAndMoveMatrix(self): - m1=FreeCAD.Matrix() - m1.move(10,5,-3) - m1.rotateY(.2) - m2=FreeCAD.Matrix() - m2.rotateY(.2) - m2.move(10,5,-3) - m3=FreeCAD.Matrix() - m3.move(10,5,-3) - m4=FreeCAD.Matrix() - m4.rotateY(.2) - self.assertNotEqual(m1, m3*m4, "Wrong multiplication order") - self.assertEqual(m1, m4*m3 , "Wrong multiplication order") - self.assertEqual(m2, m3*m4 , "Wrong multiplication order") - self.assertNotEqual(m2, m4*m3, "Wrong multiplication order") - + m1 = FreeCAD.Matrix() + m1.move(10, 5, -3) + m1.rotateY(0.2) + m2 = FreeCAD.Matrix() + m2.rotateY(0.2) + m2.move(10, 5, -3) + m3 = FreeCAD.Matrix() + m3.move(10, 5, -3) + m4 = FreeCAD.Matrix() + m4.rotateY(0.2) + self.assertNotEqual(m1, m3 * m4, "Wrong multiplication order") + self.assertEqual(m1, m4 * m3, "Wrong multiplication order") + self.assertEqual(m2, m3 * m4, "Wrong multiplication order") + self.assertNotEqual(m2, m4 * m3, "Wrong multiplication order") def testRotationFromMatrix(self): m1 = FreeCAD.Matrix() - m1.rotateZ(.2) + m1.rotateZ(0.2) m1.scale(0.5) - m1.rotateY(.2) + m1.rotateY(0.2) m1.scale(3) - m1.move(10,5,-3) + m1.move(10, 5, -3) r1 = FreeCAD.Rotation(m1) m2 = FreeCAD.Matrix() - m2.rotateZ(.2) - m2.rotateY(.2) - m2.move(10,5,-3) - r2 = FreeCAD.Rotation(m2) - self.assertTrue(r1.isSame(r2, 1e-7), 'Scale on matrix influenced rotation') + m2.rotateZ(0.2) + m2.rotateY(0.2) + m2.move(10, 5, -3) + r2 = FreeCAD.Rotation(m2) + self.assertTrue(r1.isSame(r2, 1e-7), "Scale on matrix influenced rotation") m3 = FreeCAD.Matrix() m3.scale(-1) r3 = FreeCAD.Rotation(m3) r0 = FreeCAD.Rotation() - self.assertTrue(r3.isSame(r0, 1e-7), 'Scale on matrix influenced rotation') + self.assertTrue(r3.isSame(r0, 1e-7), "Scale on matrix influenced rotation") m4 = FreeCAD.Matrix() - m4.scale(1.25,1.0,0.25) - m4.move(4,5,6) - r24 = FreeCAD.Rotation(m2*m4) - r42 = FreeCAD.Rotation(m4*m2) - self.assertTrue(r2.isSame(r24, 1e-7), 'Scale on matrix influenced rotation') - self.assertTrue(r2.isSame(r42, 1e-7), 'Scale on matrix influenced rotation') + m4.scale(1.25, 1.0, 0.25) + m4.move(4, 5, 6) + r24 = FreeCAD.Rotation(m2 * m4) + r42 = FreeCAD.Rotation(m4 * m2) + self.assertTrue(r2.isSame(r24, 1e-7), "Scale on matrix influenced rotation") + self.assertTrue(r2.isSame(r42, 1e-7), "Scale on matrix influenced rotation") - def testRotation(self): - r=FreeCAD.Rotation(1,0,0,0) # 180 deg around (1,0,0) - self.assertEqual(r.Axis, FreeCAD.Vector(1,0,0)) + r = FreeCAD.Rotation(1, 0, 0, 0) # 180 deg around (1,0,0) + self.assertEqual(r.Axis, FreeCAD.Vector(1, 0, 0)) self.assertAlmostEqual(math.fabs(r.Angle), math.fabs(math.pi)) - r=r.multiply(r) # identity - self.assertEqual(r.Axis, FreeCAD.Vector(0,0,1)) + r = r.multiply(r) # identity + self.assertEqual(r.Axis, FreeCAD.Vector(0, 0, 1)) self.assertAlmostEqual(r.Angle, 0) - r=FreeCAD.Rotation(1,0,0,0) - r.Q=(0,0,0,1) # update axis and angle - s=FreeCAD.Rotation(0,0,0,1) + r = FreeCAD.Rotation(1, 0, 0, 0) + r.Q = (0, 0, 0, 1) # update axis and angle + s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) - r=FreeCAD.Rotation(1,0,0,0) - r.Matrix=FreeCAD.Matrix() # update axis and angle - s=FreeCAD.Rotation(0,0,0,1) + r = FreeCAD.Rotation(1, 0, 0, 0) + r.Matrix = FreeCAD.Matrix() # update axis and angle + s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) - r=FreeCAD.Rotation(1,0,0,0) - r.Axes=(FreeCAD.Vector(0,0,1),FreeCAD.Vector(0,0,1)) # update axis and angle - s=FreeCAD.Rotation(0,0,0,1) + r = FreeCAD.Rotation(1, 0, 0, 0) + r.Axes = (FreeCAD.Vector(0, 0, 1), FreeCAD.Vector(0, 0, 1)) # update axis and angle + s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) - #add 360 deg to angle - r=FreeCAD.Rotation(FreeCAD.Vector(1,0,0),270) - s=FreeCAD.Rotation(FreeCAD.Vector(1,0,0),270+360) + # add 360 deg to angle + r = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 270) + s = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 270 + 360) self.assertEqual(r.Axis, s.Axis) - #self.assertAlmostEqual(r.Angle, s.Angle + 2*math.pi) + # self.assertAlmostEqual(r.Angle, s.Angle + 2*math.pi) self.assertTrue(r.isSame(s)) - #subtract 360 deg from angle using Euler angles - r=FreeCAD.Rotation(0,0,180) + # subtract 360 deg from angle using Euler angles + r = FreeCAD.Rotation(0, 0, 180) r.invert() - s=FreeCAD.Rotation(0,0,-180) + s = FreeCAD.Rotation(0, 0, -180) self.assertTrue(r.isSame(s)) - #subtract 360 deg from angle using quaternion - r=FreeCAD.Rotation(1,0,0,0) - s=FreeCAD.Rotation(-1,0,0,0) - #angles have the same sign + # subtract 360 deg from angle using quaternion + r = FreeCAD.Rotation(1, 0, 0, 0) + s = FreeCAD.Rotation(-1, 0, 0, 0) + # angles have the same sign if r.Angle * s.Angle > 0: - self.assertEqual(r.Axis, s.Axis*(-1)) + self.assertEqual(r.Axis, s.Axis * (-1)) else: self.assertAlmostEqual(r.Angle, -s.Angle) self.assertTrue(r.isSame(s)) @@ -338,10 +343,10 @@ class AlgebraTestCase(unittest.TestCase): self.assertTrue(r.isSame(s)) # gimbal lock (north pole) - r=FreeCAD.Rotation() + r = FreeCAD.Rotation() r.setYawPitchRoll(20, 90, 10) - a=r.getYawPitchRoll() - s=FreeCAD.Rotation() + a = r.getYawPitchRoll() + s = FreeCAD.Rotation() s.setYawPitchRoll(*a) self.assertAlmostEqual(a[0], 0.0) self.assertAlmostEqual(a[1], 90.0) @@ -349,10 +354,10 @@ class AlgebraTestCase(unittest.TestCase): self.assertTrue(r.isSame(s, 1e-12)) # gimbal lock (south pole) - r=FreeCAD.Rotation() + r = FreeCAD.Rotation() r.setYawPitchRoll(20, -90, 10) - a=r.getYawPitchRoll() - s=FreeCAD.Rotation() + a = r.getYawPitchRoll() + s = FreeCAD.Rotation() s.setYawPitchRoll(*a) self.assertAlmostEqual(a[0], 0.0) self.assertAlmostEqual(a[1], -90.0) @@ -382,20 +387,20 @@ class AlgebraTestCase(unittest.TestCase): plm = FreeCAD.Placement() rot.Matrix = FreeCAD.Matrix(1, 1, 0, 0, 1, 0, 0, 0, 1) - def testYawPitchRoll(self): def getYPR1(yaw, pitch, roll): r = FreeCAD.Rotation() r.setYawPitchRoll(yaw, pitch, roll) return r + def getYPR2(yaw, pitch, roll): rx = FreeCAD.Rotation() ry = FreeCAD.Rotation() rz = FreeCAD.Rotation() - rx.Axis = FreeCAD.Vector(1,0,0) - ry.Axis = FreeCAD.Vector(0,1,0) - rz.Axis = FreeCAD.Vector(0,0,1) + rx.Axis = FreeCAD.Vector(1, 0, 0) + ry.Axis = FreeCAD.Vector(0, 1, 0) + rz.Axis = FreeCAD.Vector(0, 0, 1) rx.Angle = math.radians(roll) ry.Angle = math.radians(pitch) @@ -404,9 +409,9 @@ class AlgebraTestCase(unittest.TestCase): return rz.multiply(ry).multiply(rx) angles = [] - angles.append((10,10,10)) - angles.append((13,45,-24)) - angles.append((10,-90,20)) + angles.append((10, 10, 10)) + angles.append((13, 45, -24)) + angles.append((10, -90, 20)) for i in angles: r = getYPR1(*i) @@ -414,21 +419,31 @@ class AlgebraTestCase(unittest.TestCase): self.assertTrue(r.isSame(s, 1e-12)) def testBounding(self): - b=FreeCAD.BoundBox() + b = FreeCAD.BoundBox() b.setVoid() - self.assertFalse(b.isValid(),"Bbox is not invalid") - b.add(0,0,0) + self.assertFalse(b.isValid(), "Bbox is not invalid") + b.add(0, 0, 0) self.assertTrue(b.isValid(), "Bbox is invalid") self.assertEqual(b.XLength, 0, "X length > 0") self.assertEqual(b.YLength, 0, "Y length > 0") self.assertEqual(b.ZLength, 0, "Z length > 0") - self.assertEqual(b.Center, FreeCAD.Vector(0,0,0), "Center is not at (0,0,0)") + self.assertEqual(b.Center, FreeCAD.Vector(0, 0, 0), "Center is not at (0,0,0)") self.assertTrue(b.isInside(b.Center), "Center is not inside Bbox") - b.add(2,2,2) - self.assertTrue(b.isInside(b.getIntersectionPoint(b.Center,FreeCAD.Vector(0,1,0))),"Intersection point is not inside Bbox") - self.assertTrue(b.intersect(b),"Bbox doesn't intersect with itself") - self.assertFalse(b.intersected(FreeCAD.BoundBox(4,4,4,6,6,6)).isValid(),"Bbox should not intersect with Bbox outside") - self.assertEqual(b.intersected(FreeCAD.BoundBox(-2,-2,-2,2,2,2)).Center, b.Center,"Bbox is not a full subset") + b.add(2, 2, 2) + self.assertTrue( + b.isInside(b.getIntersectionPoint(b.Center, FreeCAD.Vector(0, 1, 0))), + "Intersection point is not inside Bbox", + ) + self.assertTrue(b.intersect(b), "Bbox doesn't intersect with itself") + self.assertFalse( + b.intersected(FreeCAD.BoundBox(4, 4, 4, 6, 6, 6)).isValid(), + "Bbox should not intersect with Bbox outside", + ) + self.assertEqual( + b.intersected(FreeCAD.BoundBox(-2, -2, -2, 2, 2, 2)).Center, + b.Center, + "Bbox is not a full subset", + ) def testMultLeftOrRight(self): doc = FreeCAD.newDocument() @@ -451,12 +466,13 @@ class AlgebraTestCase(unittest.TestCase): FreeCAD.closeDocument(doc.Name) + class MatrixTestCase(unittest.TestCase): def setUp(self): self.mat = FreeCAD.Matrix() def testOrder(self): - self.mat = FreeCAD.Matrix(1.0,2.0,3.0,4.0) + self.mat = FreeCAD.Matrix(1.0, 2.0, 3.0, 4.0) self.assertEqual(self.mat.A11, 1.0) self.assertEqual(self.mat.A12, 2.0) self.assertEqual(self.mat.A13, 3.0) @@ -507,18 +523,20 @@ class MatrixTestCase(unittest.TestCase): def testMatrixPlacementMatrix(self): # Example taken from https://forum.freecad.org/viewtopic.php?f=3&t=61000 - mat = FreeCAD.Matrix(-0.470847778020266, - 0.8150598976807029, - 0.3376088628746235, - -11.25290913640202, - -0.8822144756796808, - -0.4350066260577338, - -0.180185641360483, - -2876.45492562325, - 1.955470978815492e-9, - -0.3826834326750831, - 0.923879538425552, - 941.3822018176414) + mat = FreeCAD.Matrix( + -0.470847778020266, + 0.8150598976807029, + 0.3376088628746235, + -11.25290913640202, + -0.8822144756796808, + -0.4350066260577338, + -0.180185641360483, + -2876.45492562325, + 1.955470978815492e-9, + -0.3826834326750831, + 0.923879538425552, + 941.3822018176414, + ) plm = FreeCAD.Placement(mat) mat = plm.toMatrix() self.assertEqual(mat.hasScale(), FreeCAD.ScaleType.NoScaling) @@ -528,60 +546,60 @@ class MatrixTestCase(unittest.TestCase): self.mat * "string" def testUnity(self): - mat = FreeCAD.Matrix(2,0,0,0, 0,1,0,0, 0,0,2,0, 0,0,0,-1) + mat = FreeCAD.Matrix(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, -1) self.assertFalse(mat.isUnity()) mat.unity() self.assertTrue(mat.isUnity()) def testPower(self): - mat = FreeCAD.Matrix(2,0,0,0, 0,1,0,0, 0,0,2,0, 0,0,0,-1) + mat = FreeCAD.Matrix(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, -1) with self.assertRaises(NotImplementedError): mat ** "string" - mat2 = mat ** 0 + mat2 = mat**0 self.assertTrue(mat2.isUnity()) - self.assertEqual(mat ** -1, mat.inverse()) - self.assertEqual(mat ** 1, mat) - self.assertEqual(mat ** 2, mat * mat) - self.assertEqual(mat ** 3, mat * mat * mat) + self.assertEqual(mat**-1, mat.inverse()) + self.assertEqual(mat**1, mat) + self.assertEqual(mat**2, mat * mat) + self.assertEqual(mat**3, mat * mat * mat) mat.nullify() with self.assertRaises(RuntimeError): - mat ** -1 + mat**-1 def testScale(self): - self.mat.scale(1., 2., 3.) + self.mat.scale(1.0, 2.0, 3.0) self.assertEqual(self.mat.determinant(), 6.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.NonUniformLeft) self.mat.unity() self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.NoScaling) - self.mat.scale(2., 2., 2.) + self.mat.scale(2.0, 2.0, 2.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Uniform) self.mat.rotateX(1.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Uniform) - self.mat.scale(1., 2., 3.) + self.mat.scale(1.0, 2.0, 3.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.NonUniformLeft) self.mat.unity() - self.mat.scale(1., 2., 3.) + self.mat.scale(1.0, 2.0, 3.0) self.mat.rotateX(1.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.NonUniformRight) self.mat.unity() - self.mat.setCol(0, FreeCAD.Vector(1,2,3)) - self.mat.setCol(1, FreeCAD.Vector(1,2,3)) - self.mat.setCol(2, FreeCAD.Vector(1,2,3)) + self.mat.setCol(0, FreeCAD.Vector(1, 2, 3)) + self.mat.setCol(1, FreeCAD.Vector(1, 2, 3)) + self.mat.setCol(2, FreeCAD.Vector(1, 2, 3)) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Other) self.mat.unity() - self.mat.setRow(0, FreeCAD.Vector(1,2,3)) - self.mat.setRow(1, FreeCAD.Vector(1,2,3)) - self.mat.setRow(2, FreeCAD.Vector(1,2,3)) + self.mat.setRow(0, FreeCAD.Vector(1, 2, 3)) + self.mat.setRow(1, FreeCAD.Vector(1, 2, 3)) + self.mat.setRow(2, FreeCAD.Vector(1, 2, 3)) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Other) self.mat.unity() - self.mat.scale(-1.) + self.mat.scale(-1.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Uniform) - self.mat.scale(-2.) + self.mat.scale(-2.0) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Uniform) def testShearing(self): - self.mat.setRow(1, FreeCAD.Vector(0,1,1)) + self.mat.setRow(1, FreeCAD.Vector(0, 1, 1)) self.assertEqual(self.mat.hasScale(), FreeCAD.ScaleType.Other) def testMultLeftOrRight(self): @@ -589,7 +607,7 @@ class MatrixTestCase(unittest.TestCase): mat1.rotateX(1.0) mat2 = FreeCAD.Matrix() - mat2.scale(1., 2., 3.) + mat2.scale(1.0, 2.0, 3.0) self.assertEqual((mat1 * mat2).hasScale(), FreeCAD.ScaleType.NonUniformRight) self.assertEqual((mat2 * mat1).hasScale(), FreeCAD.ScaleType.NonUniformLeft) @@ -612,12 +630,12 @@ class MatrixTestCase(unittest.TestCase): self.mat.row("string") self.assertEqual(type(self.mat.col(0)), FreeCAD.Vector) self.assertEqual(type(self.mat.row(0)), FreeCAD.Vector) - self.mat.setCol(0, FreeCAD.Vector(1,0,0)) - self.mat.setRow(0, FreeCAD.Vector(1,0,0)) + self.mat.setCol(0, FreeCAD.Vector(1, 0, 0)) + self.mat.setRow(0, FreeCAD.Vector(1, 0, 0)) def testTrace(self): - self.mat.scale(2., 2., 2.) - self.assertEqual(self.mat.trace(), FreeCAD.Vector(2., 2., 2.)) + self.mat.scale(2.0, 2.0, 2.0) + self.assertEqual(self.mat.trace(), FreeCAD.Vector(2.0, 2.0, 2.0)) def testNumberProtocol(self): with self.assertRaises(NotImplementedError): diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index 3bfe503281..4fe36310b7 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -1,396 +1,420 @@ -#*************************************************************************** -#* Copyright (c) 2003 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2003 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ import FreeCAD, os, unittest, tempfile import math -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD Document code -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- class DocumentBasicCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("CreateTest") + def setUp(self): + self.Doc = FreeCAD.newDocument("CreateTest") - def testAccessByNameOrID(self): - obj = self.Doc.addObject("App::DocumentObject", "MyName") + def testAccessByNameOrID(self): + obj = self.Doc.addObject("App::DocumentObject", "MyName") - with self.assertRaises(TypeError): - self.Doc.getObject([1]) + with self.assertRaises(TypeError): + self.Doc.getObject([1]) - self.assertEqual(self.Doc.getObject(obj.Name), obj) - self.assertEqual(self.Doc.getObject("Unknown"), None) - self.assertEqual(self.Doc.getObject(obj.ID), obj) - self.assertEqual(self.Doc.getObject(obj.ID+1), None) + self.assertEqual(self.Doc.getObject(obj.Name), obj) + self.assertEqual(self.Doc.getObject("Unknown"), None) + self.assertEqual(self.Doc.getObject(obj.ID), obj) + self.assertEqual(self.Doc.getObject(obj.ID + 1), None) - def testCreateDestroy(self): - #FIXME: Causes somehow a ref count error but it's _not_ FreeCAD.getDocument()!!! - #If we remove the whole method no error appears. - self.failUnless(FreeCAD.getDocument("CreateTest") is not None,"Creating Document failed") + def testCreateDestroy(self): + # FIXME: Causes somehow a ref count error but it's _not_ FreeCAD.getDocument()!!! + # If we remove the whole method no error appears. + self.failUnless(FreeCAD.getDocument("CreateTest") is not None, "Creating Document failed") - def testAddition(self): - # Cannot write a real test case for that but when debugging the - # C-code there shouldn't be a memory leak (see rev. 1814) - self.Doc.openTransaction("Add") - L1 = self.Doc.addObject("App::FeatureTest","Label") - self.Doc.commitTransaction() - self.Doc.undo() + def testAddition(self): + # Cannot write a real test case for that but when debugging the + # C-code there shouldn't be a memory leak (see rev. 1814) + self.Doc.openTransaction("Add") + L1 = self.Doc.addObject("App::FeatureTest", "Label") + self.Doc.commitTransaction() + self.Doc.undo() - def testAddRemoveUndo(self): - # Bug #0000525 - self.Doc.openTransaction("Add") - obj=self.Doc.addObject("App::FeatureTest","Label") - self.Doc.commitTransaction() - self.Doc.removeObject(obj.Name) - self.Doc.undo() - self.Doc.undo() + def testAddRemoveUndo(self): + # Bug #0000525 + self.Doc.openTransaction("Add") + obj = self.Doc.addObject("App::FeatureTest", "Label") + self.Doc.commitTransaction() + self.Doc.removeObject(obj.Name) + self.Doc.undo() + self.Doc.undo() - def testNoRecompute(self): - L1 = self.Doc.addObject("App::FeatureTest","Label") - self.Doc.recompute() - L1.TypeNoRecompute = 2 - execcount = L1.ExecCount - objectcount = self.Doc.recompute() - self.assertEqual(objectcount, 0) - self.assertEqual(L1.ExecCount, execcount) + def testNoRecompute(self): + L1 = self.Doc.addObject("App::FeatureTest", "Label") + self.Doc.recompute() + L1.TypeNoRecompute = 2 + execcount = L1.ExecCount + objectcount = self.Doc.recompute() + self.assertEqual(objectcount, 0) + self.assertEqual(L1.ExecCount, execcount) - def testNoRecomputeParent(self): - L1 = self.Doc.addObject("App::FeatureTest","Child") - L2 = self.Doc.addObject("App::FeatureTest","Parent") - L2.Source1 = L1 - self.Doc.recompute() - L1.TypeNoRecompute = 2 - countChild = L1.ExecCount - countParent = L2.ExecCount - objectcount = self.Doc.recompute() - self.assertEqual(objectcount, 1) - self.assertEqual(L1.ExecCount, countChild) - self.assertEqual(L2.ExecCount, countParent+1) + def testNoRecomputeParent(self): + L1 = self.Doc.addObject("App::FeatureTest", "Child") + L2 = self.Doc.addObject("App::FeatureTest", "Parent") + L2.Source1 = L1 + self.Doc.recompute() + L1.TypeNoRecompute = 2 + countChild = L1.ExecCount + countParent = L2.ExecCount + objectcount = self.Doc.recompute() + self.assertEqual(objectcount, 1) + self.assertEqual(L1.ExecCount, countChild) + self.assertEqual(L2.ExecCount, countParent + 1) - L1.touch('') - countChild = L1.ExecCount - countParent = L2.ExecCount - objectcount = self.Doc.recompute() - self.assertEqual(objectcount, 1) - self.assertEqual(L1.ExecCount, countChild) - self.assertEqual(L2.ExecCount, countParent+1) + L1.touch("") + countChild = L1.ExecCount + countParent = L2.ExecCount + objectcount = self.Doc.recompute() + self.assertEqual(objectcount, 1) + self.assertEqual(L1.ExecCount, countChild) + self.assertEqual(L2.ExecCount, countParent + 1) - L1.enforceRecompute() - countChild = L1.ExecCount - countParent = L2.ExecCount - objectcount = self.Doc.recompute() - self.assertEqual(objectcount, 2) - self.assertEqual(L1.ExecCount, countChild+1) - self.assertEqual(L2.ExecCount, countParent+1) + L1.enforceRecompute() + countChild = L1.ExecCount + countParent = L2.ExecCount + objectcount = self.Doc.recompute() + self.assertEqual(objectcount, 2) + self.assertEqual(L1.ExecCount, countChild + 1) + self.assertEqual(L2.ExecCount, countParent + 1) - def testAbortTransaction(self): - self.Doc.openTransaction("Add") - obj=self.Doc.addObject("App::FeatureTest","Label") - self.Doc.abortTransaction() - TempPath = tempfile.gettempdir() - SaveName = TempPath + os.sep + "SaveRestoreTests.FCStd" - self.Doc.saveAs(SaveName) + def testAbortTransaction(self): + self.Doc.openTransaction("Add") + obj = self.Doc.addObject("App::FeatureTest", "Label") + self.Doc.abortTransaction() + TempPath = tempfile.gettempdir() + SaveName = TempPath + os.sep + "SaveRestoreTests.FCStd" + self.Doc.saveAs(SaveName) - def testRemoval(self): - # Cannot write a real test case for that but when debugging the - # C-code there shouldn't be a memory leak (see rev. 1814) - self.Doc.openTransaction("Add") - L1 = self.Doc.addObject("App::FeatureTest","Label") - self.Doc.commitTransaction() - self.Doc.openTransaction("Rem") - L1 = self.Doc.removeObject("Label") - self.Doc.commitTransaction() + def testRemoval(self): + # Cannot write a real test case for that but when debugging the + # C-code there shouldn't be a memory leak (see rev. 1814) + self.Doc.openTransaction("Add") + L1 = self.Doc.addObject("App::FeatureTest", "Label") + self.Doc.commitTransaction() + self.Doc.openTransaction("Rem") + L1 = self.Doc.removeObject("Label") + self.Doc.commitTransaction() - def testObjects(self): - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - #call members to check for errors in ref counting - self.Doc.ActiveObject - self.Doc.Objects - self.Doc.UndoMode - self.Doc.UndoRedoMemSize - self.Doc.UndoCount - # test read only mechanismus - try: - self.Doc.UndoCount = 3 - except Exception: - FreeCAD.Console.PrintLog(" exception thrown, OK\n") - else: - self.fail("no exception thrown") - self.Doc.RedoCount - self.Doc.UndoNames - self.Doc.RedoNames - self.Doc.recompute() - self.failUnless(L1.Integer == 4711) - self.failUnless(L1.Float-47.11<0.001) - self.failUnless(L1.Bool == True) - self.failUnless(L1.String == "4711") - #temporarily not checked because of strange behavior of boost::filesystem JR - #self.failUnless(L1.Path == "c:/temp") - self.failUnless(float(L1.Angle)-3.0<0.001) - self.failUnless(float(L1.Distance)-47.11<0.001) + def testObjects(self): + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + # call members to check for errors in ref counting + self.Doc.ActiveObject + self.Doc.Objects + self.Doc.UndoMode + self.Doc.UndoRedoMemSize + self.Doc.UndoCount + # test read only mechanismus + try: + self.Doc.UndoCount = 3 + except Exception: + FreeCAD.Console.PrintLog(" exception thrown, OK\n") + else: + self.fail("no exception thrown") + self.Doc.RedoCount + self.Doc.UndoNames + self.Doc.RedoNames + self.Doc.recompute() + self.failUnless(L1.Integer == 4711) + self.failUnless(L1.Float - 47.11 < 0.001) + self.failUnless(L1.Bool == True) + self.failUnless(L1.String == "4711") + # temporarily not checked because of strange behavior of boost::filesystem JR + # self.failUnless(L1.Path == "c:/temp") + self.failUnless(float(L1.Angle) - 3.0 < 0.001) + self.failUnless(float(L1.Distance) - 47.11 < 0.001) - # test basic property stuff - self.failUnless(not L1.getDocumentationOfProperty("Source1") == "") - self.failUnless(L1.getGroupOfProperty("Source1") == "Feature Test") - self.failUnless(L1.getTypeOfProperty("Source1") == []) - self.failUnless(L1.getEnumerationsOfProperty("Source1") is None) + # test basic property stuff + self.failUnless(not L1.getDocumentationOfProperty("Source1") == "") + self.failUnless(L1.getGroupOfProperty("Source1") == "Feature Test") + self.failUnless(L1.getTypeOfProperty("Source1") == []) + self.failUnless(L1.getEnumerationsOfProperty("Source1") is None) + # test the constraint types ( both are constraint to percent range) + self.failUnless(L1.ConstraintInt == 5) + self.failUnless(L1.ConstraintFloat - 5.0 < 0.001) + L1.ConstraintInt = 500 + L1.ConstraintFloat = 500.0 + self.failUnless(L1.ConstraintInt == 100) + self.failUnless(L1.ConstraintFloat - 100.0 < 0.001) + L1.ConstraintInt = -500 + L1.ConstraintFloat = -500.0 + self.failUnless(L1.ConstraintInt == 0) + self.failUnless(L1.ConstraintFloat - 0.0 < 0.001) - # test the constraint types ( both are constraint to percent range) - self.failUnless(L1.ConstraintInt == 5) - self.failUnless(L1.ConstraintFloat-5.0<0.001) - L1.ConstraintInt = 500 - L1.ConstraintFloat = 500.0 - self.failUnless(L1.ConstraintInt == 100) - self.failUnless(L1.ConstraintFloat - 100.0 < 0.001) - L1.ConstraintInt = -500 - L1.ConstraintFloat = -500.0 - self.failUnless(L1.ConstraintInt == 0) - self.failUnless(L1.ConstraintFloat - 0.0 < 0.001) + # test enum property + # in App::FeatureTest the current value is set to 4 + self.failUnless(L1.Enum == "Four") + L1.Enum = "Three" + self.failUnless(L1.Enum == "Three", "Different value to 'Three'") + L1.Enum = 2 + self.failUnless(L1.Enum == "Two", "Different value to 'Two'") + try: + L1.Enum = "SurelyNotInThere!" + except Exception: + FreeCAD.Console.PrintLog(" exception thrown, OK\n") + else: + self.fail("no exception thrown") + self.failUnless( + sorted(L1.getEnumerationsOfProperty("Enum")) + == sorted(["Zero", "One", "Two", "Three", "Four"]) + ) - # test enum property - # in App::FeatureTest the current value is set to 4 - self.failUnless(L1.Enum == "Four") - L1.Enum = "Three" - self.failUnless(L1.Enum == "Three", "Different value to 'Three'") - L1.Enum = 2 - self.failUnless(L1.Enum == "Two", "Different value to 'Two'") - try: - L1.Enum = "SurelyNotInThere!" - except Exception: - FreeCAD.Console.PrintLog(" exception thrown, OK\n") - else: - self.fail("no exception thrown") - self.failUnless(sorted(L1.getEnumerationsOfProperty('Enum')) == sorted(['Zero', 'One', 'Two', 'Three', 'Four'])) + # self.failUnless(L1.IntegerList == [4711] ) + # f = L1.FloatList + # self.failUnless(f -47.11<0.001 ) + # self.failUnless(L1.Matrix == [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0] ) + # self.failUnless(L1.Vector == [1.0,2.0,3.0]) - #self.failUnless(L1.IntegerList == [4711] ) - #f = L1.FloatList - #self.failUnless(f -47.11<0.001 ) - #self.failUnless(L1.Matrix == [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0] ) - #self.failUnless(L1.Vector == [1.0,2.0,3.0]) + self.failUnless(L1.Label == "Label_1", "Invalid object name") + L1.Label = "Label_2" + self.Doc.recompute() + self.failUnless(L1.Label == "Label_2", "Invalid object name") + self.Doc.removeObject("Label_1") - self.failUnless(L1.Label== "Label_1","Invalid object name") - L1.Label="Label_2" - self.Doc.recompute() - self.failUnless(L1.Label== "Label_2","Invalid object name") - self.Doc.removeObject("Label_1") + def testEnum(self): + enumeration_choices = ["one", "two"] + obj = self.Doc.addObject("App::FeaturePython", "Label_2") + obj.addProperty("App::PropertyEnumeration", "myEnumeration", "Enum", "mytest") + with self.assertRaises(ValueError): + obj.myEnumeration = enumeration_choices[0] - def testEnum(self): - enumeration_choices = ["one", "two"] - obj = self.Doc.addObject("App::FeaturePython","Label_2") - obj.addProperty("App::PropertyEnumeration", "myEnumeration", "Enum", "mytest") - with self.assertRaises(ValueError): - obj.myEnumeration = enumeration_choices[0] + obj.myEnumeration = enumeration_choices + obj.myEnumeration = 0 + self.Doc.openTransaction("Modify enum") + obj.myEnumeration = 1 + self.assertTrue(obj.myEnumeration, enumeration_choices[1]) + self.Doc.commitTransaction() + self.Doc.undo() + self.assertTrue(obj.myEnumeration, enumeration_choices[0]) - obj.myEnumeration = enumeration_choices - obj.myEnumeration = 0 - self.Doc.openTransaction("Modify enum") - obj.myEnumeration = 1 - self.assertTrue(obj.myEnumeration, enumeration_choices[1]) - self.Doc.commitTransaction() - self.Doc.undo() - self.assertTrue(obj.myEnumeration, enumeration_choices[0]) + def testWrongTypes(self): + with self.assertRaises(TypeError): + self.Doc.addObject("App::DocumentObjectExtension") - def testWrongTypes(self): - with self.assertRaises(TypeError): - self.Doc.addObject("App::DocumentObjectExtension") + class Feature: + pass - class Feature: - pass - with self.assertRaises(TypeError): - self.Doc.addObject(type="App::DocumentObjectExtension", objProxy=Feature(), attach=True) + with self.assertRaises(TypeError): + self.Doc.addObject(type="App::DocumentObjectExtension", objProxy=Feature(), attach=True) - ext = FreeCAD.Base.TypeId.fromName("App::DocumentObjectExtension") - self.assertEqual(ext.createInstance(), None) + ext = FreeCAD.Base.TypeId.fromName("App::DocumentObjectExtension") + self.assertEqual(ext.createInstance(), None) - obj = self.Doc.addObject("App::FeaturePython", "Object") - with self.assertRaises(TypeError): - obj.addProperty("App::DocumentObjectExtension", "Property") + obj = self.Doc.addObject("App::FeaturePython", "Object") + with self.assertRaises(TypeError): + obj.addProperty("App::DocumentObjectExtension", "Property") - with self.assertRaises(TypeError): - self.Doc.findObjects(Type="App::DocumentObjectExtension") + with self.assertRaises(TypeError): + self.Doc.findObjects(Type="App::DocumentObjectExtension") - e = FreeCAD.Base.TypeId.fromName("App::LinkExtensionPython") - self.assertIsNone(e.createInstance()) + e = FreeCAD.Base.TypeId.fromName("App::LinkExtensionPython") + self.assertIsNone(e.createInstance()) - if FreeCAD.GuiUp: - obj = self.Doc.addObject("App::DocumentObject", viewType="App::Extension") - self.assertIsNone(obj.ViewObject) + if FreeCAD.GuiUp: + obj = self.Doc.addObject("App::DocumentObject", viewType="App::Extension") + self.assertIsNone(obj.ViewObject) - def testMem(self): - self.Doc.MemSize + def testMem(self): + self.Doc.MemSize - def testDuplicateLinks(self): - obj = self.Doc.addObject("App::FeatureTest","obj") - grp = self.Doc.addObject("App::DocumentObjectGroup","group") - grp.Group = [obj,obj] - self.Doc.removeObject(obj.Name) - self.assertListEqual(grp.Group, []) + def testDuplicateLinks(self): + obj = self.Doc.addObject("App::FeatureTest", "obj") + grp = self.Doc.addObject("App::DocumentObjectGroup", "group") + grp.Group = [obj, obj] + self.Doc.removeObject(obj.Name) + self.assertListEqual(grp.Group, []) - def testPlacementList(self): - obj = self.Doc.addObject("App::FeaturePython","Label") - obj.addProperty("App::PropertyPlacementList", "PlmList") - plm = FreeCAD.Placement() - plm.Base = (1,2,3) - plm.Rotation = (0,0,1,0) - obj.PlmList = [plm] - cpy = self.Doc.copyObject(obj) - self.assertListEqual(obj.PlmList, cpy.PlmList) + def testPlacementList(self): + obj = self.Doc.addObject("App::FeaturePython", "Label") + obj.addProperty("App::PropertyPlacementList", "PlmList") + plm = FreeCAD.Placement() + plm.Base = (1, 2, 3) + plm.Rotation = (0, 0, 1, 0) + obj.PlmList = [plm] + cpy = self.Doc.copyObject(obj) + self.assertListEqual(obj.PlmList, cpy.PlmList) - def testRawAxis(self): - obj = self.Doc.addObject("App::FeaturePython","Label") - obj.addProperty("App::PropertyPlacement", "Plm") - obj.addProperty("App::PropertyRotation", "Rot") - obj.Plm.Rotation.Axis = (1,2,3) - obj.Rot.Axis = (3,2,1) + def testRawAxis(self): + obj = self.Doc.addObject("App::FeaturePython", "Label") + obj.addProperty("App::PropertyPlacement", "Plm") + obj.addProperty("App::PropertyRotation", "Rot") + obj.Plm.Rotation.Axis = (1, 2, 3) + obj.Rot.Axis = (3, 2, 1) - # saving and restoring - SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument("CreateTest") - self.Doc = FreeCAD.open(SaveName) - obj = self.Doc.ActiveObject + # saving and restoring + SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument("CreateTest") + self.Doc = FreeCAD.open(SaveName) + obj = self.Doc.ActiveObject - self.assertEqual(obj.Plm.Rotation.RawAxis.x, 1) - self.assertEqual(obj.Plm.Rotation.RawAxis.y, 2) - self.assertEqual(obj.Plm.Rotation.RawAxis.z, 3) + self.assertEqual(obj.Plm.Rotation.RawAxis.x, 1) + self.assertEqual(obj.Plm.Rotation.RawAxis.y, 2) + self.assertEqual(obj.Plm.Rotation.RawAxis.z, 3) - self.assertEqual(obj.Rot.RawAxis.x, 3) - self.assertEqual(obj.Rot.RawAxis.y, 2) - self.assertEqual(obj.Rot.RawAxis.z, 1) + self.assertEqual(obj.Rot.RawAxis.x, 3) + self.assertEqual(obj.Rot.RawAxis.y, 2) + self.assertEqual(obj.Rot.RawAxis.z, 1) - def testAddRemove(self): - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - # must delete object - self.Doc.removeObject(L1.Name) - try: - L1.Name - except Exception: - self.failUnless(True) - else: - self.failUnless(False) - del L1 + def testAddRemove(self): + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + # must delete object + self.Doc.removeObject(L1.Name) + try: + L1.Name + except Exception: + self.failUnless(True) + else: + self.failUnless(False) + del L1 - # What do we expect here? - self.Doc.openTransaction("AddRemove") - L2 = self.Doc.addObject("App::FeatureTest","Label_2") - self.Doc.removeObject(L2.Name) - self.Doc.commitTransaction() - self.Doc.undo() - try: - L2.Name - except Exception: - self.failUnless(True) - else: - self.failUnless(False) - del L2 + # What do we expect here? + self.Doc.openTransaction("AddRemove") + L2 = self.Doc.addObject("App::FeatureTest", "Label_2") + self.Doc.removeObject(L2.Name) + self.Doc.commitTransaction() + self.Doc.undo() + try: + L2.Name + except Exception: + self.failUnless(True) + else: + self.failUnless(False) + del L2 - def testSubObject(self): - obj = self.Doc.addObject("App::Origin", "Origin") - self.Doc.recompute() + def testSubObject(self): + obj = self.Doc.addObject("App::Origin", "Origin") + self.Doc.recompute() - res = obj.getSubObject("X_Axis", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(1,0,0)).getAngle(FreeCAD.Vector(1,0,0)), 0.0) + res = obj.getSubObject("X_Axis", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0 + ) - res = obj.getSubObject("Y_Axis", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(1,0,0)).getAngle(FreeCAD.Vector(0,1,0)), 0.0) + res = obj.getSubObject("Y_Axis", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(0, 1, 0)), 0.0 + ) - res = obj.getSubObject("Z_Axis", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(1,0,0)).getAngle(FreeCAD.Vector(0,0,1)), 0.0) + res = obj.getSubObject("Z_Axis", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(0, 0, 1)), 0.0 + ) - res = obj.getSubObject("XY_Plane", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(0,0,1)).getAngle(FreeCAD.Vector(0,0,1)), 0.0) + res = obj.getSubObject("XY_Plane", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(0, 0, 1)), 0.0 + ) - res = obj.getSubObject("XZ_Plane", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(0,0,1)).getAngle(FreeCAD.Vector(0,-1,0)), 0.0) + res = obj.getSubObject("XZ_Plane", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(0, -1, 0)), 0.0 + ) - res = obj.getSubObject("YZ_Plane", retType=2) - self.assertEqual(res[1].multVec(FreeCAD.Vector(0,0,1)).getAngle(FreeCAD.Vector(1,0,0)), 0.0) + res = obj.getSubObject("YZ_Plane", retType=2) + self.assertEqual( + res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0 + ) - res = obj.getSubObject("YZ_Plane", retType=3) - self.assertEqual(res.multVec(FreeCAD.Vector(0,0,1)).getAngle(FreeCAD.Vector(1,0,0)), 0.0) + res = obj.getSubObject("YZ_Plane", retType=3) + self.assertEqual( + res.multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0 + ) - res = obj.getSubObject("YZ_Plane", retType=4) - self.assertEqual(res.multVec(FreeCAD.Vector(0,0,1)).getAngle(FreeCAD.Vector(1,0,0)), 0.0) + res = obj.getSubObject("YZ_Plane", retType=4) + self.assertEqual( + res.multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0 + ) - self.assertEqual(obj.getSubObject(("XY_Plane", "YZ_Plane"), retType=4)[0], obj.getSubObject("XY_Plane", retType=4)) - self.assertEqual(obj.getSubObject(("XY_Plane", "YZ_Plane"), retType=4)[1], obj.getSubObject("YZ_Plane", retType=4)) + self.assertEqual( + obj.getSubObject(("XY_Plane", "YZ_Plane"), retType=4)[0], + obj.getSubObject("XY_Plane", retType=4), + ) + self.assertEqual( + obj.getSubObject(("XY_Plane", "YZ_Plane"), retType=4)[1], + obj.getSubObject("YZ_Plane", retType=4), + ) - # Create a second origin object - obj2 = self.Doc.addObject("App::Origin", "Origin2") - self.Doc.recompute() + # Create a second origin object + obj2 = self.Doc.addObject("App::Origin", "Origin2") + self.Doc.recompute() - # Use the names of the origin's out-list - for i in obj2.OutList: - self.assertEqual(obj2.getSubObject(i.Name, retType=1).Name, i.Name) - # Add a '.' to the names - for i in obj2.OutList: - self.assertEqual(obj2.getSubObject(i.Name + '.', retType=1).Name, i.Name) + # Use the names of the origin's out-list + for i in obj2.OutList: + self.assertEqual(obj2.getSubObject(i.Name, retType=1).Name, i.Name) + # Add a '.' to the names + for i in obj2.OutList: + self.assertEqual(obj2.getSubObject(i.Name + ".", retType=1).Name, i.Name) - def testExtensions(self): - #we try to create a normal python object and add an extension to it - obj = self.Doc.addObject("App::DocumentObject", "Extension_1") - grp = self.Doc.addObject("App::DocumentObject", "Extension_2") - #we should have all methods we need to handle extensions - try: - self.failUnless(not grp.hasExtension("App::GroupExtensionPython")) - grp.addExtension("App::GroupExtensionPython") - self.failUnless(grp.hasExtension("App::GroupExtension")) - self.failUnless(grp.hasExtension("App::GroupExtensionPython")) - grp.addObject(obj) - self.failUnless(len(grp.Group) == 1) - self.failUnless(grp.Group[0] == obj) - except Exception: - self.failUnless(False) + def testExtensions(self): + # we try to create a normal python object and add an extension to it + obj = self.Doc.addObject("App::DocumentObject", "Extension_1") + grp = self.Doc.addObject("App::DocumentObject", "Extension_2") + # we should have all methods we need to handle extensions + try: + self.failUnless(not grp.hasExtension("App::GroupExtensionPython")) + grp.addExtension("App::GroupExtensionPython") + self.failUnless(grp.hasExtension("App::GroupExtension")) + self.failUnless(grp.hasExtension("App::GroupExtensionPython")) + grp.addObject(obj) + self.failUnless(len(grp.Group) == 1) + self.failUnless(grp.Group[0] == obj) + except Exception: + self.failUnless(False) - #test if the method override works - class SpecialGroup(): - def allowObject(self, obj): - return False; + # test if the method override works + class SpecialGroup: + def allowObject(self, obj): + return False - callback = SpecialGroup() - grp2 = self.Doc.addObject("App::FeaturePython", "Extension_3") - grp2.addExtension("App::GroupExtensionPython") - grp2.Proxy = callback + callback = SpecialGroup() + grp2 = self.Doc.addObject("App::FeaturePython", "Extension_3") + grp2.addExtension("App::GroupExtensionPython") + grp2.Proxy = callback - try: - self.failUnless(grp2.hasExtension("App::GroupExtension")) - grp2.addObject(obj) - self.failUnless(len(grp2.Group) == 0) - except Exception: - self.failUnless(True) + try: + self.failUnless(grp2.hasExtension("App::GroupExtension")) + grp2.addObject(obj) + self.failUnless(len(grp2.Group) == 0) + except Exception: + self.failUnless(True) - self.Doc.removeObject(grp.Name) - self.Doc.removeObject(grp2.Name) - self.Doc.removeObject(obj.Name) - del obj - del grp - del grp2 + self.Doc.removeObject(grp.Name) + self.Doc.removeObject(grp2.Name) + self.Doc.removeObject(obj.Name) + del obj + del grp + del grp2 - def testExtensionBug0002785(self): - - class MyExtension(): + def testExtensionBug0002785(self): + class MyExtension: def __init__(self, obj): obj.addExtension("App::GroupExtensionPython") @@ -401,168 +425,185 @@ class DocumentBasicCases(unittest.TestCase): self.Doc.removeObject(obj.Name) del obj - def testExtensionGroup(self): - obj = self.Doc.addObject("App::DocumentObject", "Obj") - grp = self.Doc.addObject("App::FeaturePython", "Extension_2") - grp.addExtension("App::GroupExtensionPython") - grp.Group = [obj] - self.assertTrue(obj in grp.Group) + def testExtensionGroup(self): + obj = self.Doc.addObject("App::DocumentObject", "Obj") + grp = self.Doc.addObject("App::FeaturePython", "Extension_2") + grp.addExtension("App::GroupExtensionPython") + grp.Group = [obj] + self.assertTrue(obj in grp.Group) - def testExtensionBugViewProvider(self): + def testExtensionBugViewProvider(self): + class Layer: + def __init__(self, obj): + obj.addExtension("App::GroupExtensionPython") - class Layer(): - def __init__(self, obj): - obj.addExtension("App::GroupExtensionPython") + class LayerViewProvider: + def __init__(self, obj): + obj.addExtension("Gui::ViewProviderGroupExtensionPython") + obj.Proxy = self - class LayerViewProvider(): - def __init__(self, obj): - obj.addExtension("Gui::ViewProviderGroupExtensionPython") - obj.Proxy = self + obj = self.Doc.addObject("App::FeaturePython", "Layer") + Layer(obj) + self.failUnless(obj.hasExtension("App::GroupExtension")) - obj = self.Doc.addObject("App::FeaturePython","Layer") - Layer(obj) - self.failUnless(obj.hasExtension("App::GroupExtension")) + if FreeCAD.GuiUp: + LayerViewProvider(obj.ViewObject) + self.failUnless(obj.ViewObject.hasExtension("Gui::ViewProviderGroupExtension")) + self.failUnless(obj.ViewObject.hasExtension("Gui::ViewProviderGroupExtensionPython")) - if FreeCAD.GuiUp: - LayerViewProvider(obj.ViewObject) - self.failUnless(obj.ViewObject.hasExtension("Gui::ViewProviderGroupExtension")) - self.failUnless(obj.ViewObject.hasExtension("Gui::ViewProviderGroupExtensionPython")) + self.Doc.removeObject(obj.Name) + del obj - self.Doc.removeObject(obj.Name) - del obj + def testPropertyLink_Issue2902Part1(self): + o1 = self.Doc.addObject("App::FeatureTest", "test1") + o2 = self.Doc.addObject("App::FeatureTest", "test2") + o3 = self.Doc.addObject("App::FeatureTest", "test3") - def testPropertyLink_Issue2902Part1(self): - o1 = self.Doc.addObject("App::FeatureTest","test1") - o2 = self.Doc.addObject("App::FeatureTest","test2") - o3 = self.Doc.addObject("App::FeatureTest","test3") + o1.Link = o2 + self.assertEqual(o1.Link, o2) + o1.Link = o3 + self.assertEqual(o1.Link, o3) + o2.Placement = FreeCAD.Placement() + self.assertEqual(o1.Link, o3) - o1.Link=o2 - self.assertEqual(o1.Link, o2) - o1.Link=o3 - self.assertEqual(o1.Link, o3) - o2.Placement = FreeCAD.Placement() - self.assertEqual(o1.Link, o3) + def testProp_NonePropertyLink(self): + obj1 = self.Doc.addObject("App::FeaturePython", "Obj1") + obj2 = self.Doc.addObject("App::FeaturePython", "Obj2") + obj1.addProperty( + "App::PropertyLink", + "Link", + "Base", + "Link to another feature", + FreeCAD.PropertyType.Prop_None, + False, + False, + ) + obj1.Link = obj2 + self.assertEqual(obj1.MustExecute, True) - def testProp_NonePropertyLink(self): - obj1 = self.Doc.addObject("App::FeaturePython", "Obj1") - obj2 = self.Doc.addObject("App::FeaturePython", "Obj2") - obj1.addProperty("App::PropertyLink", "Link", "Base", "Link to another feature", FreeCAD.PropertyType.Prop_None, False, False) - obj1.Link = obj2 - self.assertEqual(obj1.MustExecute, True) + def testProp_OutputPropertyLink(self): + obj1 = self.Doc.addObject("App::FeaturePython", "Obj1") + obj2 = self.Doc.addObject("App::FeaturePython", "Obj2") + obj1.addProperty( + "App::PropertyLink", + "Link", + "Base", + "Link to another feature", + FreeCAD.PropertyType.Prop_Output, + False, + False, + ) + obj1.Link = obj2 + self.assertEqual(obj1.MustExecute, False) - def testProp_OutputPropertyLink(self): - obj1 = self.Doc.addObject("App::FeaturePython", "Obj1") - obj2 = self.Doc.addObject("App::FeaturePython", "Obj2") - obj1.addProperty("App::PropertyLink", "Link", "Base", "Link to another feature", FreeCAD.PropertyType.Prop_Output, False, False) - obj1.Link = obj2 - self.assertEqual(obj1.MustExecute, False) + def testAttributeOfDynamicProperty(self): + obj = self.Doc.addObject("App::FeaturePython", "Obj") + # Prop_NoPersist is the enum with the highest value + max_value = FreeCAD.PropertyType.Prop_NoPersist + list_of_types = [] + for i in range(0, max_value + 1): + obj.addProperty("App::PropertyString", "String" + str(i), "", "", i) + list_of_types.append(obj.getTypeOfProperty("String" + str(i))) - def testAttributeOfDynamicProperty(self): - obj = self.Doc.addObject("App::FeaturePython", "Obj") - # Prop_NoPersist is the enum with the highest value - max_value = FreeCAD.PropertyType.Prop_NoPersist - list_of_types = [] - for i in range(0, max_value + 1): - obj.addProperty("App::PropertyString", "String" + str(i), "", "", i) - list_of_types.append(obj.getTypeOfProperty("String" + str(i))) + # saving and restoring + SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument("CreateTest") + self.Doc = FreeCAD.open(SaveName) - # saving and restoring - SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument("CreateTest") - self.Doc = FreeCAD.open(SaveName) + obj = self.Doc.ActiveObject + for i in range(0, max_value): + types = obj.getTypeOfProperty("String" + str(i)) + self.assertEqual(list_of_types[i], types) - obj = self.Doc.ActiveObject - for i in range(0, max_value): - types = obj.getTypeOfProperty("String" + str(i)) - self.assertEqual(list_of_types[i], types) + # A property with flag Prop_NoPersist won't be saved to the file + with self.assertRaises(AttributeError): + obj.getTypeOfProperty("String" + str(max_value)) - # A property with flag Prop_NoPersist won't be saved to the file - with self.assertRaises(AttributeError): - obj.getTypeOfProperty("String" + str(max_value)) + def testNotification_Issue2902Part2(self): + o = self.Doc.addObject("App::FeatureTest", "test") - def testNotification_Issue2902Part2(self): - o = self.Doc.addObject("App::FeatureTest","test") + plm = o.Placement + o.Placement = FreeCAD.Placement() + plm.Base.x = 5 + self.assertEqual(o.Placement.Base.x, 0) + o.Placement.Base.x = 5 + self.assertEqual(o.Placement.Base.x, 5) - plm = o.Placement - o.Placement = FreeCAD.Placement() - plm.Base.x = 5 - self.assertEqual(o.Placement.Base.x, 0) - o.Placement.Base.x=5 - self.assertEqual(o.Placement.Base.x, 5) + def testNotification_Issue2996(self): + if not FreeCAD.GuiUp: + return + # works only if Gui is shown + class ViewProvider: + def __init__(self, vobj): + vobj.Proxy = self - def testNotification_Issue2996(self): - if not FreeCAD.GuiUp: - return - # works only if Gui is shown - class ViewProvider: - def __init__(self, vobj): - vobj.Proxy=self + def attach(self, vobj): + self.ViewObject = vobj + self.Object = vobj.Object - def attach(self, vobj): - self.ViewObject = vobj - self.Object = vobj.Object + def claimChildren(self): + children = [self.Object.Link] + return children - def claimChildren(self): - children = [self.Object.Link] - return children + obj = self.Doc.addObject("App::FeaturePython", "Sketch") + obj.addProperty("App::PropertyLink", "Link") + ViewProvider(obj.ViewObject) - obj=self.Doc.addObject("App::FeaturePython", "Sketch") - obj.addProperty("App::PropertyLink","Link") - ViewProvider(obj.ViewObject) + ext = self.Doc.addObject("App::FeatureTest", "Extrude") + ext.Link = obj - ext=self.Doc.addObject("App::FeatureTest", "Extrude") - ext.Link=obj + sli = self.Doc.addObject("App::FeaturePython", "Slice") + sli.addProperty("App::PropertyLink", "Link").Link = ext + ViewProvider(sli.ViewObject) - sli=self.Doc.addObject("App::FeaturePython", "Slice") - sli.addProperty("App::PropertyLink","Link").Link=ext - ViewProvider(sli.ViewObject) + com = self.Doc.addObject("App::FeaturePython", "CompoundFilter") + com.addProperty("App::PropertyLink", "Link").Link = sli + ViewProvider(com.ViewObject) - com=self.Doc.addObject("App::FeaturePython", "CompoundFilter") - com.addProperty("App::PropertyLink", "Link").Link=sli - ViewProvider(com.ViewObject) + ext.Label = "test" - ext.Label="test" + self.assertEqual(ext.Link, obj) + self.assertNotEqual(ext.Link, sli) - self.assertEqual(ext.Link, obj) - self.assertNotEqual(ext.Link, sli) + def testIssue4823(self): + # https://forum.freecad.org/viewtopic.php?f=3&t=52775 + # The issue was only visible in GUI mode and it crashed in the tree view + obj = self.Doc.addObject("App::Origin") + self.Doc.removeObject(obj.Name) - def testIssue4823(self): - # https://forum.freecad.org/viewtopic.php?f=3&t=52775 - # The issue was only visible in GUI mode and it crashed in the tree view - obj = self.Doc.addObject("App::Origin") - self.Doc.removeObject(obj.Name) + def testSamePropertyOfLinkAndLinkedObject(self): + # See also https://github.com/FreeCAD/FreeCAD/pull/6787 + test = self.Doc.addObject("App::FeaturePython", "Python") + link = self.Doc.addObject("App::Link", "Link") + test.addProperty("App::PropertyFloat", "Test") + link.addProperty("App::PropertyFloat", "Test") + link.LinkedObject = test + # saving and restoring + SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument("CreateTest") + self.Doc = FreeCAD.open(SaveName) + self.assertIn("Test", self.Doc.Python.PropertiesList) + self.assertIn("Test", self.Doc.Link.PropertiesList) - def testSamePropertyOfLinkAndLinkedObject(self): - # See also https://github.com/FreeCAD/FreeCAD/pull/6787 - test = self.Doc.addObject("App::FeaturePython", "Python") - link = self.Doc.addObject("App::Link", "Link") - test.addProperty("App::PropertyFloat", "Test") - link.addProperty("App::PropertyFloat", "Test") - link.LinkedObject = test - # saving and restoring - SaveName = tempfile.gettempdir() + os.sep + "CreateTest.FCStd" - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument("CreateTest") - self.Doc = FreeCAD.open(SaveName) - self.assertIn("Test", self.Doc.Python.PropertiesList) - self.assertIn("Test", self.Doc.Link.PropertiesList) + def tearDown(self): + # closing doc + FreeCAD.closeDocument("CreateTest") - def tearDown(self): - #closing doc - FreeCAD.closeDocument("CreateTest") # class must be defined in global scope to allow it to be reloaded on document open -class SaveRestoreSpecialGroup(): +class SaveRestoreSpecialGroup: def __init__(self, obj): obj.addExtension("App::GroupExtensionPython") obj.Proxy = self def allowObject(self, obj): - return False; + return False + # class must be defined in global scope to allow it to be reloaded on document open -class SaveRestoreSpecialGroupViewProvider(): +class SaveRestoreSpecialGroupViewProvider: def __init__(self, obj): obj.addExtension("Gui::ViewProviderGroupExtensionPython") obj.Proxy = self @@ -570,1609 +611,1678 @@ class SaveRestoreSpecialGroupViewProvider(): def testFunction(self): pass + class DocumentSaveRestoreCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("SaveRestoreTests") - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - L2 = self.Doc.addObject("App::FeatureTest","Label_2") - L3 = self.Doc.addObject("App::FeatureTest","Label_3") - self.TempPath = tempfile.gettempdir() - FreeCAD.Console.PrintLog( ' Using temp path: ' + self.TempPath + '\n') + def setUp(self): + self.Doc = FreeCAD.newDocument("SaveRestoreTests") + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + L2 = self.Doc.addObject("App::FeatureTest", "Label_2") + L3 = self.Doc.addObject("App::FeatureTest", "Label_3") + self.TempPath = tempfile.gettempdir() + FreeCAD.Console.PrintLog(" Using temp path: " + self.TempPath + "\n") - def testSaveAndRestore(self): - # saving and restoring - SaveName = self.TempPath + os.sep + "SaveRestoreTests.FCStd" - self.failUnless(self.Doc.Label_1.TypeTransient == 4711) - self.Doc.Label_1.TypeTransient = 4712 - # setup Linking - self.Doc.Label_1.Link = self.Doc.Label_2 - self.Doc.Label_2.Link = self.Doc.Label_3 - self.Doc.Label_1.LinkSub = (self.Doc.Label_2,["Sub1","Sub2"]) - self.Doc.Label_2.LinkSub = (self.Doc.Label_3,["Sub3","Sub4"]) - # save the document - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument("SaveRestoreTests") - self.Doc = FreeCAD.open(SaveName) - self.failUnless(self.Doc.Label_1.Integer == 4711) - self.failUnless(self.Doc.Label_2.Integer == 4711) - # test Linkage - self.failUnless(self.Doc.Label_1.Link == self.Doc.Label_2) - self.failUnless(self.Doc.Label_2.Link == self.Doc.Label_3) - self.failUnless(self.Doc.Label_1.LinkSub == (self.Doc.Label_2,["Sub1","Sub2"])) - self.failUnless(self.Doc.Label_2.LinkSub == (self.Doc.Label_3,["Sub3","Sub4"])) - # do NOT save transient properties - self.failUnless(self.Doc.Label_1.TypeTransient == 4711) - self.failUnless(self.Doc == FreeCAD.getDocument(self.Doc.Name)) + def testSaveAndRestore(self): + # saving and restoring + SaveName = self.TempPath + os.sep + "SaveRestoreTests.FCStd" + self.failUnless(self.Doc.Label_1.TypeTransient == 4711) + self.Doc.Label_1.TypeTransient = 4712 + # setup Linking + self.Doc.Label_1.Link = self.Doc.Label_2 + self.Doc.Label_2.Link = self.Doc.Label_3 + self.Doc.Label_1.LinkSub = (self.Doc.Label_2, ["Sub1", "Sub2"]) + self.Doc.Label_2.LinkSub = (self.Doc.Label_3, ["Sub3", "Sub4"]) + # save the document + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument("SaveRestoreTests") + self.Doc = FreeCAD.open(SaveName) + self.failUnless(self.Doc.Label_1.Integer == 4711) + self.failUnless(self.Doc.Label_2.Integer == 4711) + # test Linkage + self.failUnless(self.Doc.Label_1.Link == self.Doc.Label_2) + self.failUnless(self.Doc.Label_2.Link == self.Doc.Label_3) + self.failUnless(self.Doc.Label_1.LinkSub == (self.Doc.Label_2, ["Sub1", "Sub2"])) + self.failUnless(self.Doc.Label_2.LinkSub == (self.Doc.Label_3, ["Sub3", "Sub4"])) + # do NOT save transient properties + self.failUnless(self.Doc.Label_1.TypeTransient == 4711) + self.failUnless(self.Doc == FreeCAD.getDocument(self.Doc.Name)) - def testRestore(self): - Doc = FreeCAD.newDocument("RestoreTests") - Doc.addObject("App::FeatureTest","Label_1") - # saving and restoring - FileName = self.TempPath + os.sep + "Test2.FCStd" - Doc.saveAs(FileName) - # restore must first clear the current content - Doc.restore() - self.failUnless(len(Doc.Objects) == 1) - FreeCAD.closeDocument("RestoreTests") + def testRestore(self): + Doc = FreeCAD.newDocument("RestoreTests") + Doc.addObject("App::FeatureTest", "Label_1") + # saving and restoring + FileName = self.TempPath + os.sep + "Test2.FCStd" + Doc.saveAs(FileName) + # restore must first clear the current content + Doc.restore() + self.failUnless(len(Doc.Objects) == 1) + FreeCAD.closeDocument("RestoreTests") - def testActiveDocument(self): - # open 2nd doc - Second = FreeCAD.newDocument("Active") - FreeCAD.closeDocument("Active") - try: - # There might be no active document anymore - # This also checks for dangling pointers - Active = FreeCAD.activeDocument() - # Second is still a valid object - self.failUnless(Second != Active) - except Exception: - # Okay, no document open - self.failUnless(True) + def testActiveDocument(self): + # open 2nd doc + Second = FreeCAD.newDocument("Active") + FreeCAD.closeDocument("Active") + try: + # There might be no active document anymore + # This also checks for dangling pointers + Active = FreeCAD.activeDocument() + # Second is still a valid object + self.failUnless(Second != Active) + except Exception: + # Okay, no document open + self.failUnless(True) - def testExtensionSaveRestore(self): - # saving and restoring - SaveName = self.TempPath + os.sep + "SaveRestoreExtensions.FCStd" - Doc = FreeCAD.newDocument("SaveRestoreExtensions") - #we try to create a normal python object and add an extension to it - obj = Doc.addObject("App::DocumentObject", "Obj") - grp1 = Doc.addObject("App::DocumentObject", "Extension_1") - grp2 = Doc.addObject("App::FeaturePython", "Extension_2") + def testExtensionSaveRestore(self): + # saving and restoring + SaveName = self.TempPath + os.sep + "SaveRestoreExtensions.FCStd" + Doc = FreeCAD.newDocument("SaveRestoreExtensions") + # we try to create a normal python object and add an extension to it + obj = Doc.addObject("App::DocumentObject", "Obj") + grp1 = Doc.addObject("App::DocumentObject", "Extension_1") + grp2 = Doc.addObject("App::FeaturePython", "Extension_2") - grp1.addExtension("App::GroupExtensionPython") - SaveRestoreSpecialGroup(grp2) - if FreeCAD.GuiUp: - SaveRestoreSpecialGroupViewProvider(grp2.ViewObject) - grp2.Group = [obj] + grp1.addExtension("App::GroupExtensionPython") + SaveRestoreSpecialGroup(grp2) + if FreeCAD.GuiUp: + SaveRestoreSpecialGroupViewProvider(grp2.ViewObject) + grp2.Group = [obj] - Doc.saveAs(SaveName) - FreeCAD.closeDocument("SaveRestoreExtensions") - Doc = FreeCAD.open(SaveName) + Doc.saveAs(SaveName) + FreeCAD.closeDocument("SaveRestoreExtensions") + Doc = FreeCAD.open(SaveName) - self.failUnless(Doc.Extension_1.hasExtension("App::GroupExtension")) - self.failUnless(Doc.Extension_2.hasExtension("App::GroupExtension")) - self.failUnless(Doc.Extension_2.Group[0] is Doc.Obj) - self.failUnless(hasattr(Doc.Extension_2.Proxy, 'allowObject')) + self.failUnless(Doc.Extension_1.hasExtension("App::GroupExtension")) + self.failUnless(Doc.Extension_2.hasExtension("App::GroupExtension")) + self.failUnless(Doc.Extension_2.Group[0] is Doc.Obj) + self.failUnless(hasattr(Doc.Extension_2.Proxy, "allowObject")) - if FreeCAD.GuiUp: - self.failUnless(Doc.Extension_2.ViewObject.hasExtension("Gui::ViewProviderGroupExtensionPython")) - self.failUnless(hasattr(Doc.Extension_2.ViewObject.Proxy, 'testFunction')) + if FreeCAD.GuiUp: + self.failUnless( + Doc.Extension_2.ViewObject.hasExtension("Gui::ViewProviderGroupExtensionPython") + ) + self.failUnless(hasattr(Doc.Extension_2.ViewObject.Proxy, "testFunction")) - FreeCAD.closeDocument("SaveRestoreExtensions") + FreeCAD.closeDocument("SaveRestoreExtensions") - def testPersistenceContentDump(self): - #test smallest level... property - self.Doc.Label_1.Vector = (1,2,3) - dump = self.Doc.Label_1.dumpPropertyContent('Vector', Compression = 9) - self.Doc.Label_2.restorePropertyContent('Vector', dump) - self.assertEqual(self.Doc.Label_1.Vector, self.Doc.Label_2.Vector) + def testPersistenceContentDump(self): + # test smallest level... property + self.Doc.Label_1.Vector = (1, 2, 3) + dump = self.Doc.Label_1.dumpPropertyContent("Vector", Compression=9) + self.Doc.Label_2.restorePropertyContent("Vector", dump) + self.assertEqual(self.Doc.Label_1.Vector, self.Doc.Label_2.Vector) - #next higher: object - self.Doc.Label_1.Distance = 12 - self.Doc.Label_1.String = 'test' - dump = self.Doc.Label_1.dumpContent() - self.Doc.Label_3.restoreContent(dump) - self.assertEqual(self.Doc.Label_1.Distance, self.Doc.Label_3.Distance) - self.assertEqual(self.Doc.Label_1.String, self.Doc.Label_3.String) + # next higher: object + self.Doc.Label_1.Distance = 12 + self.Doc.Label_1.String = "test" + dump = self.Doc.Label_1.dumpContent() + self.Doc.Label_3.restoreContent(dump) + self.assertEqual(self.Doc.Label_1.Distance, self.Doc.Label_3.Distance) + self.assertEqual(self.Doc.Label_1.String, self.Doc.Label_3.String) - #highest level: document - dump = self.Doc.dumpContent(9) - Doc = FreeCAD.newDocument("DumpTest") - Doc.restoreContent(dump) - self.assertEqual(len(self.Doc.Objects), len(Doc.Objects)) - self.assertEqual(self.Doc.Label_1.Distance, Doc.Label_1.Distance) - self.assertEqual(self.Doc.Label_1.String, Doc.Label_1.String) - self.assertEqual(self.Doc.Label_1.Vector, Doc.Label_1.Vector) - FreeCAD.closeDocument("DumpTest") + # highest level: document + dump = self.Doc.dumpContent(9) + Doc = FreeCAD.newDocument("DumpTest") + Doc.restoreContent(dump) + self.assertEqual(len(self.Doc.Objects), len(Doc.Objects)) + self.assertEqual(self.Doc.Label_1.Distance, Doc.Label_1.Distance) + self.assertEqual(self.Doc.Label_1.String, Doc.Label_1.String) + self.assertEqual(self.Doc.Label_1.Vector, Doc.Label_1.Vector) + FreeCAD.closeDocument("DumpTest") + + def tearDown(self): + # closing doc + FreeCAD.closeDocument("SaveRestoreTests") - def tearDown(self): - #closing doc - FreeCAD.closeDocument("SaveRestoreTests") class DocumentRecomputeCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("RecomputeTests") - self.L1 = self.Doc.addObject("App::FeatureTest","Label_1") - self.L2 = self.Doc.addObject("App::FeatureTest","Label_2") - self.L3 = self.Doc.addObject("App::FeatureTest","Label_3") + def setUp(self): + self.Doc = FreeCAD.newDocument("RecomputeTests") + self.L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + self.L2 = self.Doc.addObject("App::FeatureTest", "Label_2") + self.L3 = self.Doc.addObject("App::FeatureTest", "Label_3") - def testDescent(self): - # testing the up and downstream stuff - FreeCAD.Console.PrintLog("def testDescent(self):Testcase not implemented\n") - self.L1.Link = self.L2 - self.L2.Link = self.L3 + def testDescent(self): + # testing the up and downstream stuff + FreeCAD.Console.PrintLog("def testDescent(self):Testcase not implemented\n") + self.L1.Link = self.L2 + self.L2.Link = self.L3 - def testRecompute(self): + def testRecompute(self): - # sequence to test recompute behaviour - # L1---\ L7 - # / \ \ | - # L2 L3 \ L8 - # / \ / \ / - # L4 L5 L6 + # sequence to test recompute behaviour + # L1---\ L7 + # / \ \ | + # L2 L3 \ L8 + # / \ / \ / + # L4 L5 L6 - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - L2 = self.Doc.addObject("App::FeatureTest","Label_2") - L3 = self.Doc.addObject("App::FeatureTest","Label_3") - L4 = self.Doc.addObject("App::FeatureTest","Label_4") - L5 = self.Doc.addObject("App::FeatureTest","Label_5") - L6 = self.Doc.addObject("App::FeatureTest","Label_6") - L7 = self.Doc.addObject("App::FeatureTest","Label_7") - L8 = self.Doc.addObject("App::FeatureTest","Label_8") - L1.LinkList = [L2,L3,L6] - L2.Link = L4 - L2.LinkList = [L5] - L3.LinkList = [L5,L6] - L7.Link = L8 #make second root + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + L2 = self.Doc.addObject("App::FeatureTest", "Label_2") + L3 = self.Doc.addObject("App::FeatureTest", "Label_3") + L4 = self.Doc.addObject("App::FeatureTest", "Label_4") + L5 = self.Doc.addObject("App::FeatureTest", "Label_5") + L6 = self.Doc.addObject("App::FeatureTest", "Label_6") + L7 = self.Doc.addObject("App::FeatureTest", "Label_7") + L8 = self.Doc.addObject("App::FeatureTest", "Label_8") + L1.LinkList = [L2, L3, L6] + L2.Link = L4 + L2.LinkList = [L5] + L3.LinkList = [L5, L6] + L7.Link = L8 # make second root - self.failUnless(L7 in self.Doc.RootObjects) - self.failUnless(L1 in self.Doc.RootObjects) + self.failUnless(L7 in self.Doc.RootObjects) + self.failUnless(L1 in self.Doc.RootObjects) - self.failUnless(len(self.Doc.Objects) == len(self.Doc.TopologicalSortedObjects)) + self.failUnless(len(self.Doc.Objects) == len(self.Doc.TopologicalSortedObjects)) - seqDic = {} - i = 0 - for obj in self.Doc.TopologicalSortedObjects: - seqDic[obj] = i - print(obj) - i += 1 + seqDic = {} + i = 0 + for obj in self.Doc.TopologicalSortedObjects: + seqDic[obj] = i + print(obj) + i += 1 - self.failUnless(seqDic[L2] > seqDic[L1]) - self.failUnless(seqDic[L3] > seqDic[L1]) - self.failUnless(seqDic[L5] > seqDic[L2]) - self.failUnless(seqDic[L5] > seqDic[L3]) - self.failUnless(seqDic[L5] > seqDic[L1]) + self.failUnless(seqDic[L2] > seqDic[L1]) + self.failUnless(seqDic[L3] > seqDic[L1]) + self.failUnless(seqDic[L5] > seqDic[L2]) + self.failUnless(seqDic[L5] > seqDic[L3]) + self.failUnless(seqDic[L5] > seqDic[L1]) + self.failUnless( + (0, 0, 0, 0, 0, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + self.failUnless(self.Doc.recompute() == 4) + self.failUnless( + (1, 1, 1, 0, 0, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L5.enforceRecompute() + self.failUnless( + (1, 1, 1, 0, 0, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + self.failUnless(self.Doc.recompute() == 4) + self.failUnless( + (2, 2, 2, 0, 1, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L4.enforceRecompute() + self.failUnless(self.Doc.recompute() == 3) + self.failUnless( + (3, 3, 2, 1, 1, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L5.enforceRecompute() + self.failUnless(self.Doc.recompute() == 4) + self.failUnless( + (4, 4, 3, 1, 2, 0) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L6.enforceRecompute() + self.failUnless(self.Doc.recompute() == 3) + self.failUnless( + (5, 4, 4, 1, 2, 1) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L2.enforceRecompute() + self.failUnless(self.Doc.recompute() == 2) + self.failUnless( + (6, 5, 4, 1, 2, 1) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) + L1.enforceRecompute() + self.failUnless(self.Doc.recompute() == 1) + self.failUnless( + (7, 5, 4, 1, 2, 1) + == (L1.ExecCount, L2.ExecCount, L3.ExecCount, L4.ExecCount, L5.ExecCount, L6.ExecCount) + ) - self.failUnless((0, 0, 0, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - self.failUnless(self.Doc.recompute()==4) - self.failUnless((1, 1, 1, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L5.enforceRecompute() - self.failUnless((1, 1, 1, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - self.failUnless(self.Doc.recompute()==4) - self.failUnless((2, 2, 2, 0, 1, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L4.enforceRecompute() - self.failUnless(self.Doc.recompute()==3) - self.failUnless((3, 3, 2, 1, 1, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L5.enforceRecompute() - self.failUnless(self.Doc.recompute()==4) - self.failUnless((4, 4, 3, 1, 2, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L6.enforceRecompute() - self.failUnless(self.Doc.recompute()==3) - self.failUnless((5, 4, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L2.enforceRecompute() - self.failUnless(self.Doc.recompute()==2) - self.failUnless((6, 5, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) - L1.enforceRecompute() - self.failUnless(self.Doc.recompute()==1) - self.failUnless((7, 5, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount)) + self.Doc.removeObject(L1.Name) + self.Doc.removeObject(L2.Name) + self.Doc.removeObject(L3.Name) + self.Doc.removeObject(L4.Name) + self.Doc.removeObject(L5.Name) + self.Doc.removeObject(L6.Name) + self.Doc.removeObject(L7.Name) + self.Doc.removeObject(L8.Name) - self.Doc.removeObject(L1.Name) - self.Doc.removeObject(L2.Name) - self.Doc.removeObject(L3.Name) - self.Doc.removeObject(L4.Name) - self.Doc.removeObject(L5.Name) - self.Doc.removeObject(L6.Name) - self.Doc.removeObject(L7.Name) - self.Doc.removeObject(L8.Name) + def tearDown(self): + # closing doc + FreeCAD.closeDocument("RecomputeTests") - def tearDown(self): - #closing doc - FreeCAD.closeDocument("RecomputeTests") class UndoRedoCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("UndoTest") - self.Doc.UndoMode = 0 - self.Doc.addObject("App::FeatureTest","Base") - self.Doc.addObject("App::FeatureTest","Del") - self.Doc.getObject("Del").Integer = 2 + def setUp(self): + self.Doc = FreeCAD.newDocument("UndoTest") + self.Doc.UndoMode = 0 + self.Doc.addObject("App::FeatureTest", "Base") + self.Doc.addObject("App::FeatureTest", "Del") + self.Doc.getObject("Del").Integer = 2 - def testUndoProperties(self): - # switch on the Undo - self.Doc.UndoMode = 1 + def testUndoProperties(self): + # switch on the Undo + self.Doc.UndoMode = 1 - # first transaction - self.Doc.openTransaction("Transaction1") - self.Doc.addObject("App::FeatureTest","test1") - self.Doc.getObject("test1").Integer = 1 - self.Doc.getObject("test1").String = "test1" - self.Doc.getObject("test1").Float = 1.0 - self.Doc.getObject("test1").Bool = 1 + # first transaction + self.Doc.openTransaction("Transaction1") + self.Doc.addObject("App::FeatureTest", "test1") + self.Doc.getObject("test1").Integer = 1 + self.Doc.getObject("test1").String = "test1" + self.Doc.getObject("test1").Float = 1.0 + self.Doc.getObject("test1").Bool = 1 - #self.Doc.getObject("test1").IntegerList = 1 - #self.Doc.getObject("test1").FloatList = 1.0 + # self.Doc.getObject("test1").IntegerList = 1 + # self.Doc.getObject("test1").FloatList = 1.0 - #self.Doc.getObject("test1").Matrix = (1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0) - #self.Doc.getObject("test1").Vector = (1.0,1.0,1.0) + # self.Doc.getObject("test1").Matrix = (1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0) + # self.Doc.getObject("test1").Vector = (1.0,1.0,1.0) - # second transaction - self.Doc.openTransaction("Transaction2") - self.Doc.getObject("test1").Integer = 2 - self.Doc.getObject("test1").String = "test2" - self.Doc.getObject("test1").Float = 2.0 - self.Doc.getObject("test1").Bool = 0 + # second transaction + self.Doc.openTransaction("Transaction2") + self.Doc.getObject("test1").Integer = 2 + self.Doc.getObject("test1").String = "test2" + self.Doc.getObject("test1").Float = 2.0 + self.Doc.getObject("test1").Bool = 0 - # switch on the Undo OFF - self.Doc.UndoMode = 0 + # switch on the Undo OFF + self.Doc.UndoMode = 0 - def testUndoClear(self): - # switch on the Undo - self.Doc.UndoMode = 1 - self.assertEqual(self.Doc.UndoNames,[]) - self.assertEqual(self.Doc.UndoCount,0) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + def testUndoClear(self): + # switch on the Undo + self.Doc.UndoMode = 1 + self.assertEqual(self.Doc.UndoNames, []) + self.assertEqual(self.Doc.UndoCount, 0) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - self.Doc.openTransaction("Transaction1") - # becomes the active object - self.Doc.addObject("App::FeatureTest","test1") - self.Doc.commitTransaction() - # removes the active object - self.Doc.undo() - self.assertEqual(self.Doc.ActiveObject,None) - # deletes the active object - self.Doc.clearUndos() - self.assertEqual(self.Doc.ActiveObject,None) + self.Doc.openTransaction("Transaction1") + # becomes the active object + self.Doc.addObject("App::FeatureTest", "test1") + self.Doc.commitTransaction() + # removes the active object + self.Doc.undo() + self.assertEqual(self.Doc.ActiveObject, None) + # deletes the active object + self.Doc.clearUndos() + self.assertEqual(self.Doc.ActiveObject, None) - def testUndo(self): - # switch on the Undo - self.Doc.UndoMode = 1 - self.assertEqual(self.Doc.UndoNames,[]) - self.assertEqual(self.Doc.UndoCount,0) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + def testUndo(self): + # switch on the Undo + self.Doc.UndoMode = 1 + self.assertEqual(self.Doc.UndoNames, []) + self.assertEqual(self.Doc.UndoCount, 0) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # first transaction - self.Doc.openTransaction("Transaction1") - self.Doc.addObject("App::FeatureTest","test1") - self.Doc.getObject("test1").Integer = 1 - self.Doc.getObject("Del").Integer = 1 - self.Doc.removeObject("Del") - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # first transaction + self.Doc.openTransaction("Transaction1") + self.Doc.addObject("App::FeatureTest", "test1") + self.Doc.getObject("test1").Integer = 1 + self.Doc.getObject("Del").Integer = 1 + self.Doc.removeObject("Del") + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # second transaction - self.Doc.openTransaction("Transaction2") - # new behavior: no change, no transaction - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # second transaction + self.Doc.openTransaction("Transaction2") + # new behavior: no change, no transaction + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - self.Doc.getObject("test1").Integer = 2 - self.assertEqual(self.Doc.UndoNames,['Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + self.Doc.getObject("test1").Integer = 2 + self.assertEqual(self.Doc.UndoNames, ["Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # abort second transaction - self.Doc.abortTransaction() - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) - self.assertEqual(self.Doc.getObject("test1").Integer, 1) + # abort second transaction + self.Doc.abortTransaction() + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) + self.assertEqual(self.Doc.getObject("test1").Integer, 1) - # again second transaction - self.Doc.openTransaction("Transaction2") - self.Doc.getObject("test1").Integer = 2 - self.assertEqual(self.Doc.UndoNames,['Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # again second transaction + self.Doc.openTransaction("Transaction2") + self.Doc.getObject("test1").Integer = 2 + self.assertEqual(self.Doc.UndoNames, ["Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # third transaction - self.Doc.openTransaction("Transaction3") - self.Doc.getObject("test1").Integer = 3 - self.assertEqual(self.Doc.UndoNames,['Transaction3','Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,3) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # third transaction + self.Doc.openTransaction("Transaction3") + self.Doc.getObject("test1").Integer = 3 + self.assertEqual(self.Doc.UndoNames, ["Transaction3", "Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 3) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # fourth transaction - self.Doc.openTransaction("Transaction4") - self.Doc.getObject("test1").Integer = 4 - self.assertEqual(self.Doc.UndoNames,['Transaction4','Transaction3','Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,4) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # fourth transaction + self.Doc.openTransaction("Transaction4") + self.Doc.getObject("test1").Integer = 4 + self.assertEqual( + self.Doc.UndoNames, ["Transaction4", "Transaction3", "Transaction2", "Transaction1"] + ) + self.assertEqual(self.Doc.UndoCount, 4) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # undo the fourth transaction - self.Doc.undo() - self.assertEqual(self.Doc.getObject("test1").Integer, 3) - self.assertEqual(self.Doc.UndoNames,['Transaction3','Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,3) - self.assertEqual(self.Doc.RedoNames,['Transaction4']) - self.assertEqual(self.Doc.RedoCount,1) + # undo the fourth transaction + self.Doc.undo() + self.assertEqual(self.Doc.getObject("test1").Integer, 3) + self.assertEqual(self.Doc.UndoNames, ["Transaction3", "Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 3) + self.assertEqual(self.Doc.RedoNames, ["Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 1) - # undo the third transaction - self.Doc.undo() - self.assertEqual(self.Doc.getObject("test1").Integer, 2) - self.assertEqual(self.Doc.UndoNames,['Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,['Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,2) + # undo the third transaction + self.Doc.undo() + self.assertEqual(self.Doc.getObject("test1").Integer, 2) + self.assertEqual(self.Doc.UndoNames, ["Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, ["Transaction3", "Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 2) - # undo the second transaction - self.Doc.undo() - self.assertEqual(self.Doc.getObject("test1").Integer, 1) - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,['Transaction2','Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,3) + # undo the second transaction + self.Doc.undo() + self.assertEqual(self.Doc.getObject("test1").Integer, 1) + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, ["Transaction2", "Transaction3", "Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 3) - # undo the first transaction - self.Doc.undo() - self.failUnless(self.Doc.getObject("test1") is None) - self.failUnless(self.Doc.getObject("Del").Integer == 2) - self.assertEqual(self.Doc.UndoNames,[]) - self.assertEqual(self.Doc.UndoCount,0) - self.assertEqual(self.Doc.RedoNames,['Transaction1','Transaction2','Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,4) + # undo the first transaction + self.Doc.undo() + self.failUnless(self.Doc.getObject("test1") is None) + self.failUnless(self.Doc.getObject("Del").Integer == 2) + self.assertEqual(self.Doc.UndoNames, []) + self.assertEqual(self.Doc.UndoCount, 0) + self.assertEqual( + self.Doc.RedoNames, ["Transaction1", "Transaction2", "Transaction3", "Transaction4"] + ) + self.assertEqual(self.Doc.RedoCount, 4) - # redo the first transaction - self.Doc.redo() - self.assertEqual(self.Doc.getObject("test1").Integer, 1) - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,['Transaction2','Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,3) + # redo the first transaction + self.Doc.redo() + self.assertEqual(self.Doc.getObject("test1").Integer, 1) + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, ["Transaction2", "Transaction3", "Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 3) - # redo the second transaction - self.Doc.redo() - self.assertEqual(self.Doc.getObject("test1").Integer, 2) - self.assertEqual(self.Doc.UndoNames,['Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,['Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,2) + # redo the second transaction + self.Doc.redo() + self.assertEqual(self.Doc.getObject("test1").Integer, 2) + self.assertEqual(self.Doc.UndoNames, ["Transaction2", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, ["Transaction3", "Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 2) - # undo the second transaction - self.Doc.undo() - self.assertEqual(self.Doc.getObject("test1").Integer, 1) - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,['Transaction2','Transaction3','Transaction4']) - self.assertEqual(self.Doc.RedoCount,3) + # undo the second transaction + self.Doc.undo() + self.assertEqual(self.Doc.getObject("test1").Integer, 1) + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, ["Transaction2", "Transaction3", "Transaction4"]) + self.assertEqual(self.Doc.RedoCount, 3) - # new transaction eight - self.Doc.openTransaction("Transaction8") - self.Doc.getObject("test1").Integer = 8 - self.assertEqual(self.Doc.UndoNames,['Transaction8','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) - self.Doc.abortTransaction() - self.assertEqual(self.Doc.UndoNames,['Transaction1']) - self.assertEqual(self.Doc.UndoCount,1) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # new transaction eight + self.Doc.openTransaction("Transaction8") + self.Doc.getObject("test1").Integer = 8 + self.assertEqual(self.Doc.UndoNames, ["Transaction8", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) + self.Doc.abortTransaction() + self.assertEqual(self.Doc.UndoNames, ["Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 1) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # again new transaction eight - self.Doc.openTransaction("Transaction8") - self.Doc.getObject("test1").Integer = 8 - self.assertEqual(self.Doc.UndoNames,['Transaction8','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # again new transaction eight + self.Doc.openTransaction("Transaction8") + self.Doc.getObject("test1").Integer = 8 + self.assertEqual(self.Doc.UndoNames, ["Transaction8", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - # again new transaction nine - self.Doc.openTransaction("Transaction9") - self.Doc.getObject("test1").Integer = 9 - self.assertEqual(self.Doc.UndoNames,['Transaction9','Transaction8','Transaction1']) - self.assertEqual(self.Doc.UndoCount,3) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) - self.Doc.commitTransaction() - self.assertEqual(self.Doc.UndoNames,['Transaction9','Transaction8','Transaction1']) - self.assertEqual(self.Doc.UndoCount,3) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) - self.assertEqual(self.Doc.getObject("test1").Integer, 9) + # again new transaction nine + self.Doc.openTransaction("Transaction9") + self.Doc.getObject("test1").Integer = 9 + self.assertEqual(self.Doc.UndoNames, ["Transaction9", "Transaction8", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 3) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) + self.Doc.commitTransaction() + self.assertEqual(self.Doc.UndoNames, ["Transaction9", "Transaction8", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 3) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) + self.assertEqual(self.Doc.getObject("test1").Integer, 9) - # undo the ninth transaction - self.Doc.undo() - self.assertEqual(self.Doc.getObject("test1").Integer, 8) - self.assertEqual(self.Doc.UndoNames,['Transaction8','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) - self.assertEqual(self.Doc.RedoNames,['Transaction9']) - self.assertEqual(self.Doc.RedoCount,1) + # undo the ninth transaction + self.Doc.undo() + self.assertEqual(self.Doc.getObject("test1").Integer, 8) + self.assertEqual(self.Doc.UndoNames, ["Transaction8", "Transaction1"]) + self.assertEqual(self.Doc.UndoCount, 2) + self.assertEqual(self.Doc.RedoNames, ["Transaction9"]) + self.assertEqual(self.Doc.RedoCount, 1) - # switch on the Undo OFF - self.Doc.UndoMode = 0 - self.assertEqual(self.Doc.UndoNames,[]) - self.assertEqual(self.Doc.UndoCount,0) - self.assertEqual(self.Doc.RedoNames,[]) - self.assertEqual(self.Doc.RedoCount,0) + # switch on the Undo OFF + self.Doc.UndoMode = 0 + self.assertEqual(self.Doc.UndoNames, []) + self.assertEqual(self.Doc.UndoCount, 0) + self.assertEqual(self.Doc.RedoNames, []) + self.assertEqual(self.Doc.RedoCount, 0) - def testUndoInList(self): + def testUndoInList(self): - self.Doc.UndoMode = 1 + self.Doc.UndoMode = 1 - self.Doc.openTransaction("Box") - self.Box = self.Doc.addObject('App::FeatureTest') - self.Doc.commitTransaction() + self.Doc.openTransaction("Box") + self.Box = self.Doc.addObject("App::FeatureTest") + self.Doc.commitTransaction() - self.Doc.openTransaction("Cylinder") - self.Cylinder = self.Doc.addObject('App::FeatureTest') - self.Doc.commitTransaction() + self.Doc.openTransaction("Cylinder") + self.Cylinder = self.Doc.addObject("App::FeatureTest") + self.Doc.commitTransaction() - self.Doc.openTransaction("Fuse") - self.Fuse1 = self.Doc.addObject('App::FeatureTest', 'Fuse') - self.Fuse1.LinkList = [self.Box, self.Cylinder] - self.Doc.commitTransaction() + self.Doc.openTransaction("Fuse") + self.Fuse1 = self.Doc.addObject("App::FeatureTest", "Fuse") + self.Fuse1.LinkList = [self.Box, self.Cylinder] + self.Doc.commitTransaction() - self.Doc.undo() - self.failUnless(len(self.Box.InList) == 0) - self.failUnless(len(self.Cylinder.InList) == 0) + self.Doc.undo() + self.failUnless(len(self.Box.InList) == 0) + self.failUnless(len(self.Cylinder.InList) == 0) - self.Doc.redo() - self.failUnless(len(self.Box.InList) == 1) - self.failUnless(self.Box.InList[0] == self.Doc.Fuse) - self.failUnless(len(self.Cylinder.InList) == 1) - self.failUnless(self.Cylinder.InList[0] == self.Doc.Fuse) + self.Doc.redo() + self.failUnless(len(self.Box.InList) == 1) + self.failUnless(self.Box.InList[0] == self.Doc.Fuse) + self.failUnless(len(self.Cylinder.InList) == 1) + self.failUnless(self.Cylinder.InList[0] == self.Doc.Fuse) - def testUndoIssue0003150Part1(self): + def testUndoIssue0003150Part1(self): - self.Doc.UndoMode = 1 + self.Doc.UndoMode = 1 - self.Doc.openTransaction("Box") - self.Box = self.Doc.addObject('App::FeatureTest') - self.Doc.commitTransaction() + self.Doc.openTransaction("Box") + self.Box = self.Doc.addObject("App::FeatureTest") + self.Doc.commitTransaction() - self.Doc.openTransaction("Cylinder") - self.Cylinder = self.Doc.addObject('App::FeatureTest') - self.Doc.commitTransaction() + self.Doc.openTransaction("Cylinder") + self.Cylinder = self.Doc.addObject("App::FeatureTest") + self.Doc.commitTransaction() - self.Doc.openTransaction("Fuse") - self.Fuse1 = self.Doc.addObject('App::FeatureTest') - self.Fuse1.LinkList = [self.Box, self.Cylinder] - self.Doc.commitTransaction() - self.Doc.recompute() + self.Doc.openTransaction("Fuse") + self.Fuse1 = self.Doc.addObject("App::FeatureTest") + self.Fuse1.LinkList = [self.Box, self.Cylinder] + self.Doc.commitTransaction() + self.Doc.recompute() - self.Doc.openTransaction("Sphere") - self.Sphere = self.Doc.addObject('App::FeatureTest') - self.Doc.commitTransaction() + self.Doc.openTransaction("Sphere") + self.Sphere = self.Doc.addObject("App::FeatureTest") + self.Doc.commitTransaction() - self.Doc.openTransaction("Fuse") - self.Fuse2 = self.Doc.addObject('App::FeatureTest') - self.Fuse2.LinkList = [self.Fuse1, self.Sphere] - self.Doc.commitTransaction() - self.Doc.recompute() + self.Doc.openTransaction("Fuse") + self.Fuse2 = self.Doc.addObject("App::FeatureTest") + self.Fuse2.LinkList = [self.Fuse1, self.Sphere] + self.Doc.commitTransaction() + self.Doc.recompute() - self.Doc.openTransaction("Part") - self.Part = self.Doc.addObject('App::Part') - self.Doc.commitTransaction() + self.Doc.openTransaction("Part") + self.Part = self.Doc.addObject("App::Part") + self.Doc.commitTransaction() - self.Doc.openTransaction("Drag") - self.Part.addObject(self.Fuse2) - self.Doc.commitTransaction() + self.Doc.openTransaction("Drag") + self.Part.addObject(self.Fuse2) + self.Doc.commitTransaction() - #3 undos show the problem of failing recompute - self.Doc.undo() - self.Doc.undo() - self.Doc.undo() - self.failUnless(self.Doc.recompute() >= 0) + # 3 undos show the problem of failing recompute + self.Doc.undo() + self.Doc.undo() + self.Doc.undo() + self.failUnless(self.Doc.recompute() >= 0) + + def tearDown(self): + # closing doc + FreeCAD.closeDocument("UndoTest") - def tearDown(self): - # closing doc - FreeCAD.closeDocument("UndoTest") class DocumentGroupCases(unittest.TestCase): + def setUp(self): + self.Doc = FreeCAD.newDocument("GroupTests") - def setUp(self): - self.Doc = FreeCAD.newDocument("GroupTests") + def testGroup(self): + # Add an object to the group + L2 = self.Doc.addObject("App::FeatureTest", "Label_2") + G1 = self.Doc.addObject("App::DocumentObjectGroup", "Group") + G1.addObject(L2) + self.failUnless(G1.hasObject(L2)) - def testGroup(self): - # Add an object to the group - L2 = self.Doc.addObject("App::FeatureTest","Label_2") - G1 = self.Doc.addObject("App::DocumentObjectGroup","Group") - G1.addObject(L2) - self.failUnless(G1.hasObject(L2)) + # Adding the group to itself must fail + try: + G1.addObject(G1) + except Exception: + FreeCAD.Console.PrintLog("Cannot add group to itself, OK\n") + else: + self.fail("Adding the group to itself must not be possible") - # Adding the group to itself must fail - try: - G1.addObject(G1) - except Exception: - FreeCAD.Console.PrintLog("Cannot add group to itself, OK\n") - else: - self.fail("Adding the group to itself must not be possible") + self.Doc.UndoMode = 1 - self.Doc.UndoMode = 1 + # Remove object from group + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Label_2") + self.Doc.commitTransaction() + self.failUnless(G1.getObject("Label_2") is None) + self.Doc.undo() + self.failUnless(G1.getObject("Label_2") is not None) - # Remove object from group - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Label_2") - self.Doc.commitTransaction() - self.failUnless(G1.getObject("Label_2") is None) - self.Doc.undo() - self.failUnless(G1.getObject("Label_2") is not None) + # Remove first group and then the object + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Group") + self.Doc.removeObject("Label_2") + self.Doc.commitTransaction() + self.Doc.undo() + self.failUnless(G1.getObject("Label_2") is not None) - # Remove first group and then the object - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Group") - self.Doc.removeObject("Label_2") - self.Doc.commitTransaction() - self.Doc.undo() - self.failUnless(G1.getObject("Label_2") is not None) + # Remove first object and then the group in two transactions + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Label_2") + self.Doc.commitTransaction() + self.failUnless(G1.getObject("Label_2") is None) + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Group") + self.Doc.commitTransaction() + self.Doc.undo() + self.Doc.undo() + self.failUnless(G1.getObject("Label_2") is not None) - # Remove first object and then the group in two transactions - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Label_2") - self.Doc.commitTransaction() - self.failUnless(G1.getObject("Label_2") is None) - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Group") - self.Doc.commitTransaction() - self.Doc.undo() - self.Doc.undo() - self.failUnless(G1.getObject("Label_2") is not None) + # Remove first object and then the group in one transaction + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Label_2") + self.failUnless(G1.getObject("Label_2") is None) + self.Doc.removeObject("Group") + self.Doc.commitTransaction() + self.Doc.undo() + # FIXME: See bug #1820554 + self.failUnless(G1.getObject("Label_2") is not None) - # Remove first object and then the group in one transaction - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Label_2") - self.failUnless(G1.getObject("Label_2") is None) - self.Doc.removeObject("Group") - self.Doc.commitTransaction() - self.Doc.undo() - # FIXME: See bug #1820554 - self.failUnless(G1.getObject("Label_2") is not None) + # Add a second object to the group + L3 = self.Doc.addObject("App::FeatureTest", "Label_3") + G1.addObject(L3) + self.Doc.openTransaction("Remove") + self.Doc.removeObject("Label_2") + self.failUnless(G1.getObject("Label_2") is None) + self.Doc.removeObject("Label_3") + self.failUnless(G1.getObject("Label_3") is None) + self.Doc.removeObject("Group") + self.Doc.commitTransaction() + self.Doc.undo() + self.failUnless(G1.getObject("Label_3") is not None) + self.failUnless(G1.getObject("Label_2") is not None) - # Add a second object to the group - L3 = self.Doc.addObject("App::FeatureTest","Label_3") - G1.addObject(L3) - self.Doc.openTransaction("Remove") - self.Doc.removeObject("Label_2") - self.failUnless(G1.getObject("Label_2") is None) - self.Doc.removeObject("Label_3") - self.failUnless(G1.getObject("Label_3") is None) - self.Doc.removeObject("Group") - self.Doc.commitTransaction() - self.Doc.undo() - self.failUnless(G1.getObject("Label_3") is not None) - self.failUnless(G1.getObject("Label_2") is not None) + self.Doc.UndoMode = 0 - self.Doc.UndoMode = 0 + # Cleanup + self.Doc.removeObject("Group") + self.Doc.removeObject("Label_2") + self.Doc.removeObject("Label_3") - # Cleanup - self.Doc.removeObject("Group") - self.Doc.removeObject("Label_2") - self.Doc.removeObject("Label_3") + def testGroupAndGeoFeatureGroup(self): - def testGroupAndGeoFeatureGroup(self): + # an object can only be in one group at once, that must be enforced + obj1 = self.Doc.addObject("App::FeatureTest", "obj1") + grp1 = self.Doc.addObject("App::DocumentObjectGroup", "Group1") + grp2 = self.Doc.addObject("App::DocumentObjectGroup", "Group2") + grp1.addObject(obj1) + self.failUnless(obj1.getParentGroup() == grp1) + self.failUnless(obj1.getParentGeoFeatureGroup() is None) + self.failUnless(grp1.hasObject(obj1)) + grp2.addObject(obj1) + self.failUnless(grp1.hasObject(obj1) == False) + self.failUnless(grp2.hasObject(obj1)) - # an object can only be in one group at once, that must be enforced - obj1 = self.Doc.addObject("App::FeatureTest","obj1") - grp1 = self.Doc.addObject("App::DocumentObjectGroup","Group1") - grp2 = self.Doc.addObject("App::DocumentObjectGroup","Group2") - grp1.addObject(obj1) - self.failUnless(obj1.getParentGroup()==grp1) - self.failUnless(obj1.getParentGeoFeatureGroup() is None) - self.failUnless(grp1.hasObject(obj1)) - grp2.addObject(obj1) - self.failUnless(grp1.hasObject(obj1)==False) - self.failUnless(grp2.hasObject(obj1)) + # an object is allowed to be in a group and a geofeaturegroup + prt1 = self.Doc.addObject("App::Part", "Part1") + prt2 = self.Doc.addObject("App::Part", "Part2") - # an object is allowed to be in a group and a geofeaturegroup - prt1 = self.Doc.addObject("App::Part","Part1") - prt2 = self.Doc.addObject("App::Part","Part2") + prt1.addObject(grp2) + self.failUnless(grp2.getParentGeoFeatureGroup() == prt1) + self.failUnless(grp2.getParentGroup() is None) + self.failUnless(grp2.hasObject(obj1)) + self.failUnless(prt1.hasObject(grp2)) + self.failUnless(prt1.hasObject(obj1)) - prt1.addObject(grp2) - self.failUnless(grp2.getParentGeoFeatureGroup() == prt1) - self.failUnless(grp2.getParentGroup() is None) - self.failUnless(grp2.hasObject(obj1)) - self.failUnless(prt1.hasObject(grp2)) - self.failUnless(prt1.hasObject(obj1)) + # it is not allowed to be in 2 geofeaturegroups + prt2.addObject(grp2) + self.failUnless(grp2.hasObject(obj1)) + self.failUnless(prt1.hasObject(grp2) == False) + self.failUnless(prt1.hasObject(obj1) == False) + self.failUnless(prt2.hasObject(grp2)) + self.failUnless(prt2.hasObject(obj1)) + try: + grp = prt1.Group + grp.append(obj1) + prt1.Group = grp + except Exception: + grp.remove(obj1) + self.failUnless(prt1.Group == grp) + else: + self.fail("No exception thrown when object is in multiple Groups") - #it is not allowed to be in 2 geofeaturegroups - prt2.addObject(grp2) - self.failUnless(grp2.hasObject(obj1)) - self.failUnless(prt1.hasObject(grp2)==False) - self.failUnless(prt1.hasObject(obj1)==False) - self.failUnless(prt2.hasObject(grp2)) - self.failUnless(prt2.hasObject(obj1)) - try: - grp = prt1.Group + # it is not allowed to be in 2 Groups + prt2.addObject(grp1) + grp = grp1.Group grp.append(obj1) - prt1.Group = grp - except Exception: - grp.remove(obj1) - self.failUnless(prt1.Group == grp) - else: - self.fail("No exception thrown when object is in multiple Groups") + try: + grp1.Group = grp + except Exception: + pass + else: + self.fail("No exception thrown when object is in multiple Groups") - #it is not allowed to be in 2 Groups - prt2.addObject(grp1) - grp = grp1.Group - grp.append(obj1) - try: - grp1.Group = grp - except Exception: - pass - else: - self.fail("No exception thrown when object is in multiple Groups") + # cross linking between GeoFeatureGroups is not allowed + self.Doc.recompute() + box = self.Doc.addObject("App::FeatureTest", "Box") + cyl = self.Doc.addObject("App::FeatureTest", "Cylinder") + fus = self.Doc.addObject("App::FeatureTest", "Fusion") + fus.LinkList = [cyl, box] + self.Doc.recompute() + self.failUnless(fus.State[0] == "Up-to-date") + fus.LinkList = ( + [] + ) # remove all links as addObject would otherwise transfer all linked objects + prt1.addObject(cyl) + fus.LinkList = [cyl, box] + self.Doc.recompute() + # self.failUnless(fus.State[0] == 'Invalid') + fus.LinkList = [] + prt1.addObject(box) + fus.LinkList = [cyl, box] + self.Doc.recompute() + # self.failUnless(fus.State[0] == 'Invalid') + fus.LinkList = [] + prt1.addObject(fus) + fus.LinkList = [cyl, box] + self.Doc.recompute() + self.failUnless(fus.State[0] == "Up-to-date") + prt2.addObject(box) # this time addObject should move all dependencies to the new part + self.Doc.recompute() + self.failUnless(fus.State[0] == "Up-to-date") - #cross linking between GeoFeatureGroups is not allowed - self.Doc.recompute() - box = self.Doc.addObject("App::FeatureTest","Box") - cyl = self.Doc.addObject("App::FeatureTest","Cylinder") - fus = self.Doc.addObject("App::FeatureTest","Fusion") - fus.LinkList = [cyl, box] - self.Doc.recompute() - self.failUnless(fus.State[0] == 'Up-to-date') - fus.LinkList = [] #remove all links as addObject would otherwise transfer all linked objects - prt1.addObject(cyl) - fus.LinkList = [cyl, box] - self.Doc.recompute() - #self.failUnless(fus.State[0] == 'Invalid') - fus.LinkList = [] - prt1.addObject(box) - fus.LinkList = [cyl, box] - self.Doc.recompute() - #self.failUnless(fus.State[0] == 'Invalid') - fus.LinkList = [] - prt1.addObject(fus) - fus.LinkList = [cyl, box] - self.Doc.recompute() - self.failUnless(fus.State[0] == 'Up-to-date') - prt2.addObject(box) #this time addObject should move all dependencies to the new part - self.Doc.recompute() - self.failUnless(fus.State[0] == 'Up-to-date') + # grouping must be resilient against cyclic links and not crash: #issue 0002567 + prt1.addObject(prt2) + grp = prt2.Group + grp.append(prt1) + prt2.Group = grp + self.Doc.recompute() + prt2.Group = [] + try: + prt2.Group = [prt2] + except Exception: + pass + else: + self.fail("Exception is expected") - #grouping must be resilient against cyclic links and not crash: #issue 0002567 - prt1.addObject(prt2) - grp = prt2.Group - grp.append(prt1) - prt2.Group = grp - self.Doc.recompute() - prt2.Group = [] - try: - prt2.Group = [prt2] - except Exception: - pass - else: - self.fail("Exception is expected") + self.Doc.recompute() - self.Doc.recompute() + def testIssue0003150Part2(self): + self.box = self.Doc.addObject("App::FeatureTest") + self.cyl = self.Doc.addObject("App::FeatureTest") + self.sph = self.Doc.addObject("App::FeatureTest") - def testIssue0003150Part2(self): - self.box = self.Doc.addObject("App::FeatureTest") - self.cyl = self.Doc.addObject("App::FeatureTest") - self.sph = self.Doc.addObject("App::FeatureTest") + self.fus1 = self.Doc.addObject("App::FeatureTest") + self.fus2 = self.Doc.addObject("App::FeatureTest") - self.fus1 = self.Doc.addObject("App::FeatureTest") - self.fus2 = self.Doc.addObject("App::FeatureTest") + self.fus1.LinkList = [self.box, self.cyl] + self.fus2.LinkList = [self.sph, self.cyl] - self.fus1.LinkList = [self.box, self.cyl]; - self.fus2.LinkList = [self.sph, self.cyl]; + self.prt = self.Doc.addObject("App::Part") + self.prt.addObject(self.fus1) + self.failUnless(len(self.prt.Group) == 5) + self.failUnless(self.fus2.getParentGeoFeatureGroup() == self.prt) + self.failUnless(self.prt.hasObject(self.sph)) - self.prt = self.Doc.addObject("App::Part") - self.prt.addObject(self.fus1) - self.failUnless(len(self.prt.Group)==5) - self.failUnless(self.fus2.getParentGeoFeatureGroup() == self.prt) - self.failUnless(self.prt.hasObject(self.sph)) + self.prt.removeObject(self.fus1) + self.failUnless(len(self.prt.Group) == 0) - self.prt.removeObject(self.fus1) - self.failUnless(len(self.prt.Group)==0) + def tearDown(self): + # closing doc + FreeCAD.closeDocument("GroupTests") - def tearDown(self): - # closing doc - FreeCAD.closeDocument("GroupTests") class DocumentPlatformCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("PlatformTests") - self.Doc.addObject("App::FeatureTest", "Test") - self.TempPath = tempfile.gettempdir() - self.DocName = self.TempPath + os.sep + "PlatformTests.FCStd" + def setUp(self): + self.Doc = FreeCAD.newDocument("PlatformTests") + self.Doc.addObject("App::FeatureTest", "Test") + self.TempPath = tempfile.gettempdir() + self.DocName = self.TempPath + os.sep + "PlatformTests.FCStd" - def testFloatList(self): - self.Doc.Test.FloatList = [-0.05, 2.5, 5.2] + def testFloatList(self): + self.Doc.Test.FloatList = [-0.05, 2.5, 5.2] - # saving and restoring - self.Doc.saveAs(self.DocName) - FreeCAD.closeDocument("PlatformTests") - self.Doc = FreeCAD.open(self.DocName) + # saving and restoring + self.Doc.saveAs(self.DocName) + FreeCAD.closeDocument("PlatformTests") + self.Doc = FreeCAD.open(self.DocName) - self.failUnless(abs(self.Doc.Test.FloatList[0] + .05) < 0.01) - self.failUnless(abs(self.Doc.Test.FloatList[1] - 2.5) < 0.01) - self.failUnless(abs(self.Doc.Test.FloatList[2] - 5.2) < 0.01) + self.failUnless(abs(self.Doc.Test.FloatList[0] + 0.05) < 0.01) + self.failUnless(abs(self.Doc.Test.FloatList[1] - 2.5) < 0.01) + self.failUnless(abs(self.Doc.Test.FloatList[2] - 5.2) < 0.01) - def testColorList(self): - self.Doc.Test.ColourList = [(1.0,0.5,0.0),(0.0,0.5,1.0)] + def testColorList(self): + self.Doc.Test.ColourList = [(1.0, 0.5, 0.0), (0.0, 0.5, 1.0)] - # saving and restoring - self.Doc.saveAs(self.DocName) - FreeCAD.closeDocument("PlatformTests") - self.Doc = FreeCAD.open(self.DocName) + # saving and restoring + self.Doc.saveAs(self.DocName) + FreeCAD.closeDocument("PlatformTests") + self.Doc = FreeCAD.open(self.DocName) - self.failUnless(abs(self.Doc.Test.ColourList[0][0] - 1.0) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[0][1] - 0.5) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[0][2] - 0.0) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[0][3] - 0.0) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[1][0] - 0.0) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[1][1] - 0.5) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[1][2] - 1.0) < 0.01) - self.failUnless(abs(self.Doc.Test.ColourList[1][3] - 0.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[0][0] - 1.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[0][1] - 0.5) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[0][2] - 0.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[0][3] - 0.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[1][0] - 0.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[1][1] - 0.5) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[1][2] - 1.0) < 0.01) + self.failUnless(abs(self.Doc.Test.ColourList[1][3] - 0.0) < 0.01) - def testVectorList(self): - self.Doc.Test.VectorList = [(-0.05, 2.5, 5.2),(-0.05, 2.5, 5.2)] + def testVectorList(self): + self.Doc.Test.VectorList = [(-0.05, 2.5, 5.2), (-0.05, 2.5, 5.2)] - # saving and restoring - self.Doc.saveAs(self.DocName) - FreeCAD.closeDocument("PlatformTests") - self.Doc = FreeCAD.open(self.DocName) + # saving and restoring + self.Doc.saveAs(self.DocName) + FreeCAD.closeDocument("PlatformTests") + self.Doc = FreeCAD.open(self.DocName) - self.failUnless(len(self.Doc.Test.VectorList) == 2) + self.failUnless(len(self.Doc.Test.VectorList) == 2) - def testPoints(self): - try: - self.Doc.addObject("Points::Feature", "Points") + def testPoints(self): + try: + self.Doc.addObject("Points::Feature", "Points") - # saving and restoring - self.Doc.saveAs(self.DocName) - FreeCAD.closeDocument("PlatformTests") - self.Doc = FreeCAD.open(self.DocName) + # saving and restoring + self.Doc.saveAs(self.DocName) + FreeCAD.closeDocument("PlatformTests") + self.Doc = FreeCAD.open(self.DocName) - self.failUnless(self.Doc.Points.Points.count() == 0) - except Exception: - pass + self.failUnless(self.Doc.Points.Points.count() == 0) + except Exception: + pass - def tearDown(self): - #closing doc - FreeCAD.closeDocument("PlatformTests") + def tearDown(self): + # closing doc + FreeCAD.closeDocument("PlatformTests") class DocumentBacklinks(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("BackLinks") + def setUp(self): + self.Doc = FreeCAD.newDocument("BackLinks") - def testIssue0003323(self): - self.Doc.UndoMode=1 - self.Doc.openTransaction("Create object") - obj1=self.Doc.addObject("App::FeatureTest","Test1") - obj2=self.Doc.addObject("App::FeatureTest","Test2") - obj2.Link=obj1 - self.Doc.commitTransaction() - self.Doc.undo() - self.Doc.openTransaction("Create object") + def testIssue0003323(self): + self.Doc.UndoMode = 1 + self.Doc.openTransaction("Create object") + obj1 = self.Doc.addObject("App::FeatureTest", "Test1") + obj2 = self.Doc.addObject("App::FeatureTest", "Test2") + obj2.Link = obj1 + self.Doc.commitTransaction() + self.Doc.undo() + self.Doc.openTransaction("Create object") - def tearDown(self): - # closing doc - FreeCAD.closeDocument("BackLinks") + def tearDown(self): + # closing doc + FreeCAD.closeDocument("BackLinks") class DocumentFileIncludeCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("FileIncludeTests") - # testing with undo - self.Doc.UndoMode = 1 + def setUp(self): + self.Doc = FreeCAD.newDocument("FileIncludeTests") + # testing with undo + self.Doc.UndoMode = 1 + def testApplyFiles(self): + self.Doc.openTransaction("Transaction0") + self.L1 = self.Doc.addObject("App::DocumentObjectFileIncluded", "FileObject1") + self.failUnless(self.L1.File == "") + self.Filename = self.L1.File - def testApplyFiles(self): - self.Doc.openTransaction("Transaction0") - self.L1 = self.Doc.addObject("App::DocumentObjectFileIncluded","FileObject1") - self.failUnless(self.L1.File =="") - self.Filename = self.L1.File + self.Doc.openTransaction("Transaction1") + self.TempPath = tempfile.gettempdir() + # creating a file in the Transient directory of the document + file = open(self.Doc.getTempFileName("test"), "w") + file.write("test No1") + file.close() + # applying the file + self.L1.File = (file.name, "Test.txt") + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + # read again + file = open(self.L1.File, "r") + self.failUnless(file.read() == "test No1") + file.close() + file = open(self.TempPath + "/testNest.txt", "w") + file.write("test No2") + file.close() + # applying the file + self.Doc.openTransaction("Transaction2") + self.L1.File = file.name + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + # read again + file = open(self.L1.File, "r") + self.failUnless(file.read() == "test No2") + file.close() + self.Doc.undo() + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + # read again + file = open(self.L1.File, "r") + self.failUnless(file.read() == "test No1") + file.close() + self.Doc.undo() + # read again + self.failUnless(self.L1.File == "") + self.Doc.redo() + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + # read again + file = open(self.L1.File, "r") + self.failUnless(file.read() == "test No1") + file.close() + self.Doc.redo() + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + # read again + file = open(self.L1.File, "r") + self.failUnless(file.read() == "test No2") + file.close() + # Save restore test + FileName = self.TempPath + "/FileIncludeTests.fcstd" + self.Doc.saveAs(FileName) + FreeCAD.closeDocument("FileIncludeTests") + self.Doc = FreeCAD.open(self.TempPath + "/FileIncludeTests.fcstd") + # check if the file is still there + self.L1 = self.Doc.getObject("FileObject1") + file = open(self.L1.File, "r") + res = file.read() + FreeCAD.Console.PrintLog(res + "\n") + self.failUnless(res == "test No2") + self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") + file.close() - self.Doc.openTransaction("Transaction1") - self.TempPath = tempfile.gettempdir() - # creating a file in the Transient directory of the document - file = open(self.Doc.getTempFileName("test"),"w") - file.write("test No1") - file.close() - # applying the file - self.L1.File = (file.name,"Test.txt") - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - # read again - file = open(self.L1.File,"r") - self.failUnless(file.read()=="test No1") - file.close() - file = open(self.TempPath+"/testNest.txt","w") - file.write("test No2") - file.close() - # applying the file - self.Doc.openTransaction("Transaction2") - self.L1.File = file.name - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - # read again - file = open(self.L1.File,"r") - self.failUnless(file.read()=="test No2") - file.close() - self.Doc.undo() - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - # read again - file = open(self.L1.File,"r") - self.failUnless(file.read()=="test No1") - file.close() - self.Doc.undo() - # read again - self.failUnless(self.L1.File == "") - self.Doc.redo() - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - # read again - file = open(self.L1.File,"r") - self.failUnless(file.read()=="test No1") - file.close() - self.Doc.redo() - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - # read again - file = open(self.L1.File,"r") - self.failUnless(file.read()=="test No2") - file.close() - # Save restore test - FileName = self.TempPath+"/FileIncludeTests.fcstd" - self.Doc.saveAs(FileName) - FreeCAD.closeDocument("FileIncludeTests") - self.Doc = FreeCAD.open(self.TempPath+"/FileIncludeTests.fcstd") - # check if the file is still there - self.L1 = self.Doc.getObject("FileObject1") - file = open(self.L1.File,"r") - res = file.read() - FreeCAD.Console.PrintLog( res +"\n") - self.failUnless(res=="test No2") - self.failUnless(self.L1.File.split("/")[-1] == "Test.txt") - file.close() + # test for bug #94 (File overlap in PropertyFileIncluded) + L2 = self.Doc.addObject("App::DocumentObjectFileIncluded", "FileObject2") + L3 = self.Doc.addObject("App::DocumentObjectFileIncluded", "FileObject3") - # test for bug #94 (File overlap in PropertyFileIncluded) - L2 = self.Doc.addObject("App::DocumentObjectFileIncluded","FileObject2") - L3 = self.Doc.addObject("App::DocumentObjectFileIncluded","FileObject3") + # creating two files in the Transient directory of the document + file1 = open(self.Doc.getTempFileName("test"), "w") + file1.write("test No1") + file1.close() + file2 = open(self.Doc.getTempFileName("test"), "w") + file2.write("test No2") + file2.close() - # creating two files in the Transient directory of the document - file1 = open(self.Doc.getTempFileName("test"),"w") - file1.write("test No1") - file1.close() - file2 = open(self.Doc.getTempFileName("test"),"w") - file2.write("test No2") - file2.close() + # applying the file with the same base name + L2.File = (file1.name, "Test.txt") + L3.File = (file2.name, "Test.txt") - # applying the file with the same base name - L2.File = (file1.name,"Test.txt") - L3.File = (file2.name,"Test.txt") + file = open(L2.File, "r") + self.failUnless(file.read() == "test No1") + file.close() + file = open(L3.File, "r") + self.failUnless(file.read() == "test No2") + file.close() - file = open(L2.File,"r") - self.failUnless(file.read()=="test No1") - file.close() - file = open(L3.File,"r") - self.failUnless(file.read()=="test No2") - file.close() + # create a second document, copy a file and close the document + # the test is about to put the file to the correct transient dir + doc2 = FreeCAD.newDocument("Doc2") + L4 = doc2.addObject("App::DocumentObjectFileIncluded", "FileObject") + L5 = doc2.addObject("App::DocumentObjectFileIncluded", "FileObject") + L6 = doc2.addObject("App::DocumentObjectFileIncluded", "FileObject") + L4.File = (L3.File, "Test.txt") + L5.File = L3.File + L6.File = L3.File + FreeCAD.closeDocument("FileIncludeTests") + self.Doc = FreeCAD.open(self.TempPath + "/FileIncludeTests.fcstd") + self.failUnless(os.path.exists(L4.File)) + self.failUnless(os.path.exists(L5.File)) + self.failUnless(os.path.exists(L6.File)) + self.failUnless(L5.File != L6.File) + # copy file from L5 which is in the same directory + L7 = doc2.addObject("App::DocumentObjectFileIncluded", "FileObject3") + L7.File = (L5.File, "Copy.txt") + self.failUnless(os.path.exists(L7.File)) + FreeCAD.closeDocument("Doc2") - # create a second document, copy a file and close the document - # the test is about to put the file to the correct transient dir - doc2 = FreeCAD.newDocument("Doc2") - L4 = doc2.addObject("App::DocumentObjectFileIncluded","FileObject") - L5 = doc2.addObject("App::DocumentObjectFileIncluded","FileObject") - L6 = doc2.addObject("App::DocumentObjectFileIncluded","FileObject") - L4.File = (L3.File,"Test.txt") - L5.File = L3.File - L6.File = L3.File - FreeCAD.closeDocument("FileIncludeTests") - self.Doc = FreeCAD.open(self.TempPath+"/FileIncludeTests.fcstd") - self.failUnless(os.path.exists(L4.File)) - self.failUnless(os.path.exists(L5.File)) - self.failUnless(os.path.exists(L6.File)) - self.failUnless(L5.File != L6.File) - # copy file from L5 which is in the same directory - L7 = doc2.addObject("App::DocumentObjectFileIncluded","FileObject3") - L7.File = (L5.File,"Copy.txt") - self.failUnless(os.path.exists(L7.File)) - FreeCAD.closeDocument("Doc2") - - - def tearDown(self): - #closing doc - FreeCAD.closeDocument("FileIncludeTests") + def tearDown(self): + # closing doc + FreeCAD.closeDocument("FileIncludeTests") class DocumentPropertyCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("PropertyTests") - self.Obj = self.Doc.addObject("App::FeaturePython","Test") + def setUp(self): + self.Doc = FreeCAD.newDocument("PropertyTests") + self.Obj = self.Doc.addObject("App::FeaturePython", "Test") - def testDescent(self): - # testing the up and downstream stuff - props=self.Obj.supportedProperties() - for i in props: - self.Obj.addProperty(i,i.replace(':','_')) - tempPath = tempfile.gettempdir() - tempFile = tempPath + os.sep + "PropertyTests.FCStd" - self.Doc.saveAs(tempFile) - FreeCAD.closeDocument("PropertyTests") - self.Doc = FreeCAD.open(tempFile) + def testDescent(self): + # testing the up and downstream stuff + props = self.Obj.supportedProperties() + for i in props: + self.Obj.addProperty(i, i.replace(":", "_")) + tempPath = tempfile.gettempdir() + tempFile = tempPath + os.sep + "PropertyTests.FCStd" + self.Doc.saveAs(tempFile) + FreeCAD.closeDocument("PropertyTests") + self.Doc = FreeCAD.open(tempFile) - def testRemoveProperty(self): - prop = 'Something' - self.Obj.addProperty('App::PropertyFloat', prop) - self.Obj.Something = 0.01 - self.Doc.recompute() - self.Doc.openTransaction('modify and remove property') - self.Obj.Something = 0.00 - self.Obj.removeProperty(prop) - self.Obj.recompute() - self.Doc.abortTransaction() + def testRemoveProperty(self): + prop = "Something" + self.Obj.addProperty("App::PropertyFloat", prop) + self.Obj.Something = 0.01 + self.Doc.recompute() + self.Doc.openTransaction("modify and remove property") + self.Obj.Something = 0.00 + self.Obj.removeProperty(prop) + self.Obj.recompute() + self.Doc.abortTransaction() - def testRemovePropertyExpression(self): - p1 = self.Doc.addObject("App::FeaturePython", "params1") - p2 = self.Doc.addObject("App::FeaturePython", "params2") - p1.addProperty("App::PropertyFloat", "a") - p1.a = 42 - p2.addProperty("App::PropertyFloat", "b") - p2.setExpression('b', u'params1.a') - self.Doc.recompute() - p2.removeProperty("b") - p1.touch() - self.Doc.recompute() - self.assertTrue(not p2 in p1.InList) + def testRemovePropertyExpression(self): + p1 = self.Doc.addObject("App::FeaturePython", "params1") + p2 = self.Doc.addObject("App::FeaturePython", "params2") + p1.addProperty("App::PropertyFloat", "a") + p1.a = 42 + p2.addProperty("App::PropertyFloat", "b") + p2.setExpression("b", "params1.a") + self.Doc.recompute() + p2.removeProperty("b") + p1.touch() + self.Doc.recompute() + self.assertTrue(not p2 in p1.InList) - def testRemovePropertyOnChange(self): - class Feature: - def __init__(self, fp): - fp.Proxy = self - fp.addProperty("App::PropertyString","Test") - def onBeforeChange(self, fp, prop): - if prop == "Test": - fp.removeProperty("Test") - def onChanged(self, fp, prop): - getattr(fp, prop) + def testRemovePropertyOnChange(self): + class Feature: + def __init__(self, fp): + fp.Proxy = self + fp.addProperty("App::PropertyString", "Test") - obj = self.Doc.addObject("App::FeaturePython") - fea = Feature(obj) - obj.Test = "test" + def onBeforeChange(self, fp, prop): + if prop == "Test": + fp.removeProperty("Test") - def tearDown(self): - #closing doc - FreeCAD.closeDocument("PropertyTests") + def onChanged(self, fp, prop): + getattr(fp, prop) + + obj = self.Doc.addObject("App::FeaturePython") + fea = Feature(obj) + obj.Test = "test" + + def tearDown(self): + # closing doc + FreeCAD.closeDocument("PropertyTests") class DocumentExpressionCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument() + def setUp(self): + self.Doc = FreeCAD.newDocument() - def assertAlmostEqual (self, v1, v2) : - if (math.fabs(v2-v1) > 1E-12) : - self.assertEqual(v1,v2) + def assertAlmostEqual(self, v1, v2): + if math.fabs(v2 - v1) > 1e-12: + self.assertEqual(v1, v2) + def testExpression(self): + self.Obj1 = self.Doc.addObject("App::FeatureTest", "Test") + self.Obj2 = self.Doc.addObject("App::FeatureTest", "Test") + # set the object twice to test that the backlinks are removed when overwriting the expression + self.Obj2.setExpression( + "Placement.Rotation.Angle", "%s.Placement.Rotation.Angle" % self.Obj1.Name + ) + self.Obj2.setExpression( + "Placement.Rotation.Angle", "%s.Placement.Rotation.Angle" % self.Obj1.Name + ) + self.Obj1.Placement = FreeCAD.Placement( + FreeCAD.Vector(0, 0, 0), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 10) + ) + self.Doc.recompute() + self.assertAlmostEqual( + self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle + ) - def testExpression(self): - self.Obj1 = self.Doc.addObject("App::FeatureTest","Test") - self.Obj2 = self.Doc.addObject("App::FeatureTest","Test") - # set the object twice to test that the backlinks are removed when overwriting the expression - self.Obj2.setExpression('Placement.Rotation.Angle', u'%s.Placement.Rotation.Angle' % self.Obj1.Name) - self.Obj2.setExpression('Placement.Rotation.Angle', u'%s.Placement.Rotation.Angle' % self.Obj1.Name) - self.Obj1.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),10)) - self.Doc.recompute() - self.assertAlmostEqual(self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle) + # clear the expression + self.Obj2.setExpression("Placement.Rotation.Angle", None) + self.assertAlmostEqual( + self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle + ) + self.Doc.recompute() + self.assertAlmostEqual( + self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle + ) + # touch the objects to perform a recompute + self.Obj1.Placement = self.Obj1.Placement + self.Obj2.Placement = self.Obj2.Placement + # must not raise a topological error + self.assertEqual(self.Doc.recompute(), 2) - # clear the expression - self.Obj2.setExpression('Placement.Rotation.Angle', None) - self.assertAlmostEqual(self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle) - self.Doc.recompute() - self.assertAlmostEqual(self.Obj1.Placement.Rotation.Angle, self.Obj2.Placement.Rotation.Angle) - # touch the objects to perform a recompute - self.Obj1.Placement = self.Obj1.Placement - self.Obj2.Placement = self.Obj2.Placement - # must not raise a topological error - self.assertEqual(self.Doc.recompute(), 2) + # add test for issue #6948 + self.Obj3 = self.Doc.addObject("App::FeatureTest", "Test") + self.Obj3.setExpression("Float", "2*(5%3)") + self.Doc.recompute() + self.assertEqual(self.Obj3.Float, 4) + self.assertEqual(self.Obj3.evalExpression(self.Obj3.ExpressionEngine[0][1]), 4) - # add test for issue #6948 - self.Obj3 = self.Doc.addObject("App::FeatureTest", "Test") - self.Obj3.setExpression('Float', u'2*(5%3)') - self.Doc.recompute() - self.assertEqual(self.Obj3.Float, 4) - self.assertEqual(self.Obj3.evalExpression(self.Obj3.ExpressionEngine[0][1]), 4) + def testIssue4649(self): + class Cls: + def __init__(self, obj): + self.MonitorChanges = False + obj.Proxy = self + obj.addProperty("App::PropertyFloat", "propA", "group") + obj.addProperty("App::PropertyFloat", "propB", "group") + self.MonitorChanges = True + obj.setExpression("propB", "6*9") + def onChanged(self, obj, prop): + print("onChanged", self, obj, prop) + if self.MonitorChanges and prop == "propA": + print("Removing expression...") + obj.setExpression("propB", None) - def testIssue4649(self): - class Cls(): - def __init__(self, obj): - self.MonitorChanges = False - obj.Proxy = self - obj.addProperty('App::PropertyFloat', "propA", "group") - obj.addProperty('App::PropertyFloat', "propB", "group") - self.MonitorChanges = True - obj.setExpression("propB", '6*9') - def onChanged(self, obj, prop): - print("onChanged",self, obj, prop) - if (self.MonitorChanges and prop == "propA"): - print('Removing expression...') - obj.setExpression("propB", None) + obj = self.Doc.addObject("App::DocumentObjectGroupPython", "Obj") + Cls(obj) + self.Doc.UndoMode = 1 + self.Doc.openTransaction("Expression") + obj.setExpression("propA", "42") + self.Doc.recompute() + self.Doc.commitTransaction() + self.assertTrue(("propB", None) in obj.ExpressionEngine) + self.assertTrue(("propA", "42") in obj.ExpressionEngine) - obj = self.Doc.addObject("App::DocumentObjectGroupPython", "Obj") - Cls(obj) - self.Doc.UndoMode = 1 - self.Doc.openTransaction("Expression") - obj.setExpression("propA", '42') - self.Doc.recompute() - self.Doc.commitTransaction() - self.assertTrue(('propB', None) in obj.ExpressionEngine) - self.assertTrue(('propA', "42") in obj.ExpressionEngine) + self.Doc.undo() + self.assertFalse(("propB", None) in obj.ExpressionEngine) + self.assertFalse(("propA", "42") in obj.ExpressionEngine) - self.Doc.undo() - self.assertFalse(('propB', None) in obj.ExpressionEngine) - self.assertFalse(('propA', "42") in obj.ExpressionEngine) + self.Doc.redo() + self.assertTrue(("propB", None) in obj.ExpressionEngine) + self.assertTrue(("propA", "42") in obj.ExpressionEngine) - self.Doc.redo() - self.assertTrue(('propB', None) in obj.ExpressionEngine) - self.assertTrue(('propA', "42") in obj.ExpressionEngine) + self.Doc.recompute() + obj.ExpressionEngine - self.Doc.recompute() - obj.ExpressionEngine + TempPath = tempfile.gettempdir() + SaveName = TempPath + os.sep + "ExpressionTests.FCStd" + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument(self.Doc.Name) + self.Doc = FreeCAD.openDocument(SaveName) - TempPath = tempfile.gettempdir() - SaveName = TempPath + os.sep + "ExpressionTests.FCStd" - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument(self.Doc.Name) - self.Doc = FreeCAD.openDocument(SaveName) + def testCyclicDependencyOnPlacement(self): + obj = self.Doc.addObject("App::FeaturePython", "Python") + obj.addProperty("App::PropertyPlacement", "Placement") + obj.setExpression(".Placement.Base.x", ".Placement.Base.y + 10mm") + with self.assertRaises(RuntimeError): + obj.setExpression(".Placement.Base.y", ".Placement.Base.x + 10mm") - def testCyclicDependencyOnPlacement(self): - obj = self.Doc.addObject("App::FeaturePython","Python") - obj.addProperty("App::PropertyPlacement", "Placement") - obj.setExpression('.Placement.Base.x', '.Placement.Base.y + 10mm') - with self.assertRaises(RuntimeError): - obj.setExpression('.Placement.Base.y', '.Placement.Base.x + 10mm') - - def tearDown(self): - #closing doc - FreeCAD.closeDocument(self.Doc.Name) + def tearDown(self): + # closing doc + FreeCAD.closeDocument(self.Doc.Name) class DocumentObserverCases(unittest.TestCase): + class Observer: + def __init__(self): + self.clear() - class Observer(): + def clear(self): + self.signal = [] + self.parameter = [] + self.parameter2 = [] - def __init__(self): - self.clear() + def slotCreatedDocument(self, doc): + self.signal.append("DocCreated") + self.parameter.append(doc) - def clear(self): - self.signal = [] - self.parameter = [] - self.parameter2 = [] + def slotDeletedDocument(self, doc): + self.signal.append("DocDeleted") + self.parameter.append(doc) - def slotCreatedDocument(self, doc): - self.signal.append('DocCreated'); - self.parameter.append(doc); + def slotRelabelDocument(self, doc): + self.signal.append("DocRelabled") + self.parameter.append(doc) - def slotDeletedDocument(self, doc): - self.signal.append('DocDeleted'); - self.parameter.append(doc); + def slotActivateDocument(self, doc): + self.signal.append("DocActivated") + self.parameter.append(doc) - def slotRelabelDocument(self, doc): - self.signal.append('DocRelabled'); - self.parameter.append(doc); + def slotRecomputedDocument(self, doc): + self.signal.append("DocRecomputed") + self.parameter.append(doc) - def slotActivateDocument(self, doc): - self.signal.append('DocActivated'); - self.parameter.append(doc); + def slotUndoDocument(self, doc): + self.signal.append("DocUndo") + self.parameter.append(doc) - def slotRecomputedDocument(self, doc): - self.signal.append('DocRecomputed'); - self.parameter.append(doc); + def slotRedoDocument(self, doc): + self.signal.append("DocRedo") + self.parameter.append(doc) - def slotUndoDocument(self, doc): - self.signal.append('DocUndo'); - self.parameter.append(doc); + def slotOpenTransaction(self, doc, name): + self.signal.append("DocOpenTransaction") + self.parameter.append(doc) + self.parameter2.append(name) - def slotRedoDocument(self, doc): - self.signal.append('DocRedo'); - self.parameter.append(doc); + def slotCommitTransaction(self, doc): + self.signal.append("DocCommitTransaction") + self.parameter.append(doc) - def slotOpenTransaction(self, doc, name): - self.signal.append('DocOpenTransaction'); - self.parameter.append(doc); - self.parameter2.append(name); + def slotAbortTransaction(self, doc): + self.signal.append("DocAbortTransaction") + self.parameter.append(doc) - def slotCommitTransaction(self, doc): - self.signal.append('DocCommitTransaction'); - self.parameter.append(doc); + def slotBeforeChangeDocument(self, doc, prop): + self.signal.append("DocBeforeChange") + self.parameter.append(doc) + self.parameter2.append(prop) - def slotAbortTransaction(self, doc): - self.signal.append('DocAbortTransaction'); - self.parameter.append(doc); + def slotChangedDocument(self, doc, prop): + self.signal.append("DocChanged") + self.parameter.append(doc) + self.parameter2.append(prop) - def slotBeforeChangeDocument(self, doc, prop): - self.signal.append('DocBeforeChange') - self.parameter.append(doc) - self.parameter2.append(prop) + def slotCreatedObject(self, obj): + self.signal.append("ObjCreated") + self.parameter.append(obj) - def slotChangedDocument(self, doc, prop): - self.signal.append('DocChanged') - self.parameter.append(doc) - self.parameter2.append(prop) + def slotDeletedObject(self, obj): + self.signal.append("ObjDeleted") + self.parameter.append(obj) - def slotCreatedObject(self, obj): - self.signal.append('ObjCreated'); - self.parameter.append(obj); + def slotChangedObject(self, obj, prop): + self.signal.append("ObjChanged") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotDeletedObject(self, obj): - self.signal.append('ObjDeleted'); - self.parameter.append(obj) + def slotBeforeChangeObject(self, obj, prop): + self.signal.append("ObjBeforeChange") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotChangedObject(self, obj, prop): - self.signal.append('ObjChanged'); - self.parameter.append(obj) - self.parameter2.append(prop) + def slotRecomputedObject(self, obj): + self.signal.append("ObjRecomputed") + self.parameter.append(obj) - def slotBeforeChangeObject(self, obj, prop): - self.signal.append('ObjBeforeChange'); - self.parameter.append(obj) - self.parameter2.append(prop) + def slotAppendDynamicProperty(self, obj, prop): + self.signal.append("ObjAddDynProp") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotRecomputedObject(self, obj): - self.signal.append('ObjRecomputed'); - self.parameter.append(obj) + def slotRemoveDynamicProperty(self, obj, prop): + self.signal.append("ObjRemoveDynProp") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotAppendDynamicProperty(self, obj, prop): - self.signal.append('ObjAddDynProp'); - self.parameter.append(obj) - self.parameter2.append(prop) + def slotChangePropertyEditor(self, obj, prop): + self.signal.append("ObjChangePropEdit") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotRemoveDynamicProperty(self, obj, prop): - self.signal.append('ObjRemoveDynProp'); - self.parameter.append(obj) - self.parameter2.append(prop) + def slotStartSaveDocument(self, obj, name): + self.signal.append("DocStartSave") + self.parameter.append(obj) + self.parameter2.append(name) - def slotChangePropertyEditor(self, obj, prop): - self.signal.append('ObjChangePropEdit'); - self.parameter.append(obj) - self.parameter2.append(prop) + def slotFinishSaveDocument(self, obj, name): + self.signal.append("DocFinishSave") + self.parameter.append(obj) + self.parameter2.append(name) - def slotStartSaveDocument(self, obj, name): - self.signal.append('DocStartSave') - self.parameter.append(obj) - self.parameter2.append(name) + def slotBeforeAddingDynamicExtension(self, obj, extension): + self.signal.append("ObjBeforeDynExt") + self.parameter.append(obj) + self.parameter2.append(extension) - def slotFinishSaveDocument(self, obj, name): - self.signal.append('DocFinishSave') - self.parameter.append(obj) - self.parameter2.append(name) + def slotAddedDynamicExtension(self, obj, extension): + self.signal.append("ObjDynExt") + self.parameter.append(obj) + self.parameter2.append(extension) - def slotBeforeAddingDynamicExtension(self, obj, extension): - self.signal.append('ObjBeforeDynExt') - self.parameter.append(obj) - self.parameter2.append(extension) + class GuiObserver: + def __init__(self): + self.clear() - def slotAddedDynamicExtension(self, obj, extension): - self.signal.append('ObjDynExt') - self.parameter.append(obj) - self.parameter2.append(extension) + def clear(self): + self.signal = [] + self.parameter = [] + self.parameter2 = [] - class GuiObserver(): + def slotCreatedDocument(self, doc): + self.signal.append("DocCreated") + self.parameter.append(doc) - def __init__(self): - self.clear() + def slotDeletedDocument(self, doc): + self.signal.append("DocDeleted") + self.parameter.append(doc) - def clear(self): - self.signal = [] - self.parameter = [] - self.parameter2 = [] + def slotRelabelDocument(self, doc): + self.signal.append("DocRelabled") + self.parameter.append(doc) - def slotCreatedDocument(self, doc): - self.signal.append('DocCreated'); - self.parameter.append(doc); + def slotRenameDocument(self, doc): + self.signal.append("DocRenamed") + self.parameter.append(doc) - def slotDeletedDocument(self, doc): - self.signal.append('DocDeleted'); - self.parameter.append(doc); + def slotActivateDocument(self, doc): + self.signal.append("DocActivated") + self.parameter.append(doc) - def slotRelabelDocument(self, doc): - self.signal.append('DocRelabled'); - self.parameter.append(doc); + def slotCreatedObject(self, obj): + self.signal.append("ObjCreated") + self.parameter.append(obj) - def slotRenameDocument(self, doc): - self.signal.append('DocRenamed'); - self.parameter.append(doc); + def slotDeletedObject(self, obj): + self.signal.append("ObjDeleted") + self.parameter.append(obj) - def slotActivateDocument(self, doc): - self.signal.append('DocActivated'); - self.parameter.append(doc); + def slotChangedObject(self, obj, prop): + self.signal.append("ObjChanged") + self.parameter.append(obj) + self.parameter2.append(prop) - def slotCreatedObject(self, obj): - self.signal.append('ObjCreated'); - self.parameter.append(obj); + def slotInEdit(self, obj): + self.signal.append("ObjInEdit") + self.parameter.append(obj) - def slotDeletedObject(self, obj): - self.signal.append('ObjDeleted'); - self.parameter.append(obj) + def slotResetEdit(self, obj): + self.signal.append("ObjResetEdit") + self.parameter.append(obj) - def slotChangedObject(self, obj, prop): - self.signal.append('ObjChanged'); - self.parameter.append(obj) - self.parameter2.append(prop) + def setUp(self): + self.Obs = self.Observer() + FreeCAD.addDocumentObserver(self.Obs) - def slotInEdit(self, obj): - self.signal.append('ObjInEdit'); - self.parameter.append(obj) + def testRemoveObserver(self): + FreeCAD.removeDocumentObserver(self.Obs) + self.Obs.clear() + self.Doc1 = FreeCAD.newDocument("Observer") + FreeCAD.closeDocument(self.Doc1.Name) + self.assertEqual(len(self.Obs.signal), 0) + self.assertEqual(len(self.Obs.parameter2), 0) + self.assertEqual(len(self.Obs.signal), 0) + FreeCAD.addDocumentObserver(self.Obs) - def slotResetEdit(self, obj): - self.signal.append('ObjResetEdit'); - self.parameter.append(obj) + def testSave(self): + TempPath = tempfile.gettempdir() + SaveName = TempPath + os.sep + "SaveRestoreTests.FCStd" + self.Doc1 = FreeCAD.newDocument("Observer1") + self.Doc1.saveAs(SaveName) + self.assertEqual(self.Obs.signal.pop(), "DocFinishSave") + self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName) + self.assertEqual(self.Obs.signal.pop(), "DocStartSave") + self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName) + FreeCAD.closeDocument(self.Doc1.Name) - def setUp(self): - self.Obs = self.Observer(); - FreeCAD.addDocumentObserver(self.Obs); + def testDocument(self): + # in case another document already exists then the tests cannot + # be done reliably + if FreeCAD.GuiUp and FreeCAD.activeDocument(): + return - def testRemoveObserver(self): - FreeCAD.removeDocumentObserver(self.Obs) - self.Obs.clear() - self.Doc1 = FreeCAD.newDocument("Observer") - FreeCAD.closeDocument(self.Doc1.Name) - self.assertEqual(len(self.Obs.signal), 0) - self.assertEqual(len(self.Obs.parameter2), 0) - self.assertEqual(len(self.Obs.signal), 0) - FreeCAD.addDocumentObserver(self.Obs); + # testing document level signals + self.Doc1 = FreeCAD.newDocument("Observer1") + if FreeCAD.GuiUp: + self.assertEqual(self.Obs.signal.pop(0), "DocActivated") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.signal.pop(0), "DocCreated") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.signal.pop(0), "DocBeforeChange") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.parameter2.pop(0), "Label") + self.assertEqual(self.Obs.signal.pop(0), "DocChanged") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.parameter2.pop(0), "Label") + self.assertEqual(self.Obs.signal.pop(0), "DocRelabled") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - def testSave(self): - TempPath = tempfile.gettempdir() - SaveName = TempPath + os.sep + "SaveRestoreTests.FCStd" - self.Doc1 = FreeCAD.newDocument("Observer1"); - self.Doc1.saveAs(SaveName) - self.assertEqual(self.Obs.signal.pop(), 'DocFinishSave') - self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName) - self.assertEqual(self.Obs.signal.pop(), 'DocStartSave') - self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName) - FreeCAD.closeDocument(self.Doc1.Name) + self.Doc2 = FreeCAD.newDocument("Observer2") + if FreeCAD.GuiUp: + self.assertEqual(self.Obs.signal.pop(0), "DocActivated") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) + self.assertEqual(self.Obs.signal.pop(0), "DocCreated") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) + self.assertEqual(self.Obs.signal.pop(0), "DocBeforeChange") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) + self.assertEqual(self.Obs.parameter2.pop(0), "Label") + self.assertEqual(self.Obs.signal.pop(0), "DocChanged") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) + self.assertEqual(self.Obs.parameter2.pop(0), "Label") + self.assertEqual(self.Obs.signal.pop(0), "DocRelabled") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - def testDocument(self): - # in case another document already exists then the tests cannot - # be done reliably - if FreeCAD.GuiUp and FreeCAD.activeDocument(): - return - - # testing document level signals - self.Doc1 = FreeCAD.newDocument("Observer1"); - if FreeCAD.GuiUp: - self.assertEqual(self.Obs.signal.pop(0), 'DocActivated') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.signal.pop(0), 'DocCreated') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.signal.pop(0), 'DocBeforeChange') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.parameter2.pop(0), 'Label') - self.assertEqual(self.Obs.signal.pop(0), 'DocChanged') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.parameter2.pop(0), 'Label') - self.assertEqual(self.Obs.signal.pop(0), 'DocRelabled') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - - self.Doc2 = FreeCAD.newDocument("Observer2"); - if FreeCAD.GuiUp: - self.assertEqual(self.Obs.signal.pop(0), 'DocActivated') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) - self.assertEqual(self.Obs.signal.pop(0), 'DocCreated') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) - self.assertEqual(self.Obs.signal.pop(0), 'DocBeforeChange') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) - self.assertEqual(self.Obs.parameter2.pop(0), 'Label') - self.assertEqual(self.Obs.signal.pop(0), 'DocChanged') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) - self.assertEqual(self.Obs.parameter2.pop(0), 'Label') - self.assertEqual(self.Obs.signal.pop(0), 'DocRelabled') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc2) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - - FreeCAD.setActiveDocument('Observer1') - self.assertEqual(self.Obs.signal.pop(), 'DocActivated') - self.assertTrue(self.Obs.parameter.pop() is self.Doc1) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - - #undo/redo is not enabled in cmd line mode by default - self.Doc2.UndoMode = 1 - - # Must set Doc2 as active document before start transaction test. If not, - # then a transaction will be auto created inside the active document if a - # new transaction is triggered from a non active document - FreeCAD.setActiveDocument('Observer2') - self.assertEqual(self.Obs.signal.pop(), 'DocActivated') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - - self.Doc2.openTransaction('test') - # openTransaction() now only setup pending transaction, which will only be - # created when there is actual change - self.Doc2.addObject('App::FeatureTest','test') - self.assertEqual(self.Obs.signal[0], 'DocOpenTransaction') - self.assertEqual(self.Obs.signal.count('DocOpenTransaction'),1) - self.assertTrue(self.Obs.parameter[0] is self.Doc2) - self.assertEqual(self.Obs.parameter2[0], 'test') - self.Obs.clear() - - self.Doc2.commitTransaction() - self.assertEqual(self.Obs.signal.pop(), 'DocCommitTransaction') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - - self.Doc2.openTransaction('test2') - # openTransaction() now only setup pending transaction, which will only be - # created when there is actual change - self.Doc2.addObject('App::FeatureTest','test') - self.assertEqual(self.Obs.signal[0], 'DocOpenTransaction') - self.assertEqual(self.Obs.signal.count('DocOpenTransaction'),1) - self.assertTrue(self.Obs.parameter[0] is self.Doc2) - self.assertEqual(self.Obs.parameter2[0], 'test2') - # there will be other signals because of the addObject() - self.Obs.clear() - - self.Doc2.abortTransaction() - self.assertEqual(self.Obs.signal.pop(), 'DocAbortTransaction') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - # there will be other signals because of aborting the above addObject() - self.Obs.clear() - - self.Doc2.undo() - self.assertEqual(self.Obs.signal.pop(), 'DocUndo') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - # there will be other signals because undoing the above addObject() - self.Obs.clear() - - self.Doc2.redo() - self.assertEqual(self.Obs.signal.pop(), 'DocRedo') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - # there will be other signals because redoing the above addObject() - self.Obs.clear() - - self.Doc1.Comment = 'test comment' - self.assertEqual(self.Obs.signal.pop(0), 'DocBeforeChange') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.parameter2.pop(0), 'Comment') - self.assertEqual(self.Obs.signal.pop(0), 'DocChanged') - self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) - self.assertEqual(self.Obs.parameter2.pop(0), 'Comment') - - FreeCAD.closeDocument(self.Doc2.Name) - self.assertEqual(self.Obs.signal.pop(), 'DocDeleted') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - if FreeCAD.GuiUp: - # only has document activated signal when running in GUI mode - self.assertEqual(self.Obs.signal.pop(), 'DocActivated') + FreeCAD.setActiveDocument("Observer1") + self.assertEqual(self.Obs.signal.pop(), "DocActivated") self.assertTrue(self.Obs.parameter.pop() is self.Doc1) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - FreeCAD.closeDocument(self.Doc1.Name) - self.assertEqual(self.Obs.signal.pop(), 'DocDeleted') - self.assertEqual(self.Obs.parameter.pop(), self.Doc1) - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + # undo/redo is not enabled in cmd line mode by default + self.Doc2.UndoMode = 1 - def testObject(self): - #testing signal on object changes + # Must set Doc2 as active document before start transaction test. If not, + # then a transaction will be auto created inside the active document if a + # new transaction is triggered from a non active document + FreeCAD.setActiveDocument("Observer2") + self.assertEqual(self.Obs.signal.pop(), "DocActivated") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.Doc1 = FreeCAD.newDocument("Observer1") - self.Obs.clear() + self.Doc2.openTransaction("test") + # openTransaction() now only setup pending transaction, which will only be + # created when there is actual change + self.Doc2.addObject("App::FeatureTest", "test") + self.assertEqual(self.Obs.signal[0], "DocOpenTransaction") + self.assertEqual(self.Obs.signal.count("DocOpenTransaction"), 1) + self.assertTrue(self.Obs.parameter[0] is self.Doc2) + self.assertEqual(self.Obs.parameter2[0], "test") + self.Obs.clear() - obj = self.Doc1.addObject("App::DocumentObject","obj") - self.failUnless(self.Obs.signal.pop() == 'ObjCreated') - self.failUnless(self.Obs.parameter.pop() is obj) - #there are multiple object change signals - self.Obs.clear() + self.Doc2.commitTransaction() + self.assertEqual(self.Obs.signal.pop(), "DocCommitTransaction") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - obj.Label = "myobj" - self.failUnless(self.Obs.signal.pop(0) == 'ObjBeforeChange') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(self.Obs.parameter2.pop(0) == "Label") - self.failUnless(self.Obs.signal.pop(0) == 'ObjChanged') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(self.Obs.parameter2.pop(0) == "Label") - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.Doc2.openTransaction("test2") + # openTransaction() now only setup pending transaction, which will only be + # created when there is actual change + self.Doc2.addObject("App::FeatureTest", "test") + self.assertEqual(self.Obs.signal[0], "DocOpenTransaction") + self.assertEqual(self.Obs.signal.count("DocOpenTransaction"), 1) + self.assertTrue(self.Obs.parameter[0] is self.Doc2) + self.assertEqual(self.Obs.parameter2[0], "test2") + # there will be other signals because of the addObject() + self.Obs.clear() - obj.enforceRecompute() - obj.recompute() - self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.Doc2.abortTransaction() + self.assertEqual(self.Obs.signal.pop(), "DocAbortTransaction") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + # there will be other signals because of aborting the above addObject() + self.Obs.clear() - obj.enforceRecompute() - self.Doc1.recompute() - self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(self.Obs.signal.pop(0) == 'DocRecomputed') - self.failUnless(self.Obs.parameter.pop(0) is self.Doc1) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.Doc2.undo() + self.assertEqual(self.Obs.signal.pop(), "DocUndo") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + # there will be other signals because undoing the above addObject() + self.Obs.clear() - FreeCAD.ActiveDocument.removeObject(obj.Name) - self.failUnless(self.Obs.signal.pop(0) == 'ObjDeleted') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.Doc2.redo() + self.assertEqual(self.Obs.signal.pop(), "DocRedo") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + # there will be other signals because redoing the above addObject() + self.Obs.clear() - pyobj = self.Doc1.addObject("App::FeaturePython","pyobj") - self.Obs.clear() - pyobj.addProperty("App::PropertyLength","Prop","Group","test property") - self.failUnless(self.Obs.signal.pop() == 'ObjAddDynProp') - self.failUnless(self.Obs.parameter.pop() is pyobj) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.Doc1.Comment = "test comment" + self.assertEqual(self.Obs.signal.pop(0), "DocBeforeChange") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.parameter2.pop(0), "Comment") + self.assertEqual(self.Obs.signal.pop(0), "DocChanged") + self.assertTrue(self.Obs.parameter.pop(0) is self.Doc1) + self.assertEqual(self.Obs.parameter2.pop(0), "Comment") - pyobj.setEditorMode('Prop', ['ReadOnly']) - self.failUnless(self.Obs.signal.pop() == 'ObjChangePropEdit') - self.failUnless(self.Obs.parameter.pop() is pyobj) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + FreeCAD.closeDocument(self.Doc2.Name) + self.assertEqual(self.Obs.signal.pop(), "DocDeleted") + self.assertTrue(self.Obs.parameter.pop() is self.Doc2) + if FreeCAD.GuiUp: + # only has document activated signal when running in GUI mode + self.assertEqual(self.Obs.signal.pop(), "DocActivated") + self.assertTrue(self.Obs.parameter.pop() is self.Doc1) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - pyobj.removeProperty('Prop') - self.failUnless(self.Obs.signal.pop() == 'ObjRemoveDynProp') - self.failUnless(self.Obs.parameter.pop() is pyobj) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + FreeCAD.closeDocument(self.Doc1.Name) + self.assertEqual(self.Obs.signal.pop(), "DocDeleted") + self.assertEqual(self.Obs.parameter.pop(), self.Doc1) + self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - pyobj.addExtension("App::GroupExtensionPython") - self.failUnless(self.Obs.signal.pop() == 'ObjDynExt') - self.failUnless(self.Obs.parameter.pop() is pyobj) - self.failUnless(self.Obs.parameter2.pop() == 'App::GroupExtensionPython') - self.failUnless(self.Obs.signal.pop(0) == 'ObjBeforeDynExt') - self.failUnless(self.Obs.parameter.pop(0) is pyobj) - self.failUnless(self.Obs.parameter2.pop(0) == 'App::GroupExtensionPython') - #a proxy property was changed, hence those events are also in the signal list - self.Obs.clear() + def testObject(self): + # testing signal on object changes - FreeCAD.closeDocument(self.Doc1.Name) - self.Obs.clear() + self.Doc1 = FreeCAD.newDocument("Observer1") + self.Obs.clear() - def testUndoDisabledDocument(self): + obj = self.Doc1.addObject("App::DocumentObject", "obj") + self.failUnless(self.Obs.signal.pop() == "ObjCreated") + self.failUnless(self.Obs.parameter.pop() is obj) + # there are multiple object change signals + self.Obs.clear() - # testing document level signals - self.Doc1 = FreeCAD.newDocument("Observer1"); - self.Doc1.UndoMode = 0 - self.Obs.clear() + obj.Label = "myobj" + self.failUnless(self.Obs.signal.pop(0) == "ObjBeforeChange") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(self.Obs.parameter2.pop(0) == "Label") + self.failUnless(self.Obs.signal.pop(0) == "ObjChanged") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(self.Obs.parameter2.pop(0) == "Label") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.Doc1.openTransaction('test') - self.Doc1.commitTransaction() - self.Doc1.undo() - self.Doc1.redo() - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + obj.enforceRecompute() + obj.recompute() + self.failUnless(self.Obs.signal.pop(0) == "ObjRecomputed") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - FreeCAD.closeDocument(self.Doc1.Name) - self.Obs.clear() + obj.enforceRecompute() + self.Doc1.recompute() + self.failUnless(self.Obs.signal.pop(0) == "ObjRecomputed") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(self.Obs.signal.pop(0) == "DocRecomputed") + self.failUnless(self.Obs.parameter.pop(0) is self.Doc1) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - def testGuiObserver(self): + FreeCAD.ActiveDocument.removeObject(obj.Name) + self.failUnless(self.Obs.signal.pop(0) == "ObjDeleted") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - if not FreeCAD.GuiUp: - return + pyobj = self.Doc1.addObject("App::FeaturePython", "pyobj") + self.Obs.clear() + pyobj.addProperty("App::PropertyLength", "Prop", "Group", "test property") + self.failUnless(self.Obs.signal.pop() == "ObjAddDynProp") + self.failUnless(self.Obs.parameter.pop() is pyobj) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - # in case another document already exists then the tests cannot - # be done reliably - if FreeCAD.activeDocument(): - return + pyobj.setEditorMode("Prop", ["ReadOnly"]) + self.failUnless(self.Obs.signal.pop() == "ObjChangePropEdit") + self.failUnless(self.Obs.parameter.pop() is pyobj) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.GuiObs = self.GuiObserver() - FreeCAD.Gui.addDocumentObserver(self.GuiObs) - self.Doc1 = FreeCAD.newDocument("Observer1"); - self.GuiDoc1 = FreeCAD.Gui.getDocument(self.Doc1.Name) - self.Obs.clear() - self.failUnless(self.GuiObs.signal.pop(0) == 'DocCreated') - self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) - self.failUnless(self.GuiObs.signal.pop(0) == 'DocActivated') - self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) - self.failUnless(self.GuiObs.signal.pop(0) == 'DocRelabled') - self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + pyobj.removeProperty("Prop") + self.failUnless(self.Obs.signal.pop() == "ObjRemoveDynProp") + self.failUnless(self.Obs.parameter.pop() is pyobj) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.Doc1.Label = "test" - self.failUnless(self.Obs.signal.pop() == 'DocRelabled') - self.failUnless(self.Obs.parameter.pop() is self.Doc1) - #not interested in the change signals - self.Obs.clear() - self.failUnless(self.GuiObs.signal.pop(0) == 'DocRelabled') - self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + pyobj.addExtension("App::GroupExtensionPython") + self.failUnless(self.Obs.signal.pop() == "ObjDynExt") + self.failUnless(self.Obs.parameter.pop() is pyobj) + self.failUnless(self.Obs.parameter2.pop() == "App::GroupExtensionPython") + self.failUnless(self.Obs.signal.pop(0) == "ObjBeforeDynExt") + self.failUnless(self.Obs.parameter.pop(0) is pyobj) + self.failUnless(self.Obs.parameter2.pop(0) == "App::GroupExtensionPython") + # a proxy property was changed, hence those events are also in the signal list + self.Obs.clear() - FreeCAD.setActiveDocument(self.Doc1.Name) - self.failUnless(self.Obs.signal.pop() == 'DocActivated') - self.failUnless(self.Obs.parameter.pop() is self.Doc1) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(self.GuiObs.signal.pop() == 'DocActivated') - self.failUnless(self.GuiObs.parameter.pop() is self.GuiDoc1) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + FreeCAD.closeDocument(self.Doc1.Name) + self.Obs.clear() - obj = self.Doc1.addObject("App::FeaturePython","obj") - self.failUnless(self.Obs.signal.pop() == 'ObjCreated') - self.failUnless(self.Obs.parameter.pop() is obj) - #there are multiple object change signals - self.Obs.clear() - self.failUnless(self.GuiObs.signal.pop() == "ObjCreated") - self.failUnless(self.GuiObs.parameter.pop() is obj.ViewObject) + def testUndoDisabledDocument(self): - # There are object change signals, caused by sync of obj.Visibility. Same below. - self.GuiObs.clear() + # testing document level signals + self.Doc1 = FreeCAD.newDocument("Observer1") + self.Doc1.UndoMode = 0 + self.Obs.clear() - obj.ViewObject.Visibility = False - self.failUnless(self.Obs.signal.pop() == "ObjChanged") - self.failUnless(self.Obs.parameter.pop() is obj) - self.failUnless(self.Obs.parameter2.pop() == "Visibility") - self.failUnless(self.Obs.signal.pop() == "ObjBeforeChange") - self.failUnless(self.Obs.parameter.pop() is obj) - self.failUnless(self.Obs.parameter2.pop() == "Visibility") - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(self.GuiObs.signal.pop(0) == 'ObjChanged') - self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) - self.failUnless(self.GuiObs.parameter2.pop(0) == "Visibility") - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + self.Doc1.openTransaction("test") + self.Doc1.commitTransaction() + self.Doc1.undo() + self.Doc1.redo() + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - obj.ViewObject.addProperty("App::PropertyLength","Prop","Group","test property") - self.failUnless(self.Obs.signal.pop() == 'ObjAddDynProp') - self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + FreeCAD.closeDocument(self.Doc1.Name) + self.Obs.clear() - obj.ViewObject.setEditorMode('Prop', ['ReadOnly']) - self.failUnless(self.Obs.signal.pop() == 'ObjChangePropEdit') - self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + def testGuiObserver(self): - obj.ViewObject.removeProperty('Prop') - self.failUnless(self.Obs.signal.pop() == 'ObjRemoveDynProp') - self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) - self.failUnless(self.Obs.parameter2.pop() == 'Prop') - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + if not FreeCAD.GuiUp: + return - self.GuiDoc1.setEdit('obj', 0) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(self.GuiObs.signal.pop(0) == 'ObjInEdit') - self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + # in case another document already exists then the tests cannot + # be done reliably + if FreeCAD.activeDocument(): + return - self.GuiDoc1.resetEdit() - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(self.GuiObs.signal.pop(0) == 'ObjResetEdit') - self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + self.GuiObs = self.GuiObserver() + FreeCAD.Gui.addDocumentObserver(self.GuiObs) + self.Doc1 = FreeCAD.newDocument("Observer1") + self.GuiDoc1 = FreeCAD.Gui.getDocument(self.Doc1.Name) + self.Obs.clear() + self.failUnless(self.GuiObs.signal.pop(0) == "DocCreated") + self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) + self.failUnless(self.GuiObs.signal.pop(0) == "DocActivated") + self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) + self.failUnless(self.GuiObs.signal.pop(0) == "DocRelabled") + self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) - obj.ViewObject.addExtension("Gui::ViewProviderGroupExtensionPython") - self.failUnless(self.Obs.signal.pop() == 'ObjDynExt') - self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) - self.failUnless(self.Obs.parameter2.pop() == 'Gui::ViewProviderGroupExtensionPython') - self.failUnless(self.Obs.signal.pop() == 'ObjBeforeDynExt') - self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) - self.failUnless(self.Obs.parameter2.pop() == 'Gui::ViewProviderGroupExtensionPython') - #a proxy property was changed, hence those events are also in the signal list (but of GUI observer) - self.GuiObs.clear() + self.Doc1.Label = "test" + self.failUnless(self.Obs.signal.pop() == "DocRelabled") + self.failUnless(self.Obs.parameter.pop() is self.Doc1) + # not interested in the change signals + self.Obs.clear() + self.failUnless(self.GuiObs.signal.pop(0) == "DocRelabled") + self.failUnless(self.GuiObs.parameter.pop(0) is self.GuiDoc1) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) - vo = obj.ViewObject - FreeCAD.ActiveDocument.removeObject(obj.Name) - self.failUnless(self.Obs.signal.pop(0) == 'ObjDeleted') - self.failUnless(self.Obs.parameter.pop(0) is obj) - self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) - self.failUnless(self.GuiObs.signal.pop() == 'ObjDeleted') - self.failUnless(self.GuiObs.parameter.pop() is vo) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + FreeCAD.setActiveDocument(self.Doc1.Name) + self.failUnless(self.Obs.signal.pop() == "DocActivated") + self.failUnless(self.Obs.parameter.pop() is self.Doc1) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless(self.GuiObs.signal.pop() == "DocActivated") + self.failUnless(self.GuiObs.parameter.pop() is self.GuiDoc1) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) - FreeCAD.closeDocument(self.Doc1.Name) - self.Obs.clear() - self.failUnless(self.GuiObs.signal.pop() == 'DocDeleted') - self.failUnless(self.GuiObs.parameter.pop() is self.GuiDoc1) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + obj = self.Doc1.addObject("App::FeaturePython", "obj") + self.failUnless(self.Obs.signal.pop() == "ObjCreated") + self.failUnless(self.Obs.parameter.pop() is obj) + # there are multiple object change signals + self.Obs.clear() + self.failUnless(self.GuiObs.signal.pop() == "ObjCreated") + self.failUnless(self.GuiObs.parameter.pop() is obj.ViewObject) - FreeCAD.Gui.removeDocumentObserver(self.GuiObs) - self.GuiObs.clear() + # There are object change signals, caused by sync of obj.Visibility. Same below. + self.GuiObs.clear() + + obj.ViewObject.Visibility = False + self.failUnless(self.Obs.signal.pop() == "ObjChanged") + self.failUnless(self.Obs.parameter.pop() is obj) + self.failUnless(self.Obs.parameter2.pop() == "Visibility") + self.failUnless(self.Obs.signal.pop() == "ObjBeforeChange") + self.failUnless(self.Obs.parameter.pop() is obj) + self.failUnless(self.Obs.parameter2.pop() == "Visibility") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless(self.GuiObs.signal.pop(0) == "ObjChanged") + self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) + self.failUnless(self.GuiObs.parameter2.pop(0) == "Visibility") + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + obj.ViewObject.addProperty("App::PropertyLength", "Prop", "Group", "test property") + self.failUnless(self.Obs.signal.pop() == "ObjAddDynProp") + self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + obj.ViewObject.setEditorMode("Prop", ["ReadOnly"]) + self.failUnless(self.Obs.signal.pop() == "ObjChangePropEdit") + self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + obj.ViewObject.removeProperty("Prop") + self.failUnless(self.Obs.signal.pop() == "ObjRemoveDynProp") + self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) + self.failUnless(self.Obs.parameter2.pop() == "Prop") + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + self.GuiDoc1.setEdit("obj", 0) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless(self.GuiObs.signal.pop(0) == "ObjInEdit") + self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + self.GuiDoc1.resetEdit() + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless(self.GuiObs.signal.pop(0) == "ObjResetEdit") + self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + obj.ViewObject.addExtension("Gui::ViewProviderGroupExtensionPython") + self.failUnless(self.Obs.signal.pop() == "ObjDynExt") + self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) + self.failUnless(self.Obs.parameter2.pop() == "Gui::ViewProviderGroupExtensionPython") + self.failUnless(self.Obs.signal.pop() == "ObjBeforeDynExt") + self.failUnless(self.Obs.parameter.pop() is obj.ViewObject) + self.failUnless(self.Obs.parameter2.pop() == "Gui::ViewProviderGroupExtensionPython") + # a proxy property was changed, hence those events are also in the signal list (but of GUI observer) + self.GuiObs.clear() + + vo = obj.ViewObject + FreeCAD.ActiveDocument.removeObject(obj.Name) + self.failUnless(self.Obs.signal.pop(0) == "ObjDeleted") + self.failUnless(self.Obs.parameter.pop(0) is obj) + self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + self.failUnless(self.GuiObs.signal.pop() == "ObjDeleted") + self.failUnless(self.GuiObs.parameter.pop() is vo) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + FreeCAD.closeDocument(self.Doc1.Name) + self.Obs.clear() + self.failUnless(self.GuiObs.signal.pop() == "DocDeleted") + self.failUnless(self.GuiObs.parameter.pop() is self.GuiDoc1) + self.failUnless( + not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2 + ) + + FreeCAD.Gui.removeDocumentObserver(self.GuiObs) + self.GuiObs.clear() + + def tearDown(self): + # closing doc + FreeCAD.removeDocumentObserver(self.Obs) + self.Obs.clear() + self.Obs = None - def tearDown(self): - #closing doc - FreeCAD.removeDocumentObserver(self.Obs) - self.Obs.clear() - self.Obs = None class FeatureTestColumn(unittest.TestCase): def setUp(self): @@ -2299,7 +2409,6 @@ class FeatureTestColumn(unittest.TestCase): FreeCAD.closeDocument("TestColumn") - class FeatureTestRow(unittest.TestCase): def setUp(self): doc = FreeCAD.newDocument("TestRow") @@ -2351,7 +2460,6 @@ class FeatureTestRow(unittest.TestCase): FreeCAD.closeDocument("TestRow") - class FeatureTestAbsAddress(unittest.TestCase): def setUp(self): doc = FreeCAD.newDocument("TestAbsAddress") diff --git a/src/Mod/Test/Gui/AppTestGui.cpp b/src/Mod/Test/Gui/AppTestGui.cpp index 0efb300140..b7e0c9f510 100644 --- a/src/Mod/Test/Gui/AppTestGui.cpp +++ b/src/Mod/Test/Gui/AppTestGui.cpp @@ -31,23 +31,37 @@ #include "UnitTestPy.h" -class ILoggerBlockerTest : public Base::ILogger +class ILoggerBlockerTest: public Base::ILogger { public: - ~ILoggerBlockerTest() override {Base::Console().DetachObserver(this);} + ~ILoggerBlockerTest() override + { + Base::Console().DetachObserver(this); + } - const char *Name() override {return "ILoggerBlockerTest";} + const char* Name() override + { + return "ILoggerBlockerTest"; + } - void flush() {buffer.str("");buffer.clear();} + void flush() + { + buffer.str(""); + buffer.clear(); + } - void SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level, - Base::IntendedRecipient recipient, Base::ContentType content) override{ - (void) notifiername; - (void) msg; - (void) recipient; - (void) content; + void SendLog(const std::string& notifiername, + const std::string& msg, + Base::LogStyle level, + Base::IntendedRecipient recipient, + Base::ContentType content) override + { + (void)notifiername; + (void)msg; + (void)recipient; + (void)content; - switch(level){ + switch (level) { case Base::LogStyle::Warning: buffer << "WRN"; break; @@ -68,7 +82,8 @@ public: } } - void runSingleTest(const char* comment, std::string expectedResult) { + void runSingleTest(const char* comment, std::string expectedResult) + { Base::Console().Log(comment); flush(); Base::Console().Log("LOG"); @@ -76,8 +91,10 @@ public: Base::Console().Warning("WRN"); Base::Console().Error("ERR"); Base::Console().Critical("CMS"); - if (buffer.str() != expectedResult) - throw Py::RuntimeError("ILoggerTest: " + buffer.str() + " different from " + expectedResult); + if (buffer.str() != expectedResult) { + throw Py::RuntimeError("ILoggerTest: " + buffer.str() + " different from " + + expectedResult); + } } void runTest() @@ -89,12 +106,16 @@ public: } runSingleTest("Print all", "LOGMSGWRNERRCMS"); { - Base::ILoggerBlocker blocker("ILoggerBlockerTest", Base::ConsoleSingleton::MsgType_Err | Base::ConsoleSingleton::MsgType_Wrn); + Base::ILoggerBlocker blocker("ILoggerBlockerTest", + Base::ConsoleSingleton::MsgType_Err + | Base::ConsoleSingleton::MsgType_Wrn); runSingleTest("Error & Warning blocked", "LOGMSGCMS"); } runSingleTest("Print all", "LOGMSGWRNERRCMS"); { - Base::ILoggerBlocker blocker("ILoggerBlockerTest", Base::ConsoleSingleton::MsgType_Log | Base::ConsoleSingleton::MsgType_Txt); + Base::ILoggerBlocker blocker("ILoggerBlockerTest", + Base::ConsoleSingleton::MsgType_Log + | Base::ConsoleSingleton::MsgType_Txt); runSingleTest("Log & Message blocked", "WRNERRCMS"); } runSingleTest("Print all", "LOGMSGWRNERRCMS"); @@ -102,15 +123,21 @@ public: Base::ILoggerBlocker blocker("ILoggerBlockerTest", Base::ConsoleSingleton::MsgType_Err); runSingleTest("Nested : Error blocked", "LOGMSGWRNCMS"); { - Base::ILoggerBlocker blocker2("ILoggerBlockerTest", Base::ConsoleSingleton::MsgType_Err | Base::ConsoleSingleton::MsgType_Wrn); - runSingleTest("Nested : Warning blocked + Error (from nesting) + Error (redundancy)", "LOGMSGCMS"); + Base::ILoggerBlocker blocker2("ILoggerBlockerTest", + Base::ConsoleSingleton::MsgType_Err + | Base::ConsoleSingleton::MsgType_Wrn); + runSingleTest( + "Nested : Warning blocked + Error (from nesting) + Error (redundancy)", + "LOGMSGCMS"); } runSingleTest("Nested : Error still blocked", "LOGMSGWRNCMS"); } runSingleTest("Print all", "LOGMSGWRNERRCMS"); { Base::ILoggerBlocker blocker("ILoggerBlockerTest"); - Base::Console().SetEnabledMsgType("ILoggerBlockerTest", Base::ConsoleSingleton::MsgType_Log, true); + Base::Console().SetEnabledMsgType("ILoggerBlockerTest", + Base::ConsoleSingleton::MsgType_Log, + true); runSingleTest("Log is enabled but a warning is triggered in debug mode", "LOG"); } runSingleTest("Print all", "LOGMSGWRNERRCMS"); @@ -121,68 +148,77 @@ private: }; -namespace TestGui { -class Module : public Py::ExtensionModule +namespace TestGui +{ +class Module: public Py::ExtensionModule { public: - Module() : Py::ExtensionModule("QtUnitGui") + Module() + : Py::ExtensionModule("QtUnitGui") { TestGui::UnitTestDialogPy::init_type(); - add_varargs_method("UnitTest",&Module::new_UnitTest,"UnitTest"); - add_varargs_method("setTest",&Module::setTest,"setTest"); - add_varargs_method("addTest",&Module::addTest,"addTest"); - add_varargs_method("runTest",&Module::runTest,"runTest"); - add_varargs_method("testILoggerBlocker",&Module::testILoggerBlocker,"testILoggerBlocker"); - initialize("This module is the QtUnitGui module"); // register with Python + add_varargs_method("UnitTest", &Module::new_UnitTest, "UnitTest"); + add_varargs_method("setTest", &Module::setTest, "setTest"); + add_varargs_method("addTest", &Module::addTest, "addTest"); + add_varargs_method("runTest", &Module::runTest, "runTest"); + add_varargs_method("testILoggerBlocker", &Module::testILoggerBlocker, "testILoggerBlocker"); + initialize("This module is the QtUnitGui module");// register with Python } private: Py::Object new_UnitTest(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } return Py::asObject(new TestGui::UnitTestDialogPy()); } Py::Object setTest(const Py::Tuple& args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "|s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "|s", &pstr)) { throw Py::Exception(); + } TestGui::UnitTestDialog* dlg = TestGui::UnitTestDialog::instance(); - if (pstr) + if (pstr) { dlg->setUnitTest(QString::fromLatin1(pstr)); + } dlg->show(); dlg->raise(); return Py::None(); } Py::Object addTest(const Py::Tuple& args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "|s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "|s", &pstr)) { throw Py::Exception(); + } TestGui::UnitTestDialog* dlg = TestGui::UnitTestDialog::instance(); - if (pstr) + if (pstr) { dlg->addUnitTest(QString::fromLatin1(pstr)); + } dlg->show(); dlg->raise(); return Py::None(); } Py::Object runTest(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } TestGui::UnitTestDialog* dlg = TestGui::UnitTestDialog::instance(); bool success = dlg->runCurrentTest(); return Py::Boolean(success); } - Py::Object testILoggerBlocker(const Py::Tuple& args) { - (void) args; + Py::Object testILoggerBlocker(const Py::Tuple& args) + { + (void)args; ILoggerBlockerTest iltest; - Base::Console().AttachObserver(static_cast(&iltest)); + Base::Console().AttachObserver(static_cast(&iltest)); Base::Console().SetConnectionMode(Base::ConsoleSingleton::Direct); iltest.runTest(); return Py::None(); @@ -194,7 +230,7 @@ PyObject* initModule() return Base::Interpreter().addModule(new Module); } -} +}// namespace TestGui void loadTestResource() { diff --git a/src/Mod/Test/Gui/PreCompiled.h b/src/Mod/Test/Gui/PreCompiled.h index 8e0550904d..30bbb6b618 100644 --- a/src/Mod/Test/Gui/PreCompiled.h +++ b/src/Mod/Test/Gui/PreCompiled.h @@ -29,9 +29,9 @@ // point at which warnings of overly long specifiers disabled (needed for VC6) #ifdef _MSC_VER -# pragma warning( disable : 4251 ) -# pragma warning( disable : 4503 ) -# pragma warning( disable : 4786 ) // specifier longer then 255 chars +#pragma warning(disable : 4251) +#pragma warning(disable : 4503) +#pragma warning(disable : 4786)// specifier longer then 255 chars #endif // Qt Toolkit @@ -39,6 +39,6 @@ #include #include -#endif //_PreComp_ +#endif//_PreComp_ -#endif // __PRECOMPILED_GUI__ +#endif// __PRECOMPILED_GUI__ diff --git a/src/Mod/Test/Gui/UnitTestImp.cpp b/src/Mod/Test/Gui/UnitTestImp.cpp index 6916dd17cf..fe8dcedc0d 100644 --- a/src/Mod/Test/Gui/UnitTestImp.cpp +++ b/src/Mod/Test/Gui/UnitTestImp.cpp @@ -22,8 +22,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include @@ -37,7 +37,7 @@ using namespace TestGui; /* TRANSLATOR TestGui::UnitTestDialog */ -UnitTestDialog* UnitTestDialog::_instance=nullptr; +UnitTestDialog* UnitTestDialog::_instance = nullptr; /** * Creates and returns the one and only instance of this dialog. @@ -45,18 +45,19 @@ UnitTestDialog* UnitTestDialog::_instance=nullptr; UnitTestDialog* UnitTestDialog::instance() { // not initialized? - if (!_instance) + if (!_instance) { _instance = new UnitTestDialog(Gui::getMainWindow()); + } return _instance; } /** * Destructs the instance of this dialog. */ -void UnitTestDialog::destruct () +void UnitTestDialog::destruct() { if (_instance) { - UnitTestDialog *pTmp = _instance; + UnitTestDialog* pTmp = _instance; _instance = nullptr; delete pTmp; } @@ -78,13 +79,13 @@ bool UnitTestDialog::hasInstance() * true to construct a modal dialog. */ UnitTestDialog::UnitTestDialog(QWidget* parent, Qt::WindowFlags f) - : QDialog(parent, f) - , ui(new Ui_UnitTest) + : QDialog(parent, f) + , ui(new Ui_UnitTest) { ui->setupUi(this); setupConnections(); - setProgressColor(QColor(40,210,43)); // a darker green + setProgressColor(QColor(40, 210, 43));// a darker green ui->progressBar->setAlignment(Qt::AlignCenter); // red items @@ -100,15 +101,13 @@ UnitTestDialog::~UnitTestDialog() = default; void UnitTestDialog::setupConnections() { - connect(ui->treeViewFailure, &QTreeWidget::itemDoubleClicked, - this, &UnitTestDialog::onTreeViewFailureItemDoubleClicked); - connect(ui->helpButton, &QPushButton::clicked, - this, &UnitTestDialog::onHelpButtonClicked); - connect(ui->aboutButton, &QPushButton::clicked, - this, &UnitTestDialog::onAboutButtonClicked); - connect(ui->startButton, &QPushButton::clicked, - this, &UnitTestDialog::onStartButtonClicked); - + connect(ui->treeViewFailure, + &QTreeWidget::itemDoubleClicked, + this, + &UnitTestDialog::onTreeViewFailureItemDoubleClicked); + connect(ui->helpButton, &QPushButton::clicked, this, &UnitTestDialog::onHelpButtonClicked); + connect(ui->aboutButton, &QPushButton::clicked, this, &UnitTestDialog::onAboutButtonClicked); + connect(ui->startButton, &QPushButton::clicked, this, &UnitTestDialog::onStartButtonClicked); } /** @@ -116,23 +115,22 @@ void UnitTestDialog::setupConnections() */ void UnitTestDialog::setProgressColor(const QColor& col) { - QString qss = QString::fromLatin1( - "QProgressBar {\n" - " border: 2px solid grey;\n" - " border-radius: 5px;\n" - "}\n" - "\n" - "QProgressBar::chunk {\n" - " background-color: %1;\n" - "}" - ).arg(col.name()); + QString qss = QString::fromLatin1("QProgressBar {\n" + " border: 2px solid grey;\n" + " border-radius: 5px;\n" + "}\n" + "\n" + "QProgressBar::chunk {\n" + " background-color: %1;\n" + "}") + .arg(col.name()); ui->progressBar->setStyleSheet(qss); } /** * Opens a dialog to display a detailed description about the error. */ -void UnitTestDialog::onTreeViewFailureItemDoubleClicked(QTreeWidgetItem * item, int column) +void UnitTestDialog::onTreeViewFailureItemDoubleClicked(QTreeWidgetItem* item, int column) { Q_UNUSED(column); @@ -146,7 +144,7 @@ void UnitTestDialog::onTreeViewFailureItemDoubleClicked(QTreeWidgetItem * item, // truncate the visible text when it's too long if (text.count(QLatin1Char('\n')) > 20) { QStringList lines = text.split(QLatin1Char('\n')); - lines.erase(lines.begin()+20, lines.end()); + lines.erase(lines.begin() + 20, lines.end()); text = lines.join(QLatin1String("\n")); } if (text.size() > 1000) { @@ -162,11 +160,13 @@ void UnitTestDialog::onTreeViewFailureItemDoubleClicked(QTreeWidgetItem * item, */ void UnitTestDialog::onHelpButtonClicked() { - QMessageBox::information(this, tr("Help"), tr( - "Enter the name of a callable object which, when called, will return a TestCase.\n" - "Click 'start', and the test thus produced will be run.\n\n" - "Double click on an error in the tree view to see more information about it, " - "including the stack trace.")); + QMessageBox::information( + this, + tr("Help"), + tr("Enter the name of a callable object which, when called, will return a TestCase.\n" + "Click 'start', and the test thus produced will be run.\n\n" + "Double click on an error in the tree view to see more information about it, " + "including the stack trace.")); } /** @@ -174,10 +174,12 @@ void UnitTestDialog::onHelpButtonClicked() */ void UnitTestDialog::onAboutButtonClicked() { - QMessageBox::information(this, tr("About FreeCAD UnitTest"), tr( - "Copyright (c) Werner Mayer\n\n" - "FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for " - "ones own modules.")); + QMessageBox::information( + this, + tr("About FreeCAD UnitTest"), + tr("Copyright (c) Werner Mayer\n\n" + "FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for " + "ones own modules.")); } /** @@ -186,15 +188,14 @@ void UnitTestDialog::onAboutButtonClicked() void UnitTestDialog::onStartButtonClicked() { reset(); - setProgressColor(QColor(40,210,43)); // a darker green + setProgressColor(QColor(40, 210, 43));// a darker green ui->startButton->setDisabled(true); try { - Base::Interpreter().runString( - "import qtunittest, gc\n" - "__qt_test__=qtunittest.QtTestRunner(0,\"\")\n" - "__qt_test__.runClicked()\n" - "del __qt_test__\n" - "gc.collect()\n"); + Base::Interpreter().runString("import qtunittest, gc\n" + "__qt_test__=qtunittest.QtTestRunner(0,\"\")\n" + "__qt_test__.runClicked()\n" + "del __qt_test__\n" + "gc.collect()\n"); } catch (const Base::PyException& e) { std::string msg = e.what(); @@ -238,10 +239,10 @@ void UnitTestDialog::reset() { ui->progressBar->reset(); ui->treeViewFailure->clear(); - ui->textLabelRunCt->setText (QString::fromLatin1("0")); + ui->textLabelRunCt->setText(QString::fromLatin1("0")); ui->textLabelFailCt->setText(QString::fromLatin1("0")); - ui->textLabelErrCt->setText (QString::fromLatin1("0")); - ui->textLabelRemCt->setText (QString::fromLatin1("0")); + ui->textLabelErrCt->setText(QString::fromLatin1("0")); + ui->textLabelRemCt->setText(QString::fromLatin1("0")); } /** @@ -250,9 +251,10 @@ void UnitTestDialog::reset() void UnitTestDialog::addUnitTest(const QString& unit) { int ct = ui->comboTests->count(); - for (int i=0; icomboTests->itemText(i) == unit) + for (int i = 0; i < ct; i++) { + if (ui->comboTests->itemText(i) == unit) { return; + } } ui->comboTests->addItem(unit); @@ -264,7 +266,7 @@ void UnitTestDialog::addUnitTest(const QString& unit) void UnitTestDialog::setUnitTest(const QString& unit) { addUnitTest(unit); - for (int i=0; icomboTests->count(); i++) { + for (int i = 0; i < ui->comboTests->count(); i++) { if (ui->comboTests->itemText(i) == unit) { ui->comboTests->setCurrentIndex(i); break; @@ -318,7 +320,7 @@ void UnitTestDialog::setStatusText(const QString& text) */ void UnitTestDialog::setProgressFraction(float fraction, const QString& color) { - if (fraction==0.0f) { + if (fraction == 0.0f) { ui->progressBar->setRange(0, 100); } else { @@ -326,7 +328,7 @@ void UnitTestDialog::setProgressFraction(float fraction, const QString& color) setProgressColor(Qt::red); } - ui->progressBar->setValue((int)(100*fraction)); + ui->progressBar->setValue((int)(100 * fraction)); } } @@ -345,7 +347,7 @@ void UnitTestDialog::clearErrorList() void UnitTestDialog::insertError(const QString& failure, const QString& details) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeViewFailure); - item->setText(0,failure); + item->setText(0, failure); item->setForeground(0, Qt::red); item->setData(0, Qt::UserRole, QVariant(details)); } diff --git a/src/Mod/Test/Gui/UnitTestImp.h b/src/Mod/Test/Gui/UnitTestImp.h index e38b907770..68e1678770 100644 --- a/src/Mod/Test/Gui/UnitTestImp.h +++ b/src/Mod/Test/Gui/UnitTestImp.h @@ -31,10 +31,11 @@ class QTreeWidgetItem; -namespace TestGui { +namespace TestGui +{ class Ui_UnitTest; -class UnitTestDialog : public QDialog +class UnitTestDialog: public QDialog { Q_OBJECT @@ -66,7 +67,7 @@ protected: void setProgressColor(const QColor& col); private: - void onTreeViewFailureItemDoubleClicked (QTreeWidgetItem * item, int column); + void onTreeViewFailureItemDoubleClicked(QTreeWidgetItem* item, int column); void onHelpButtonClicked(); void onAboutButtonClicked(); void onStartButtonClicked(); @@ -77,8 +78,7 @@ private: static UnitTestDialog* _instance; }; -} // namespace TestGui +}// namespace TestGui -#endif // TESTGUI_UNITTESTIMP_H - +#endif// TESTGUI_UNITTESTIMP_H diff --git a/src/Mod/Test/Gui/UnitTestPy.cpp b/src/Mod/Test/Gui/UnitTestPy.cpp index 6736cca7e6..f2ec12814c 100644 --- a/src/Mod/Test/Gui/UnitTestPy.cpp +++ b/src/Mod/Test/Gui/UnitTestPy.cpp @@ -22,14 +22,14 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include -#include "UnitTestPy.h" #include "UnitTestImp.h" +#include "UnitTestPy.h" using namespace TestGui; @@ -44,20 +44,22 @@ void UnitTestDialogPy::init_type() behaviors().supportGetattr(); behaviors().supportSetattr(); - add_varargs_method("clearErrorList",&UnitTestDialogPy::clearErrorList,"clearErrorList"); - add_varargs_method("insertError",&UnitTestDialogPy::insertError,"insertError"); - add_varargs_method("setUnitTest",&UnitTestDialogPy::setUnitTest,"setUnitTest"); - add_varargs_method("getUnitTest",&UnitTestDialogPy::getUnitTest,"getUnitTest"); - add_varargs_method("setStatusText",&UnitTestDialogPy::setStatusText,"setStatusText"); - add_varargs_method("setProgressFraction",&UnitTestDialogPy::setProgressFrac,"setProgressFraction"); - add_varargs_method("errorDialog",&UnitTestDialogPy::errorDialog,"errorDialog"); - add_varargs_method("setRunCount",&UnitTestDialogPy::setRunCount,"setRunCount"); - add_varargs_method("setFailCount",&UnitTestDialogPy::setFailCount,"setFailCount"); - add_varargs_method("setErrorCount",&UnitTestDialogPy::setErrorCount,"setErrorCount"); - add_varargs_method("setRemainCount",&UnitTestDialogPy::setRemainCount,"setRemainCount"); - add_varargs_method("updateGUI",&UnitTestDialogPy::updateGUI,"updateGUI"); - add_varargs_method("addUnitTest",&UnitTestDialogPy::addUnitTest,"addUnitTest"); - add_varargs_method("clearUnitTests",&UnitTestDialogPy::clearUnitTests,"clearUnitTests"); + add_varargs_method("clearErrorList", &UnitTestDialogPy::clearErrorList, "clearErrorList"); + add_varargs_method("insertError", &UnitTestDialogPy::insertError, "insertError"); + add_varargs_method("setUnitTest", &UnitTestDialogPy::setUnitTest, "setUnitTest"); + add_varargs_method("getUnitTest", &UnitTestDialogPy::getUnitTest, "getUnitTest"); + add_varargs_method("setStatusText", &UnitTestDialogPy::setStatusText, "setStatusText"); + add_varargs_method("setProgressFraction", + &UnitTestDialogPy::setProgressFrac, + "setProgressFraction"); + add_varargs_method("errorDialog", &UnitTestDialogPy::errorDialog, "errorDialog"); + add_varargs_method("setRunCount", &UnitTestDialogPy::setRunCount, "setRunCount"); + add_varargs_method("setFailCount", &UnitTestDialogPy::setFailCount, "setFailCount"); + add_varargs_method("setErrorCount", &UnitTestDialogPy::setErrorCount, "setErrorCount"); + add_varargs_method("setRemainCount", &UnitTestDialogPy::setRemainCount, "setRemainCount"); + add_varargs_method("updateGUI", &UnitTestDialogPy::updateGUI, "updateGUI"); + add_varargs_method("addUnitTest", &UnitTestDialogPy::addUnitTest, "addUnitTest"); + add_varargs_method("clearUnitTests", &UnitTestDialogPy::clearUnitTests, "clearUnitTests"); } UnitTestDialogPy::UnitTestDialogPy() = default; @@ -69,30 +71,32 @@ Py::Object UnitTestDialogPy::repr() return Py::String("UnitTest"); } -Py::Object UnitTestDialogPy::getattr(const char * attr) +Py::Object UnitTestDialogPy::getattr(const char* attr) { return Py::PythonExtension::getattr(attr); } -int UnitTestDialogPy::setattr(const char * attr, const Py::Object & value) +int UnitTestDialogPy::setattr(const char* attr, const Py::Object& value) { return Py::PythonExtension::setattr(attr, value); } Py::Object UnitTestDialogPy::clearErrorList(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } UnitTestDialog::instance()->clearErrorList(); return Py::None(); } Py::Object UnitTestDialogPy::insertError(const Py::Tuple& args) { - char *failure=nullptr; - char *details=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "ss", &failure,&details)) + char* failure = nullptr; + char* details = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "ss", &failure, &details)) { throw Py::Exception(); + } UnitTestDialog::instance()->insertError(QString::fromLatin1(failure), QString::fromLatin1(details)); @@ -101,9 +105,10 @@ Py::Object UnitTestDialogPy::insertError(const Py::Tuple& args) Py::Object UnitTestDialogPy::setUnitTest(const Py::Tuple& args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) { throw Py::Exception(); + } UnitTestDialog::instance()->setUnitTest(QString::fromLatin1(pstr)); return Py::None(); @@ -111,16 +116,18 @@ Py::Object UnitTestDialogPy::setUnitTest(const Py::Tuple& args) Py::Object UnitTestDialogPy::getUnitTest(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } return Py::String((const char*)UnitTestDialog::instance()->getUnitTest().toLatin1()); } Py::Object UnitTestDialogPy::setStatusText(const Py::Tuple& args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) { throw Py::Exception(); + } UnitTestDialog::instance()->setStatusText(QString::fromLatin1(pstr)); return Py::None(); @@ -129,32 +136,37 @@ Py::Object UnitTestDialogPy::setStatusText(const Py::Tuple& args) Py::Object UnitTestDialogPy::setProgressFrac(const Py::Tuple& args) { float fraction; - char* pColor=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "f|s",&fraction, &pColor)) + char* pColor = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "f|s", &fraction, &pColor)) { throw Py::Exception(); + } - if (pColor) - UnitTestDialog::instance()->setProgressFraction(fraction,QString::fromLatin1(pColor)); - else - UnitTestDialog::instance()->setProgressFraction(fraction); + if (pColor) { + UnitTestDialog::instance()->setProgressFraction(fraction, QString::fromLatin1(pColor)); + } + else { + UnitTestDialog::instance()->setProgressFraction(fraction); + } return Py::None(); } Py::Object UnitTestDialogPy::errorDialog(const Py::Tuple& args) { - char *title=nullptr; - char *message=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "ss", &title, &message)) + char* title = nullptr; + char* message = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "ss", &title, &message)) { throw Py::Exception(); - UnitTestDialog::instance()->showErrorDialog(title,message); + } + UnitTestDialog::instance()->showErrorDialog(title, message); return Py::None(); } Py::Object UnitTestDialogPy::setRunCount(const Py::Tuple& args) { int count; - if (!PyArg_ParseTuple(args.ptr(), "i", &count)) + if (!PyArg_ParseTuple(args.ptr(), "i", &count)) { throw Py::Exception(); + } UnitTestDialog::instance()->setRunCount(count); return Py::None(); } @@ -162,8 +174,9 @@ Py::Object UnitTestDialogPy::setRunCount(const Py::Tuple& args) Py::Object UnitTestDialogPy::setFailCount(const Py::Tuple& args) { int count; - if (!PyArg_ParseTuple(args.ptr(), "i", &count)) + if (!PyArg_ParseTuple(args.ptr(), "i", &count)) { throw Py::Exception(); + } UnitTestDialog::instance()->setFailCount(count); return Py::None(); } @@ -171,8 +184,9 @@ Py::Object UnitTestDialogPy::setFailCount(const Py::Tuple& args) Py::Object UnitTestDialogPy::setErrorCount(const Py::Tuple& args) { int count; - if (!PyArg_ParseTuple(args.ptr(), "i", &count)) + if (!PyArg_ParseTuple(args.ptr(), "i", &count)) { throw Py::Exception(); + } UnitTestDialog::instance()->setErrorCount(count); return Py::None(); } @@ -180,25 +194,28 @@ Py::Object UnitTestDialogPy::setErrorCount(const Py::Tuple& args) Py::Object UnitTestDialogPy::setRemainCount(const Py::Tuple& args) { int count; - if (!PyArg_ParseTuple(args.ptr(), "i", &count)) + if (!PyArg_ParseTuple(args.ptr(), "i", &count)) { throw Py::Exception(); + } UnitTestDialog::instance()->setRemainCount(count); return Py::None(); } Py::Object UnitTestDialogPy::updateGUI(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } qApp->processEvents(QEventLoop::ExcludeUserInputEvents); return Py::None(); } Py::Object UnitTestDialogPy::addUnitTest(const Py::Tuple& args) { - char *pstr; - if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) + char* pstr; + if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) { throw Py::Exception(); + } TestGui::UnitTestDialog* dlg = TestGui::UnitTestDialog::instance(); dlg->addUnitTest(QString::fromLatin1(pstr)); @@ -207,8 +224,9 @@ Py::Object UnitTestDialogPy::addUnitTest(const Py::Tuple& args) Py::Object UnitTestDialogPy::clearUnitTests(const Py::Tuple& args) { - if (!PyArg_ParseTuple(args.ptr(), "")) + if (!PyArg_ParseTuple(args.ptr(), "")) { throw Py::Exception(); + } UnitTestDialog::instance()->clearUnitTests(); return Py::None(); } diff --git a/src/Mod/Test/Gui/UnitTestPy.h b/src/Mod/Test/Gui/UnitTestPy.h index 649939f750..659e16de4b 100644 --- a/src/Mod/Test/Gui/UnitTestPy.h +++ b/src/Mod/Test/Gui/UnitTestPy.h @@ -32,41 +32,40 @@ namespace TestGui { class UnitTestDialog; -class UnitTestDialogPy : public Py::PythonExtension +class UnitTestDialogPy: public Py::PythonExtension { public: - static void init_type(); // announce properties and methods + static void init_type();// announce properties and methods UnitTestDialogPy(); ~UnitTestDialogPy() override; Py::Object repr() override; - Py::Object getattr(const char *) override; - int setattr(const char *, const Py::Object &) override; + Py::Object getattr(const char*) override; + int setattr(const char*, const Py::Object&) override; - Py::Object clearErrorList (const Py::Tuple&); - Py::Object insertError (const Py::Tuple&); - Py::Object setUnitTest (const Py::Tuple&); - Py::Object getUnitTest (const Py::Tuple&); - Py::Object setStatusText (const Py::Tuple&); - Py::Object setProgressFrac (const Py::Tuple&); - Py::Object errorDialog (const Py::Tuple&); - Py::Object setRunCount (const Py::Tuple&); - Py::Object setFailCount (const Py::Tuple&); - Py::Object setErrorCount (const Py::Tuple&); - Py::Object setRemainCount (const Py::Tuple&); - Py::Object updateGUI (const Py::Tuple&); - Py::Object addUnitTest (const Py::Tuple&); - Py::Object clearUnitTests (const Py::Tuple&); + Py::Object clearErrorList(const Py::Tuple&); + Py::Object insertError(const Py::Tuple&); + Py::Object setUnitTest(const Py::Tuple&); + Py::Object getUnitTest(const Py::Tuple&); + Py::Object setStatusText(const Py::Tuple&); + Py::Object setProgressFrac(const Py::Tuple&); + Py::Object errorDialog(const Py::Tuple&); + Py::Object setRunCount(const Py::Tuple&); + Py::Object setFailCount(const Py::Tuple&); + Py::Object setErrorCount(const Py::Tuple&); + Py::Object setRemainCount(const Py::Tuple&); + Py::Object updateGUI(const Py::Tuple&); + Py::Object addUnitTest(const Py::Tuple&); + Py::Object clearUnitTests(const Py::Tuple&); private: - using method_varargs_handler = PyObject* (*)(PyObject *_self, PyObject *_args); + using method_varargs_handler = PyObject* (*)(PyObject* _self, PyObject* _args); static method_varargs_handler pycxx_handler; - static PyObject *method_varargs_ext_handler(PyObject *_self, PyObject *_args); + static PyObject* method_varargs_ext_handler(PyObject* _self, PyObject* _args); }; -} //namespace TESTGUI_UNITTESTPY_H +}// namespace TestGui #endif - diff --git a/src/Mod/Test/Init.py b/src/Mod/Test/Init.py index a56f9f72ca..134e6dc946 100644 --- a/src/Mod/Test/Init.py +++ b/src/Mod/Test/Init.py @@ -1,33 +1,35 @@ -#*************************************************************************** -#* Copyright (c) 2001,2002 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2001,2002 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # FreeCAD init script of the test module # Base system tests -FreeCAD.__unit_test__ += [ "BaseTests", - "UnitTests", - "Document", - "Metadata", - "StringHasher", - "UnicodeTests", - "TestPythonSyntax" ] +FreeCAD.__unit_test__ += [ + "BaseTests", + "UnitTests", + "Document", + "Metadata", + "StringHasher", + "UnicodeTests", + "TestPythonSyntax", +] diff --git a/src/Mod/Test/InitGui.py b/src/Mod/Test/InitGui.py index b01eb68295..61fec8c7a8 100644 --- a/src/Mod/Test/InitGui.py +++ b/src/Mod/Test/InitGui.py @@ -1,80 +1,95 @@ -#*************************************************************************** -#* Copyright (c) 2002,2003 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2002,2003 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # Test gui init module -class TestWorkbench ( Workbench ): + +class TestWorkbench(Workbench): "Test workbench object" + def __init__(self): - self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Test/Resources/icons/TestWorkbench.svg" + self.__class__.Icon = ( + FreeCAD.getResourceDir() + "Mod/Test/Resources/icons/TestWorkbench.svg" + ) self.__class__.MenuText = "Test Framework" self.__class__.ToolTip = "Test Framework" def Initialize(self): import TestGui - list = ["Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"] - self.appendToolbar("TestTools",list) + list = ["Test_Test", "Test_TestAll", "Test_TestDoc", "Test_TestBase"] + self.appendToolbar("TestTools", list) - menu = ["Test &Commands","TestToolsGui"] - list = ["Std_TestQM","Std_TestReloadQM","Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"] - self.appendCommandbar("TestToolsGui",list) - self.appendMenu(menu,list) + menu = ["Test &Commands", "TestToolsGui"] + list = [ + "Std_TestQM", + "Std_TestReloadQM", + "Test_Test", + "Test_TestAll", + "Test_TestDoc", + "Test_TestBase", + ] + self.appendCommandbar("TestToolsGui", list) + self.appendMenu(menu, list) - menu = ["Test &Commands","TestToolsText"] - list = ["Test_TestAllText","Test_TestDocText","Test_TestBaseText"] - self.appendCommandbar("TestToolsText",list) - self.appendMenu(menu,list) + menu = ["Test &Commands", "TestToolsText"] + list = ["Test_TestAllText", "Test_TestDocText", "Test_TestBaseText"] + self.appendCommandbar("TestToolsText", list) + self.appendMenu(menu, list) - menu = ["Test &Commands","TestToolsMenu"] + menu = ["Test &Commands", "TestToolsMenu"] list = ["Test_TestCreateMenu", "Test_TestDeleteMenu", "Test_TestWork"] - self.appendCommandbar("TestToolsMenu",list) - self.appendMenu(menu,list) + self.appendCommandbar("TestToolsMenu", list) + self.appendMenu(menu, list) - menu = ["Test &Commands","TestFeatureMenu"] + menu = ["Test &Commands", "TestFeatureMenu"] list = ["Test_InsertFeature"] - self.appendCommandbar("TestFeature",list) - self.appendMenu(menu,list) + self.appendCommandbar("TestFeature", list) + self.appendMenu(menu, list) - menu = ["Test &Commands","Progress bar"] - list = ["Std_TestProgress1", "Std_TestProgress2", "Std_TestProgress3", "Std_TestProgress4", "Std_TestProgress5"] - self.appendMenu(menu,list) + menu = ["Test &Commands", "Progress bar"] + list = [ + "Std_TestProgress1", + "Std_TestProgress2", + "Std_TestProgress3", + "Std_TestProgress4", + "Std_TestProgress5", + ] + self.appendMenu(menu, list) - menu = ["Test &Commands","Console"] + menu = ["Test &Commands", "Console"] list = ["Std_TestConsoleOutput"] - self.appendMenu(menu,list) + self.appendMenu(menu, list) - menu = ["Test &Commands","MDI"] + menu = ["Test &Commands", "MDI"] list = ["Std_MDITest1", "Std_MDITest2", "Std_MDITest3"] - self.appendMenu(menu,list) + self.appendMenu(menu, list) list = ["Std_ViewExample1", "Std_ViewExample2", "Std_ViewExample3"] - self.appendMenu("Inventor View",list) + self.appendMenu("Inventor View", list) + Gui.addWorkbench(TestWorkbench()) # Base system tests -FreeCAD.__unit_test__ += [ "Workbench", - "Menu", - "Menu.MenuDeleteCases", - "Menu.MenuCreateCases" ] +FreeCAD.__unit_test__ += ["Workbench", "Menu", "Menu.MenuDeleteCases", "Menu.MenuCreateCases"] diff --git a/src/Mod/Test/Menu.py b/src/Mod/Test/Menu.py index 5beb9f939a..12e6666e24 100644 --- a/src/Mod/Test/Menu.py +++ b/src/Mod/Test/Menu.py @@ -1,37 +1,37 @@ -#*************************************************************************** -#* Copyright (c) 2005 Werner Mayer * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#* Werner Mayer 2005 * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2005 Werner Mayer * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# * Werner Mayer 2005 * +# ***************************************************************************/ # Menu test module import FreeCAD, os, unittest, FreeCADGui -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD base code -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- -#def suite(): +# def suite(): # suite = unittest.TestSuite() # suite.addTest(DocTestCase("DocumentProperties")) # suite.addTest(DocTestCase("DocumentLabels")) @@ -40,52 +40,51 @@ import FreeCAD, os, unittest, FreeCADGui class MenuCreateCases(unittest.TestCase): - def setUp(self): FreeCADGui.activateWorkbench("TestWorkbench") - FreeCAD.Console.PrintLog ('Setup Test menu...\n') - list = ["Test_TestAll","Test_TestDoc","Test_TestBase","Test_TestWork"] - w = FreeCADGui.getWorkbench('TestWorkbench') - w.appendMenu("TestMenu",list) + FreeCAD.Console.PrintLog("Setup Test menu...\n") + list = ["Test_TestAll", "Test_TestDoc", "Test_TestBase", "Test_TestWork"] + w = FreeCADGui.getWorkbench("TestWorkbench") + w.appendMenu("TestMenu", list) def testMenu(self): # check menu for items - FreeCAD.Console.PrintLog ('Checking Test menu...\n') - w = FreeCADGui.getWorkbench('TestWorkbench') + FreeCAD.Console.PrintLog("Checking Test menu...\n") + w = FreeCADGui.getWorkbench("TestWorkbench") list = w.listMenus() self.b = False for i in list: - if i == 'TestMenu': self.b=True - self.failUnless(self.b,"Test menu not found") + if i == "TestMenu": + self.b = True + self.failUnless(self.b, "Test menu not found") def tearDown(self): - if self.b: - FreeCAD.Console.PrintLog ('Test menu successfully added\n') - else: - FreeCAD.Console.PrintLog ('Adding Test menu failed\n') + if self.b: + FreeCAD.Console.PrintLog("Test menu successfully added\n") + else: + FreeCAD.Console.PrintLog("Adding Test menu failed\n") class MenuDeleteCases(unittest.TestCase): - def setUp(self): FreeCADGui.activateWorkbench("TestWorkbench") - FreeCAD.Console.PrintLog ('Remove Test menu...\n') - w = FreeCADGui.getWorkbench('TestWorkbench') + FreeCAD.Console.PrintLog("Remove Test menu...\n") + w = FreeCADGui.getWorkbench("TestWorkbench") w.removeMenu("TestMenu") def testMenu(self): # check menu for items - FreeCAD.Console.PrintLog ('Checking Test menu...\n') - w = FreeCADGui.getWorkbench('TestWorkbench') + FreeCAD.Console.PrintLog("Checking Test menu...\n") + w = FreeCADGui.getWorkbench("TestWorkbench") list = w.listMenus() self.b = True for i in list: - if i == 'TestMenu': self.b=False - self.failUnless(self.b==True,"Test menu still added") + if i == "TestMenu": + self.b = False + self.failUnless(self.b == True, "Test menu still added") def tearDown(self): - if self.b: - FreeCAD.Console.PrintLog ('Test menu successfully removed\n') - else: - FreeCAD.Console.PrintLog ('Removing Test menu failed\n') - + if self.b: + FreeCAD.Console.PrintLog("Test menu successfully removed\n") + else: + FreeCAD.Console.PrintLog("Removing Test menu failed\n") diff --git a/src/Mod/Test/Metadata.py b/src/Mod/Test/Metadata.py index 6e3e7ed5b0..d94d4e078b 100644 --- a/src/Mod/Test/Metadata.py +++ b/src/Mod/Test/Metadata.py @@ -28,8 +28,8 @@ import os import codecs import tempfile -class TestMetadata(unittest.TestCase): +class TestMetadata(unittest.TestCase): def setUp(self): self.test_dir = os.path.join(FreeCAD.getHomePath(), "Mod", "Test", "TestData") @@ -40,15 +40,24 @@ class TestMetadata(unittest.TestCase): except Exception: self.fail("Metadata construction from XML file failed") - with self.assertRaises(FreeCAD.Base.XMLBaseException, msg="Metadata construction from XML file with bad root node did not raise an exception"): + with self.assertRaises( + FreeCAD.Base.XMLBaseException, + msg="Metadata construction from XML file with bad root node did not raise an exception", + ): filename = os.path.join(self.test_dir, "bad_root_node.xml") md = FreeCAD.Metadata(filename) - with self.assertRaises(FreeCAD.Base.XMLBaseException, msg="Metadata construction from invalid XML file did not raise an exception"): + with self.assertRaises( + FreeCAD.Base.XMLBaseException, + msg="Metadata construction from invalid XML file did not raise an exception", + ): filename = os.path.join(self.test_dir, "bad_xml.xml") md = FreeCAD.Metadata(filename) - with self.assertRaises(FreeCAD.Base.XMLBaseException, msg="Metadata construction from XML file with invalid version did not raise an exception"): + with self.assertRaises( + FreeCAD.Base.XMLBaseException, + msg="Metadata construction from XML file with invalid version did not raise an exception", + ): filename = os.path.join(self.test_dir, "bad_version.xml") md = FreeCAD.Metadata(filename) @@ -66,7 +75,7 @@ class TestMetadata(unittest.TestCase): # Tags that are lists of elements: maintainers = md.Maintainer self.assertEqual(len(maintainers), 2) - + authors = md.Author self.assertEqual(len(authors), 3) @@ -112,9 +121,10 @@ class TestMetadata(unittest.TestCase): def test_file_path(self): # Issue 7112 try: - filename = os.path.join(tempfile.gettempdir(), b'H\xc3\xa5vard.xml'.decode("utf-8")) + filename = os.path.join(tempfile.gettempdir(), b"H\xc3\xa5vard.xml".decode("utf-8")) xmlfile = codecs.open(filename, mode="w", encoding="utf-8") - xmlfile.write(r""" + xmlfile.write( + r""" test Text @@ -125,14 +135,15 @@ class TestMetadata(unittest.TestCase): Workbench -""") +""" + ) xmlfile.close() md = FreeCAD.Metadata(filename) self.assertEqual(md.Name, "test") self.assertEqual(md.Description, "Text") self.assertEqual(md.Version, "1.0.0") except UnicodeEncodeError as e: - print ("Ignore UnicodeEncodeError in test_file_path:\n{}".format(str(e))) + print("Ignore UnicodeEncodeError in test_file_path:\n{}".format(str(e))) def test_content_item_tags(self): filename = os.path.join(self.test_dir, "content_items.xml") @@ -162,11 +173,13 @@ class TestMetadata(unittest.TestCase): elif workbench.Classname == "TestWorkbenchD": found[3] = True dependencies = workbench.Depend - expected_dependencies = {"DependencyA":{"type":"automatic","found":False}, - "InternalWorkbench":{"type":"internal","found":False}, - "AddonWorkbench":{"type":"addon","found":False}, - "PythonPackage":{"type":"python","found":False}, - "DependencyB":{"type":"automatic","found":False}} + expected_dependencies = { + "DependencyA": {"type": "automatic", "found": False}, + "InternalWorkbench": {"type": "internal", "found": False}, + "AddonWorkbench": {"type": "addon", "found": False}, + "PythonPackage": {"type": "python", "found": False}, + "DependencyB": {"type": "automatic", "found": False}, + } for dep in dependencies: self.assertTrue(dep["package"] in expected_dependencies) self.assertEqual(dep["type"], expected_dependencies[dep["package"]]["type"]) @@ -174,8 +187,9 @@ class TestMetadata(unittest.TestCase): for name, expected_dep in expected_dependencies.items(): self.assertTrue(expected_dep["found"], f"Failed to load dependency '{name}'") for f in found: - self.assertTrue(f,f"One of the expected workbenches was not found in the metadata file") - + self.assertTrue( + f, f"One of the expected workbenches was not found in the metadata file" + ) def test_last_supported_version(self): pass @@ -190,4 +204,4 @@ class TestMetadata(unittest.TestCase): pass def test_min_python_version(self): - pass \ No newline at end of file + pass diff --git a/src/Mod/Test/StringHasher.py b/src/Mod/Test/StringHasher.py index 98a82f975f..53f96d1848 100644 --- a/src/Mod/Test/StringHasher.py +++ b/src/Mod/Test/StringHasher.py @@ -1,25 +1,25 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -#*************************************************************************** -#* Copyright (c) 2023 Mario Passaglia * -#* * -#* This file is part of FreeCAD. * -#* * -#* FreeCAD is free software: you can redistribute it and/or modify it * -#* under the terms of the GNU Lesser General Public License as * -#* published by the Free Software Foundation, either version 2.1 of the * -#* License, or (at your option) any later version. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, but * -#* WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * -#* Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Lesser General Public * -#* License along with FreeCAD. If not, see * -#* . * -#* * -#**************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2023 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# **************************************************************************/ import FreeCAD import unittest diff --git a/src/Mod/Test/TestApp.py b/src/Mod/Test/TestApp.py index 806681d258..c948bab9c9 100644 --- a/src/Mod/Test/TestApp.py +++ b/src/Mod/Test/TestApp.py @@ -1,34 +1,35 @@ -#*************************************************************************** -#* Copyright (c) 2002 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2002 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ import FreeCAD import sys import unittest -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD base code -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- + def tryLoadingTest(testName): "Loads and returns testName, or a failing TestCase if unsuccessful." @@ -37,6 +38,7 @@ def tryLoadingTest(testName): return unittest.defaultTestLoader.loadTestsFromName(testName) except ImportError: + class LoadFailed(unittest.TestCase): def __init__(self, testName): # setattr() first, because TestCase ctor checks for methodName. @@ -52,6 +54,7 @@ def tryLoadingTest(testName): return LoadFailed(testName) + def All(): # Registered tests tests = FreeCAD.__unit_test__ @@ -63,6 +66,7 @@ def All(): return suite + def PrintAll(): # Registered tests tests = FreeCAD.__unit_test__ diff --git a/src/Mod/Test/TestGui.py b/src/Mod/Test/TestGui.py index 6284e52b67..a846ed3899 100644 --- a/src/Mod/Test/TestGui.py +++ b/src/Mod/Test/TestGui.py @@ -1,43 +1,47 @@ -#*************************************************************************** -#* Copyright (c) 2001,2002 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * Copyright (c) 2001,2002 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # FreeCAD Part module # # Part design module # import FreeCAD modules -import FreeCAD,FreeCADGui +import FreeCAD, FreeCADGui + # import the App Test module -import TestApp #Test as Module name not possible +import TestApp # Test as Module name not possible import sys -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the Commands of the Test Application module -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- class TestCmd: """Opens a Qt dialog with all inserted unit tests""" + def Activated(self): import QtUnitGui + tests = FreeCAD.__unit_test__ QtUnitGui.addTest("TestApp.All") @@ -46,81 +50,115 @@ class TestCmd: QtUnitGui.addTest(test) def GetResources(self): - return {'MenuText': 'Self-test...', 'ToolTip': 'Runs a self-test to check if the application works properly'} + return { + "MenuText": "Self-test...", + "ToolTip": "Runs a self-test to check if the application works properly", + } + class TestAllCmd: "Test all commando object" + def Activated(self): import QtUnitGui + QtUnitGui.addTest("TestApp.All") QtUnitGui.setTest("TestApp.All") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', 'MenuText': 'Test all', 'ToolTip': 'Runs all tests at once (can take very long!)'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test all", + "ToolTip": "Runs all tests at once (can take very long!)", + } + class TestDocCmd: "Document test commando object" + def Activated(self): import QtUnitGui + QtUnitGui.addTest("Document") QtUnitGui.setTest("Document") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test Document', - 'ToolTip' : 'Test the document (creation, save, load and destruction)'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test Document", + "ToolTip": "Test the document (creation, save, load and destruction)", + } + class TestBaseCmd: "Base test commando object" + def Activated(self): import QtUnitGui + QtUnitGui.addTest("BaseTests") QtUnitGui.setTest("BaseTests") def GetResources(self): return { - 'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test base', - 'ToolTip' : 'Test the basic functions of FreeCAD' - } + "Pixmap": "Std_Tool1", + "MenuText": "Test base", + "ToolTip": "Test the basic functions of FreeCAD", + } + class TestAllTextCmd: "Test all commando object" + def Activated(self): import unittest, TestApp - unittest.TextTestRunner(stream=sys.stdout,verbosity=2).run(unittest.defaultTestLoader.loadTestsFromName("TestApp.All")) + + unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( + unittest.defaultTestLoader.loadTestsFromName("TestApp.All") + ) def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test all', - 'ToolTip' : 'Runs all tests at once (can take very long!)' - } + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test all", + "ToolTip": "Runs all tests at once (can take very long!)", + } + class TestDocTextCmd: "Document test commando object" + def Activated(self): TestApp.TestText("Document") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test Document', - 'ToolTip' : 'Test the document (creation, save, load and destruction)'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test Document", + "ToolTip": "Test the document (creation, save, load and destruction)", + } + class TestBaseTextCmd: "Base test commando object" + def Activated(self): TestApp.TestText("BaseTests") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test base', - 'ToolTip' : 'Test the basic functions of FreeCAD'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test base", + "ToolTip": "Test the basic functions of FreeCAD", + } + class TestWorkbenchCmd: "Workbench test" + def Activated(self): - i=0 - while (i<20): + i = 0 + while i < 20: FreeCADGui.activateWorkbench("MeshWorkbench") FreeCADGui.updateGui() FreeCADGui.activateWorkbench("NoneWorkbench") @@ -128,36 +166,48 @@ class TestWorkbenchCmd: FreeCADGui.activateWorkbench("PartWorkbench") FreeCADGui.updateGui() print(i) - i=i+1 + i = i + 1 FreeCADGui.activateWorkbench("TestWorkbench") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Test workbench', - 'ToolTip' : 'Test the switching of workbenches in FreeCAD'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Test workbench", + "ToolTip": "Test the switching of workbenches in FreeCAD", + } + class TestCreateMenuCmd: "Base test commando object" + def Activated(self): TestApp.TestText("Menu.MenuCreateCases") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Add menu', - 'ToolTip' : 'Test the menu stuff of FreeCAD'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Add menu", + "ToolTip": "Test the menu stuff of FreeCAD", + } + class TestDeleteMenuCmd: "Base test commando object" + def Activated(self): TestApp.TestText("Menu.MenuDeleteCases") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Remove menu', - 'ToolTip' : 'Test the menu stuff of FreeCAD'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Remove menu", + "ToolTip": "Test the menu stuff of FreeCAD", + } + class TestInsertFeatureCmd: "Base test commando object" + def Activated(self): if FreeCAD.activeDocument() is not None: FreeCAD.activeDocument().addObject("App::FeatureTest") @@ -165,21 +215,24 @@ class TestInsertFeatureCmd: FreeCAD.PrintMessage("No active document.\n") def GetResources(self): - return {'Pixmap' : 'Std_Tool1', - 'MenuText': 'Insert a TestFeature', - 'ToolTip' : 'Insert a TestFeature in the active Document'} + return { + "Pixmap": "Std_Tool1", + "MenuText": "Insert a TestFeature", + "ToolTip": "Insert a TestFeature in the active Document", + } -#--------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- # Adds the commands to the FreeCAD command manager -#--------------------------------------------------------------------------- -FreeCADGui.addCommand('Test_Test' ,TestCmd()) -FreeCADGui.addCommand('Test_TestAllText' ,TestAllTextCmd()) -FreeCADGui.addCommand('Test_TestDocText' ,TestDocTextCmd()) -FreeCADGui.addCommand('Test_TestBaseText',TestBaseTextCmd()) -FreeCADGui.addCommand('Test_TestAll' ,TestAllCmd()) -FreeCADGui.addCommand('Test_TestDoc' ,TestDocCmd()) -FreeCADGui.addCommand('Test_TestBase' ,TestBaseCmd()) -FreeCADGui.addCommand('Test_TestWork' ,TestWorkbenchCmd()) -FreeCADGui.addCommand('Test_TestCreateMenu' ,TestCreateMenuCmd()) -FreeCADGui.addCommand('Test_TestDeleteMenu' ,TestDeleteMenuCmd()) -FreeCADGui.addCommand('Test_InsertFeature' ,TestInsertFeatureCmd()) +# --------------------------------------------------------------------------- +FreeCADGui.addCommand("Test_Test", TestCmd()) +FreeCADGui.addCommand("Test_TestAllText", TestAllTextCmd()) +FreeCADGui.addCommand("Test_TestDocText", TestDocTextCmd()) +FreeCADGui.addCommand("Test_TestBaseText", TestBaseTextCmd()) +FreeCADGui.addCommand("Test_TestAll", TestAllCmd()) +FreeCADGui.addCommand("Test_TestDoc", TestDocCmd()) +FreeCADGui.addCommand("Test_TestBase", TestBaseCmd()) +FreeCADGui.addCommand("Test_TestWork", TestWorkbenchCmd()) +FreeCADGui.addCommand("Test_TestCreateMenu", TestCreateMenuCmd()) +FreeCADGui.addCommand("Test_TestDeleteMenu", TestDeleteMenuCmd()) +FreeCADGui.addCommand("Test_InsertFeature", TestInsertFeatureCmd()) diff --git a/src/Mod/Test/TestPythonSyntax.py b/src/Mod/Test/TestPythonSyntax.py index 1f9b25dc18..22b53769a0 100644 --- a/src/Mod/Test/TestPythonSyntax.py +++ b/src/Mod/Test/TestPythonSyntax.py @@ -1,25 +1,25 @@ -#*************************************************************************** -#* Copyright (c) 2018 looooo * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2018 looooo * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ import os import ast @@ -34,7 +34,7 @@ def test_python_syntax(rootdir, whitelist=None): for fn in files: kargs = {} kargs["encoding"] = "utf-8" - if (not fn in whitelist) and os.path.splitext(fn)[1] == '.py': + if (not fn in whitelist) and os.path.splitext(fn)[1] == ".py": with open(os.path.join(sub_dir, fn), **kargs) as py_file: try: ast.parse(py_file.read()) @@ -45,17 +45,23 @@ def test_python_syntax(rootdir, whitelist=None): for i, m in enumerate(log): message += str(i + 1) + " " + m + "\n" if log: - raise RuntimeError("there are some files not parse-able with the used python-interpreter" + message) + raise RuntimeError( + "there are some files not parse-able with the used python-interpreter" + message + ) else: return + class PythonSyntaxTestCase(unittest.TestCase): """ Test Case to test python syntax of all python files in FreeCAD """ + def setUp(self): self.whitelist = [] - self.whitelist += ["ap203_configuration_controlled_3d_design_of_mechanical_parts_and_assemblies_mim_lf.py"] + self.whitelist += [ + "ap203_configuration_controlled_3d_design_of_mechanical_parts_and_assemblies_mim_lf.py" + ] self.whitelist += ["automotive_design.py"] self.whitelist += ["ifc2x3.py"] self.whitelist += ["ifc4.py"] diff --git a/src/Mod/Test/UnicodeTests.py b/src/Mod/Test/UnicodeTests.py index 6d505d057c..debde6f552 100644 --- a/src/Mod/Test/UnicodeTests.py +++ b/src/Mod/Test/UnicodeTests.py @@ -1,71 +1,69 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* Copyright (c) 2007 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2007 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # Open and edit only in UTF-8 !!!!!! import FreeCAD, os, unittest, tempfile -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD Document code -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- class UnicodeBasicCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("CreateTest") + def setUp(self): + self.Doc = FreeCAD.newDocument("CreateTest") - def testUnicodeLabel(self): - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - L1.Label = u"हिन्दी" - self.failUnless(L1.Label == u"हिन्दी") + def testUnicodeLabel(self): + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + L1.Label = "हिन्दी" + self.failUnless(L1.Label == "हिन्दी") + + def tearDown(self): + # closing doc + FreeCAD.closeDocument("CreateTest") - def tearDown(self): - #closing doc - FreeCAD.closeDocument("CreateTest") class DocumentSaveRestoreCases(unittest.TestCase): - def setUp(self): - self.Doc = FreeCAD.newDocument("SaveRestoreTests") - L1 = self.Doc.addObject("App::FeatureTest","Label_1") - L1.Label = u"हिन्दी" - self.TempPath = tempfile.gettempdir() - FreeCAD.Console.PrintLog( ' Using temp path: ' + self.TempPath + '\n') - - def testSaveAndRestore(self): - # saving and restoring - SaveName = self.TempPath + os.sep + "UnicodeTest.FCStd" - self.Doc.saveAs(SaveName) - FreeCAD.closeDocument("SaveRestoreTests") - self.Doc = FreeCAD.open(SaveName) - self.failUnless(self.Doc.Label_1.Label == u"हिन्दी") - FreeCAD.closeDocument("UnicodeTest") - FreeCAD.newDocument("SaveRestoreTests") - - - def tearDown(self): - #closing doc - FreeCAD.closeDocument("SaveRestoreTests") + def setUp(self): + self.Doc = FreeCAD.newDocument("SaveRestoreTests") + L1 = self.Doc.addObject("App::FeatureTest", "Label_1") + L1.Label = "हिन्दी" + self.TempPath = tempfile.gettempdir() + FreeCAD.Console.PrintLog(" Using temp path: " + self.TempPath + "\n") + def testSaveAndRestore(self): + # saving and restoring + SaveName = self.TempPath + os.sep + "UnicodeTest.FCStd" + self.Doc.saveAs(SaveName) + FreeCAD.closeDocument("SaveRestoreTests") + self.Doc = FreeCAD.open(SaveName) + self.failUnless(self.Doc.Label_1.Label == "हिन्दी") + FreeCAD.closeDocument("UnicodeTest") + FreeCAD.newDocument("SaveRestoreTests") + def tearDown(self): + # closing doc + FreeCAD.closeDocument("SaveRestoreTests") diff --git a/src/Mod/Test/UnitTests.py b/src/Mod/Test/UnitTests.py index 575f6f5680..4c3a3003c8 100644 --- a/src/Mod/Test/UnitTests.py +++ b/src/Mod/Test/UnitTests.py @@ -1,44 +1,47 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* Copyright (c) 2010 Juergen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2010 Juergen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ import FreeCAD import unittest import math + def tu(str): return FreeCAD.Units.Quantity(str).Value + def ts(q): return q.UserString + def ts2(q): return FreeCAD.Units.Quantity(q.UserString).UserString -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD UnitApi code -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- def compare(x, y): @@ -49,24 +52,24 @@ class UnitBasicCases(unittest.TestCase): def setUp(self): par = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units") dec = par.GetInt("Decimals") - self.delta = math.pow(10,-dec) + self.delta = math.pow(10, -dec) def testConversions(self): - #tu = FreeCAD.Units.translateUnit - self.assertTrue(compare(tu('10 m'), 10000.0)) - self.assertTrue(compare(tu('3/8 in'), 9.525)) - self.assertTrue(compare(tu('100 km/h'), 27777.77777777)) - self.assertTrue(compare(tu('m^2*kg*s^-3*A^-2'), 1000000.0)) - self.assertTrue(compare(tu('(m^2*kg)/(A^2*s^3)'), 1000000.0)) - self.assertTrue(compare(tu('2*pi rad'), 360.0)) - self.assertTrue(compare(tu('2*pi rad') / tu('gon'), 400.0)) - self.assertTrue(compare(tu('999 kg') / tu('1 m^3'), 0.000009999)) + # tu = FreeCAD.Units.translateUnit + self.assertTrue(compare(tu("10 m"), 10000.0)) + self.assertTrue(compare(tu("3/8 in"), 9.525)) + self.assertTrue(compare(tu("100 km/h"), 27777.77777777)) + self.assertTrue(compare(tu("m^2*kg*s^-3*A^-2"), 1000000.0)) + self.assertTrue(compare(tu("(m^2*kg)/(A^2*s^3)"), 1000000.0)) + self.assertTrue(compare(tu("2*pi rad"), 360.0)) + self.assertTrue(compare(tu("2*pi rad") / tu("gon"), 400.0)) + self.assertTrue(compare(tu("999 kg") / tu("1 m^3"), 0.000009999)) def testImperial(self): - #tu = FreeCAD.Units.translateUnit - self.assertTrue(compare(tu('3/8in'), 9.525)) - #self.assertTrue(compare(tu('1fo(3+7/16)in'),392.112500))thisgivesaparsersyntaxerror!!! - self.assertTrue(compare(tu('1\'(3+7/16)"'), 392.112500)) + # tu = FreeCAD.Units.translateUnit + self.assertTrue(compare(tu("3/8in"), 9.525)) + # self.assertTrue(compare(tu('1fo(3+7/16)in'),392.112500))thisgivesaparsersyntaxerror!!! + self.assertTrue(compare(tu("1'(3+7/16)\""), 392.112500)) psi = FreeCAD.Units.parseQuantity("1psi") mpa = psi.getValueAs("MPa").Value @@ -91,7 +94,7 @@ class UnitBasicCases(unittest.TestCase): def testDivide(self): qu1 = FreeCAD.Units.Quantity("1 m/s") qu2 = FreeCAD.Units.Quantity("m/s") - self.assertTrue(qu1/qu2, 1) + self.assertTrue(qu1 / qu2, 1) def testSchemes(self): schemes = FreeCAD.Units.listSchemas() @@ -101,20 +104,41 @@ class UnitBasicCases(unittest.TestCase): for i in range(num): t = FreeCAD.Units.schemaTranslate(psi, i) v = FreeCAD.Units.parseQuantity(t[0]).getValueAs("psi") - self.assertAlmostEqual(1, v.Value, msg="Failed with \"{0}\" scheme: {1} != 1 (delta: {2})".format(schemes[i], v.Value, self.delta), delta=self.delta) + self.assertAlmostEqual( + 1, + v.Value, + msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format( + schemes[i], v.Value, self.delta + ), + delta=self.delta, + ) ksi = FreeCAD.Units.parseQuantity("1ksi") for i in range(num): t = FreeCAD.Units.schemaTranslate(ksi, i) v = FreeCAD.Units.parseQuantity(t[0]).getValueAs("ksi") - self.assertAlmostEqual(1, v.Value, msg="Failed with \"{0}\" scheme: {1} != 1 (delta: {2})".format(schemes[i], v.Value, self.delta), delta=self.delta) + self.assertAlmostEqual( + 1, + v.Value, + msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format( + schemes[i], v.Value, self.delta + ), + delta=self.delta, + ) vacuum_permittivity = FreeCAD.Units.parseQuantity("1F/m") - vacuum_permittivity.Format = {"NumberFormat" : FreeCAD.Units.NumberFormat.Scientific} + vacuum_permittivity.Format = {"NumberFormat": FreeCAD.Units.NumberFormat.Scientific} for i in range(num): t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, i) v = FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m") - self.assertAlmostEqual(1, v.Value, msg="Failed with \"{0}\" scheme: {1} != 1 (delta: {2})".format(schemes[i], v.Value, self.delta), delta=self.delta) + self.assertAlmostEqual( + 1, + v.Value, + msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format( + schemes[i], v.Value, self.delta + ), + delta=self.delta, + ) def testSchemeTranslation(self): quantities = [] @@ -126,33 +150,37 @@ class UnitBasicCases(unittest.TestCase): for i in quantities: q1 = getattr(FreeCAD.Units, i) q1 = FreeCAD.Units.Quantity(q1) - q1.Format = {'Precision': 16} + q1.Format = {"Precision": 16} for idx, val in enumerate(schemes): [t, amountPerUnit, unit] = FreeCAD.Units.schemaTranslate(q1, idx) try: q2 = FreeCAD.Units.Quantity(t) if math.fabs(q1.Value - q2.Value) > 0.01: - print (" {} : {} : {} : {} : {}".format(q1, q2, t, i, val).encode("utf-8").strip()) + print( + " {} : {} : {} : {} : {}".format(q1, q2, t, i, val) + .encode("utf-8") + .strip() + ) except Exception as e: - print ("{} : {} : {} : {}".format(q1, i, val, e).encode("utf-8").strip()) + print("{} : {} : {} : {}".format(q1, i, val, e).encode("utf-8").strip()) def testVoltage(self): q1 = FreeCAD.Units.Quantity("1e20 V") - t = FreeCAD.Units.schemaTranslate(q1, 0) # Standard + t = FreeCAD.Units.schemaTranslate(q1, 0) # Standard q2 = FreeCAD.Units.Quantity(t[0]) self.assertAlmostEqual(q1.Value, q2.Value, delta=self.delta) def testEnergy(self): q1 = FreeCAD.Units.Quantity("1e20 J") - t = FreeCAD.Units.schemaTranslate(q1, 0) # Standard + t = FreeCAD.Units.schemaTranslate(q1, 0) # Standard q2 = FreeCAD.Units.Quantity(t[0]) self.assertAlmostEqual(q1.Value, q2.Value, delta=self.delta) def testTrigonometric(self): - #tu=FreeCAD.Units.translateUnit - self.assertTrue(compare(tu('sin(pi)'), math.sin(math.pi))) - self.assertTrue(compare(tu('cos(pi)'), math.cos(math.pi))) - self.assertTrue(compare(tu('tan(pi)'), math.tan(math.pi))) + # tu=FreeCAD.Units.translateUnit + self.assertTrue(compare(tu("sin(pi)"), math.sin(math.pi))) + self.assertTrue(compare(tu("cos(pi)"), math.cos(math.pi))) + self.assertTrue(compare(tu("tan(pi)"), math.tan(math.pi))) def testQuantity(self): length = FreeCAD.Units.Quantity(1, "m") @@ -160,34 +188,34 @@ class UnitBasicCases(unittest.TestCase): self.assertEqual(length.Unit, FreeCAD.Units.Length) def testToString(self): - value = FreeCAD.Units.toNumber(1023, 'g', 2) + value = FreeCAD.Units.toNumber(1023, "g", 2) self.assertEqual(float(value), 1000) - value = FreeCAD.Units.toNumber(1023, 'g', 3) + value = FreeCAD.Units.toNumber(1023, "g", 3) self.assertEqual(float(value), 1020) - value = FreeCAD.Units.toNumber(1023, 'f', 2) + value = FreeCAD.Units.toNumber(1023, "f", 2) self.assertEqual(float(value), 1023) - value = FreeCAD.Units.toNumber(1023, 'e', 1) + value = FreeCAD.Units.toNumber(1023, "e", 1) self.assertEqual(float(value), 1000) - value = FreeCAD.Units.toNumber(1023, 'e', 2) + value = FreeCAD.Units.toNumber(1023, "e", 2) self.assertEqual(float(value), 1020) - value = FreeCAD.Units.toNumber(1023, 'e', 3) + value = FreeCAD.Units.toNumber(1023, "e", 3) self.assertEqual(float(value), 1023) q = FreeCAD.Units.Quantity("1023") - value = FreeCAD.Units.toNumber(q, 'f', 2) + value = FreeCAD.Units.toNumber(q, "f", 2) self.assertEqual(float(value), 1023) with self.assertRaises(TypeError): - FreeCAD.Units.toNumber("1023", 'g', 2) + FreeCAD.Units.toNumber("1023", "g", 2) with self.assertRaises(ValueError): - FreeCAD.Units.toNumber(1023, 'gg', 2) + FreeCAD.Units.toNumber(1023, "gg", 2) with self.assertRaises(ValueError): - FreeCAD.Units.toNumber(1023, 's', 2) + FreeCAD.Units.toNumber(1023, "s", 2) def testIssue6735(self): FreeCAD.Units.Quantity("1400.0 N/mm^2") diff --git a/src/Mod/Test/Workbench.py b/src/Mod/Test/Workbench.py index d6807ce50d..6890b5bf4c 100755 --- a/src/Mod/Test/Workbench.py +++ b/src/Mod/Test/Workbench.py @@ -1,25 +1,26 @@ -#*************************************************************************** -#* Copyright (c) 2006 Werner Mayer * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * Copyright (c) 2006 Werner Mayer * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # Workbench test module @@ -29,58 +30,69 @@ import tempfile from PySide import QtWidgets, QtCore from PySide.QtWidgets import QApplication + class CallableCheckWarning: def __call__(self): diag = QApplication.activeModalWidget() - if (diag): - QtCore.QTimer.singleShot(0, diag, QtCore.SLOT('accept()')) + if diag: + QtCore.QTimer.singleShot(0, diag, QtCore.SLOT("accept()")) + class WorkbenchTestCase(unittest.TestCase): def setUp(self): self.Active = FreeCADGui.activeWorkbench() FreeCAD.Console.PrintLog(FreeCADGui.activeWorkbench().name()) - + def testActivate(self): - wbs=FreeCADGui.listWorkbenches() + wbs = FreeCADGui.listWorkbenches() # this gives workbenches a possibility to detect that we're under test environment FreeCAD.TestEnvironment = True for i in wbs: try: - print ("Activate workbench '{}'".format(i)) + print("Activate workbench '{}'".format(i)) cobj = CallableCheckWarning() QtCore.QTimer.singleShot(500, cobj) success = FreeCADGui.activateWorkbench(i) - FreeCAD.Console.PrintLog("Active: "+FreeCADGui.activeWorkbench().name()+ " Expected: "+i+"\n") + FreeCAD.Console.PrintLog( + "Active: " + FreeCADGui.activeWorkbench().name() + " Expected: " + i + "\n" + ) self.assertTrue(success, "Test on activating workbench {0} failed".format(i)) except Exception as e: self.fail("Loading of workbench '{0}' failed: {1}".format(i, e)) del FreeCAD.TestEnvironment - + def testHandler(self): import __main__ + class UnitWorkbench(__main__.Workbench): MenuText = "Unittest" ToolTip = "Unittest" + def Initialize(self): cmds = ["Test_Test"] - self.appendToolbar("My Unittest",cmds) + self.appendToolbar("My Unittest", cmds) + def GetClassName(self): return "Gui::PythonWorkbench" FreeCADGui.addWorkbench(UnitWorkbench()) - wbs=FreeCADGui.listWorkbenches() + wbs = FreeCADGui.listWorkbenches() self.failUnless("UnitWorkbench" in wbs, "Test on adding workbench handler failed") FreeCADGui.activateWorkbench("UnitWorkbench") FreeCADGui.updateGui() - self.failUnless(FreeCADGui.activeWorkbench().name()=="UnitWorkbench", "Test on loading workbench 'Unittest' failed") + self.failUnless( + FreeCADGui.activeWorkbench().name() == "UnitWorkbench", + "Test on loading workbench 'Unittest' failed", + ) FreeCADGui.removeWorkbench("UnitWorkbench") - wbs=FreeCADGui.listWorkbenches() + wbs = FreeCADGui.listWorkbenches() self.failUnless(not "UnitWorkbench" in wbs, "Test on removing workbench handler failed") def testInvalidType(self): class MyExtWorkbench(FreeCADGui.Workbench): def Initialize(self): pass + def GetClassName(self): return "App::Extension" @@ -93,6 +105,7 @@ class WorkbenchTestCase(unittest.TestCase): FreeCADGui.activateWorkbench(self.Active.name()) FreeCAD.Console.PrintLog(self.Active.name()) + class CommandTestCase(unittest.TestCase): def testPR6889(self): # Fixes a crash @@ -106,13 +119,16 @@ class CommandTestCase(unittest.TestCase): cmd = FreeCADGui.Command.get(name) cmd.run() + class TestNavigationStyle(unittest.TestCase): def setUp(self): self.Doc = FreeCAD.newDocument("CreateTest") def testInvalidStyle(self): FreeCADGui.getDocument(self.Doc).ActiveView.setNavigationType("App::Extension") - self.assertNotEqual(FreeCADGui.getDocument(self.Doc).ActiveView.getNavigationType(), "App::Extension") + self.assertNotEqual( + FreeCADGui.getDocument(self.Doc).ActiveView.getNavigationType(), "App::Extension" + ) def tearDown(self): FreeCAD.closeDocument("CreateTest") diff --git a/src/Mod/Test/__init__.py b/src/Mod/Test/__init__.py index 60247201e2..b929969e9f 100644 --- a/src/Mod/Test/__init__.py +++ b/src/Mod/Test/__init__.py @@ -1,9 +1,11 @@ import unittest + def runTestsFromClass(test_case_class, verbosity=2): suite = unittest.TestLoader().loadTestsFromTestCase(test_case_class) unittest.TextTestRunner(verbosity=verbosity).run(suite) + def runTestsFromModule(test_module, verbosity=2): suite = unittest.TestLoader().loadTestsFromModule(test_module) unittest.TextTestRunner(verbosity=verbosity).run(suite) diff --git a/src/Mod/Test/testPathArray.py b/src/Mod/Test/testPathArray.py index 327748e45c..d99377d3c8 100644 --- a/src/Mod/Test/testPathArray.py +++ b/src/Mod/Test/testPathArray.py @@ -1,27 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#*************************************************************************** -#* Copyright (c) 2013 WandererFan * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2013 WandererFan * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # Tester for Draft makePathArray - shapes on a path - without subelements (see testPathArraySel.py) # Usage: in FC gui, select a "shape" document object (sphere, box, etc) (!!select in @@ -34,11 +34,11 @@ import Part import Draft print("testPathArray started") -items = 4 # count -centretrans = FreeCAD.Vector(0,0,0) # no translation -#centretrans = FreeCAD.Vector(-5,-5,0) # translation -orient = True # align to curve -#orient = False # don't align to curve +items = 4 # count +centretrans = FreeCAD.Vector(0, 0, 0) # no translation +# centretrans = FreeCAD.Vector(-5,-5,0) # translation +orient = True # align to curve +# orient = False # don't align to curve s = FreeCADGui.Selection.getSelection() print("testPathArray: Objects in selection: ", len(s)) @@ -48,7 +48,7 @@ base = s[0] path = s[1] pathsubs = [] -#o = Draft.makePathArray(base,path,items) # test with defaults -o = Draft.makePathArray(base,path,items,centretrans,orient,pathsubs) # test with non-defaults +# o = Draft.makePathArray(base,path,items) # test with defaults +o = Draft.makePathArray(base, path, items, centretrans, orient, pathsubs) # test with non-defaults print("testPathArray ended") diff --git a/src/Mod/Test/testPathArraySel.py b/src/Mod/Test/testPathArraySel.py index 9cfbd572be..91a07b8ae0 100644 --- a/src/Mod/Test/testPathArraySel.py +++ b/src/Mod/Test/testPathArraySel.py @@ -1,27 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#*************************************************************************** -#* Copyright (c) 2013 WandererFan * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2013 WandererFan * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # Tester for Draft makePathArray - shapes on a path - with selected subobjects # Usage: in FC gui, select a "shape" document object (sphere, box, etc) (!select in @@ -33,20 +33,20 @@ import Part import Draft print("testPathArray started") -items = 4 # count -centretrans = FreeCAD.Vector(0,0,0) # translation -#centretrans = FreeCAD.Vector(10,10,10) # translation -orient = True # align to curve -#orient = False # don't align to curve +items = 4 # count +centretrans = FreeCAD.Vector(0, 0, 0) # translation +# centretrans = FreeCAD.Vector(10,10,10) # translation +orient = True # align to curve +# orient = False # don't align to curve # use this to test w/ path subelements s = FreeCADGui.Selection.getSelectionEx() for o in s: - print("Selection: ", o.ObjectName) - for name in o.SubElementNames: - print(" name: ", name) - for obj in o.SubObjects: - print(" object: ",obj) + print("Selection: ", o.ObjectName) + for name in o.SubElementNames: + print(" name: ", name) + for obj in o.SubObjects: + print(" object: ", obj) print("testPathArray: Objects in selection: ", len(s)) base = s[0].Object @@ -54,7 +54,9 @@ path = s[1].Object pathsubs = list(s[1].SubElementNames) print("testPathArray: pathsubs: ", pathsubs) -#o = Draft.makePathArray(base,path,items) # test with defaults -o = Draft.makePathArray(base,path,items,centretrans,orient,pathsubs) # test w/o orienting shapes +# o = Draft.makePathArray(base,path,items) # test with defaults +o = Draft.makePathArray( + base, path, items, centretrans, orient, pathsubs +) # test w/o orienting shapes print("testPathArray ended") diff --git a/src/Mod/Test/testmakeWireString.py b/src/Mod/Test/testmakeWireString.py index a378f1b6ab..a1f5ab016b 100644 --- a/src/Mod/Test/testmakeWireString.py +++ b/src/Mod/Test/testmakeWireString.py @@ -35,35 +35,35 @@ print("testWire started") # test strings # if string contains funky characters, it has to be declared as Unicode or it # turns into the default encoding (usually utf8). FT2 doesn't do utf8. -#String = 'Wide WMA_' # wide glyphs for tracking -#String = 'Big' -#String = u'ecAnO' # UCS-2 w/ only ASCII -#String = u'ucs2uéçÄñØ' # UCS-2 -#String = 'utf8!uéçÄñØ' # UTF-8 -#String = 'abcdefghijklmnopqrstuvwxyz0123456789' -#String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' -#String = 'Big Daddy' # white space -#String = 'AVWAIXA.V' # kerning -String = 'FreeCAD' # ASCII +# String = 'Wide WMA_' # wide glyphs for tracking +# String = 'Big' +# String = u'ecAnO' # UCS-2 w/ only ASCII +# String = u'ucs2uéçÄñØ' # UCS-2 +# String = 'utf8!uéçÄñØ' # UTF-8 +# String = 'abcdefghijklmnopqrstuvwxyz0123456789' +# String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +# String = 'Big Daddy' # white space +# String = 'AVWAIXA.V' # kerning +String = "FreeCAD" # ASCII -#FontPath = '/usr/share/fonts/truetype/msttcorefonts/' -#FontName = 'Times_New_Roman_Italic.ttf' -FontPath = '/usr/share/fonts/truetype/msttcorefonts/' -FontName = 'Arial.ttf' -#FontName = 'NOTArial.ttf' # font file not found error -#FontPath = '/usr/share/fonts/truetype/msttcorefonts/' -#FontName = 'ariali.ttf' # symlink to ttf -#FontPath = '/usr/share/fonts/truetype/' -#FontName = 'Peterbuilt.ttf' # overlapping script font -#FontPath = '/usr/share/fonts/truetype/' -#FontName = 'dyspepsia.ttf' # overlapping script font # :) +# FontPath = '/usr/share/fonts/truetype/msttcorefonts/' +# FontName = 'Times_New_Roman_Italic.ttf' +FontPath = "/usr/share/fonts/truetype/msttcorefonts/" +FontName = "Arial.ttf" +# FontName = 'NOTArial.ttf' # font file not found error +# FontPath = '/usr/share/fonts/truetype/msttcorefonts/' +# FontName = 'ariali.ttf' # symlink to ttf +# FontPath = '/usr/share/fonts/truetype/' +# FontName = 'Peterbuilt.ttf' # overlapping script font +# FontPath = '/usr/share/fonts/truetype/' +# FontName = 'dyspepsia.ttf' # overlapping script font # :) -Height = 2000 # out string height FCunits -Track = 0 # intercharacter spacing +Height = 2000 # out string height FCunits +Track = 0 # intercharacter spacing print("testWire.py input String contains ", len(String), " characters.") -s = Part.makeWireString(String,FontPath,FontName,Height,Track) +s = Part.makeWireString(String, FontPath, FontName, Height, Track) print("returned from makeWireString") print("testWire.py output contains ", len(s), " WireChars.")