From de93446a1c8bb2217cf50e9b99360cf1f6ee3eac Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 13 Jul 2019 21:38:16 +0800 Subject: [PATCH] Test cases changes Slight adjustment of various test cases due to various API changes. --- src/Mod/Part/TestPartApp.py | 1 + .../PartDesignTests/TestMirrored.py | 2 +- src/Mod/Path/PathTests/TestPathUtil.py | 1 + src/Mod/Spreadsheet/TestSpreadsheet.py | 20 +++-- src/Mod/Test/Document.py | 87 ++++++++++++++----- 5 files changed, 84 insertions(+), 27 deletions(-) diff --git a/src/Mod/Part/TestPartApp.py b/src/Mod/Part/TestPartApp.py index c6669e35c5..0b4d08ee31 100644 --- a/src/Mod/Part/TestPartApp.py +++ b/src/Mod/Part/TestPartApp.py @@ -110,6 +110,7 @@ class PartTestBSplineCurve(unittest.TestCase): Box = self.Doc.addObject("Part::Box","Box") Mirroring = self.Doc.addObject("Part::Mirroring", 'Mirroring') Spreadsheet = self.Doc.addObject('Spreadsheet::Sheet', 'Spreadsheet') + Mirroring.Source = Box Mirroring.Base = (8, 5, 25) Mirroring.Normal = (0.5, 0.2, 0.9) Spreadsheet.set('A1', '=Mirroring.Base.x') diff --git a/src/Mod/PartDesign/PartDesignTests/TestMirrored.py b/src/Mod/PartDesign/PartDesignTests/TestMirrored.py index 138174ed4f..fd6b32a34f 100644 --- a/src/Mod/PartDesign/PartDesignTests/TestMirrored.py +++ b/src/Mod/PartDesign/PartDesignTests/TestMirrored.py @@ -85,7 +85,7 @@ class TestMirrored(unittest.TestCase): self.Mirrored.MirrorPlane = (self.Rect, ["H_Axis"]) self.Body.addObject(self.Mirrored) self.Doc.recompute() - self.assertEqual(self.Mirrored.State, ["Invalid"]) + self.assertIn("Invalid", self.Mirrored.State) def tearDown(self): #closing doc diff --git a/src/Mod/Path/PathTests/TestPathUtil.py b/src/Mod/Path/PathTests/TestPathUtil.py index 20edcd276a..a842bea8f1 100644 --- a/src/Mod/Path/PathTests/TestPathUtil.py +++ b/src/Mod/Path/PathTests/TestPathUtil.py @@ -105,6 +105,7 @@ class TestPathUtil(PathTestBase): # create a valid base object box = self.doc.addObject("Part::Box","Box") + self.doc.recompute() self.assertTrue(PathUtil.isValidBaseObject(box)) # a part with at least one valid object is valid diff --git a/src/Mod/Spreadsheet/TestSpreadsheet.py b/src/Mod/Spreadsheet/TestSpreadsheet.py index 19ed6be8d4..49277b8852 100644 --- a/src/Mod/Spreadsheet/TestSpreadsheet.py +++ b/src/Mod/Spreadsheet/TestSpreadsheet.py @@ -492,10 +492,17 @@ class SpreadsheetCases(unittest.TestCase): sheet.set('A52', '=+(-1 + -1)') self.doc.addObject("Part::Cylinder", "Cylinder") - self.doc.addObject("Part::Thickness", "Pipe") + # We cannot use Thickness, as this feature requires a source shape, + # otherwise it will cause recomputation failure. The new logic of + # App::Document will not continue recompute any dependent objects + + # self.doc.addObject("Part::Thickness", "Pipe") + self.doc.addObject("Part::Box", "Box") + self.doc.Box.Length = 1 + sheet.set('B1', '101') sheet.set('A53', '=-(-(B1-1)/2)') - sheet.set('A54', '=-(Cylinder.Radius + Pipe.Value - 1"/2)') + sheet.set('A54', '=-(Cylinder.Radius + Box.Length - 1"/2)') self.doc.recompute() self.assertEqual(sheet.getContents("A1"), "=1 < 2 ? 3 : 4") @@ -700,8 +707,11 @@ class SpreadsheetCases(unittest.TestCase): sheet.setAlias('B1', 'alias1') box = self.doc.addObject('Part::Box', 'Box') box.setExpression('Length', 'Spreadsheet.alias1') + box2 = self.doc.addObject('Part::Box', 'Box') + box2.setExpression('Length', '<>.alias1') sheet.Label = "Params" - self.assertEqual(box.ExpressionEngine[0][1], "Params.alias1"); + self.assertEqual(box.ExpressionEngine[0][1], "Spreadsheet.alias1"); + self.assertEqual(box2.ExpressionEngine[0][1], "<>.alias1"); def testAlias(self): """ Playing with aliases """ @@ -787,11 +797,11 @@ class SpreadsheetCases(unittest.TestCase): index=sketch.addGeometry(Part.LineSegment(v(0,0,0),v(10,10,0)),False) sketch.addConstraint(Sketcher.Constraint('Distance',index,14.0)) self.doc.recompute() - sketch.setExpression('Constraints[0]', u'Spreadsheet.Length') + sketch.setExpression('Constraints[0]', u'<>.Length') self.doc.recompute() sheet.Label="Calc" self.doc.recompute() - self.assertEqual(sketch.ExpressionEngine[0][1],'Calc.Length') + self.assertEqual(sketch.ExpressionEngine[0][1],'<>.Length') self.assertIn('Up-to-date',sketch.State) def testCrossDocumentLinks(self): diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index d56272ae2f..4624f9d3ca 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -25,7 +25,6 @@ import FreeCAD, os, unittest, tempfile import math - #--------------------------------------------------------------------------- # define the functions to test the FreeCAD Document code #--------------------------------------------------------------------------- @@ -79,7 +78,7 @@ class DocumentBasicCases(unittest.TestCase): self.assertEqual(L1.ExecCount, countChild) self.assertEqual(L2.ExecCount, countParent+1) - L1.touch() + L1.touch('') countChild = L1.ExecCount countParent = L2.ExecCount objectcount = self.Doc.recompute() @@ -689,10 +688,12 @@ class UndoRedoCases(unittest.TestCase): # second transaction self.Doc.openTransaction("Transaction2") - self.assertEqual(self.Doc.UndoNames,['Transaction2','Transaction1']) - self.assertEqual(self.Doc.UndoCount,2) + # 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) @@ -717,19 +718,19 @@ class UndoRedoCases(unittest.TestCase): # 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.Doc.getObject("test1").Integer = 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) - self.Doc.getObject("test1").Integer = 4 # undo the fourth transaction self.Doc.undo() @@ -1626,11 +1627,25 @@ class DocumentObserverCases(unittest.TestCase): #undo/redo is not enabled in cmd line mode by default self.Doc2.UndoMode = 1 - self.Doc2.openTransaction('test') - self.assertEqual(self.Obs.signal.pop(), 'DocOpenTransaction') + # 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.assertEqual(self.Obs.parameter2.pop(), 'test') 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.signal = [] + self.Obs.parameter = [] + self.Obs.parameter2 = [] self.Doc2.commitTransaction() self.assertEqual(self.Obs.signal.pop(), 'DocCommitTransaction') @@ -1638,25 +1653,41 @@ class DocumentObserverCases(unittest.TestCase): self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) self.Doc2.openTransaction('test2') - self.assertEqual(self.Obs.signal.pop(), 'DocOpenTransaction') - self.assertTrue(self.Obs.parameter.pop() is self.Doc2) - self.assertEqual(self.Obs.parameter2.pop(), 'test2') - self.assertTrue(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) + # 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.signal = [] + self.Obs.parameter = [] + self.Obs.parameter2 = [] self.Doc2.abortTransaction() self.assertEqual(self.Obs.signal.pop(), 'DocAbortTransaction') 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) + # there will be other signals because of aborting the above addObject() + self.Obs.signal = [] + self.Obs.parameter = [] + self.Obs.parameter2 = [] self.Doc2.undo() self.assertEqual(self.Obs.signal.pop(), 'DocUndo') 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) + # there will be other signals because undoing the above addObject() + self.Obs.signal = [] + self.Obs.parameter = [] + self.Obs.parameter2 = [] self.Doc2.redo() self.assertEqual(self.Obs.signal.pop(), 'DocRedo') 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) + # there will be other signals because redoing the above addObject() + self.Obs.signal = [] + self.Obs.parameter = [] + self.Obs.parameter2 = [] self.Doc1.Comment = 'test comment' self.assertEqual(self.Obs.signal.pop(0), 'DocBeforeChange') @@ -1669,6 +1700,10 @@ class DocumentObserverCases(unittest.TestCase): 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) FreeCAD.closeDocument(self.Doc1.Name) @@ -1716,8 +1751,8 @@ class DocumentObserverCases(unittest.TestCase): self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2) FreeCAD.ActiveDocument.removeObject(obj.Name) - self.failUnless(self.Obs.signal.pop() == 'ObjDeleted') - self.failUnless(self.Obs.parameter.pop() is obj) + 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) pyobj = self.Doc1.addObject("App::FeaturePython","pyobj") @@ -1820,9 +1855,19 @@ class DocumentObserverCases(unittest.TestCase): self.Obs.parameter2 = [] self.failUnless(self.GuiObs.signal.pop() == "ObjCreated") self.failUnless(self.GuiObs.parameter.pop() is obj.ViewObject) - self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2) + + # There are object change signals, caused by sync of obj.Visibility. Same below. + self.GuiObs.signal = [] + self.GuiObs.parameter = [] + self.GuiObs.parameter2 = [] 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) @@ -1864,8 +1909,8 @@ class DocumentObserverCases(unittest.TestCase): vo = obj.ViewObject FreeCAD.ActiveDocument.removeObject(obj.Name) - self.failUnless(self.Obs.signal.pop() == 'ObjDeleted') - self.failUnless(self.Obs.parameter.pop() is obj) + 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)