From 8efe30c8a90305d688fa164048941be1fd474918 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Aug 2022 15:46:40 +0200 Subject: [PATCH] Test: add test feature for unit tests --- src/App/Application.cpp | 1 + src/App/FeatureTest.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ src/App/FeatureTest.h | 14 ++++++++++ src/Mod/Test/Document.py | 29 ++++++++++++++++++++ 4 files changed, 101 insertions(+) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 3af3f26fe8..8aaa1fd782 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1996,6 +1996,7 @@ void Application::initTypes() App::FeatureTestException ::init(); App::FeatureTestColumn ::init(); App::FeatureTestPlacement ::init(); + App::FeatureTestAttribute ::init(); // Feature class App::FeaturePython ::init(); diff --git a/src/App/FeatureTest.cpp b/src/App/FeatureTest.cpp index 2a142edee6..e5ef2875ff 100644 --- a/src/App/FeatureTest.cpp +++ b/src/App/FeatureTest.cpp @@ -24,10 +24,14 @@ #include "PreCompiled.h" #ifndef _PreComp_ #include +#include #endif +#include #include +#include #include +#include #include "FeatureTest.h" #include "Material.h" @@ -235,3 +239,56 @@ DocumentObjectExecReturn *FeatureTestPlacement::execute() MultRight.setValue(q1.multRight(p2)); return nullptr; } + +// ---------------------------------------------------------------------------- + +PROPERTY_SOURCE(App::FeatureTestAttribute, App::DocumentObject) + + +FeatureTestAttribute::FeatureTestAttribute() +{ + ADD_PROPERTY(Object, (Py::Object())); + ADD_PROPERTY(Attribute, ("Name")); +} + +FeatureTestAttribute::~FeatureTestAttribute() +{ + Base::PyGILStateLocker lock; + try { + Object.getValue().getAttr("Name"); +#if PYCXX_VERSION_MAJOR >= 7 + Py::ifPyErrorThrowCxxException(); +#else + if (PyErr_Occurred()) + throw Py::RuntimeError(); +#endif + } + catch (Py::RuntimeError& e) { + e.clear(); + } + catch (Py::Exception& e) { + e.clear(); + Base::Console().Error("Unexpected exception in ~FeatureTestRemoval()\n"); + } +} + +DocumentObjectExecReturn *FeatureTestAttribute::execute() +{ + Base::PyGILStateLocker lock; + try { + Object.getValue().getAttr(Attribute.getValue()); +#if PYCXX_VERSION_MAJOR >= 7 + Py::ifPyErrorThrowCxxException(); +#else + if (PyErr_Occurred()) + throw Py::AttributeError(); +#endif + } + catch (Py::AttributeError& e) { + e.clear(); + std::stringstream str; + str << "No such attribute '" << Attribute.getValue() << "'"; + throw Base::AttributeError(str.str()); + } + return StdReturn; +} diff --git a/src/App/FeatureTest.h b/src/App/FeatureTest.h index ce54d6cb4c..032e9473cd 100644 --- a/src/App/FeatureTest.h +++ b/src/App/FeatureTest.h @@ -27,6 +27,7 @@ #include "DocumentObject.h" #include "PropertyGeo.h" #include "PropertyLinks.h" +#include "PropertyPythonObject.h" #include "PropertyUnits.h" @@ -171,6 +172,19 @@ public: //@} }; +class FeatureTestAttribute : public DocumentObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestAttribute); + +public: + FeatureTestAttribute(); + ~FeatureTestAttribute() override; + DocumentObjectExecReturn *execute() override; + + App::PropertyPythonObject Object; + App::PropertyString Attribute; +}; + } //namespace App diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index a9eb158e92..9cdd2ed827 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -2306,3 +2306,32 @@ class FeatureTestColumn(unittest.TestCase): def tearDown(self): FreeCAD.closeDocument("TestColumn") + + +class FeatureTestAttribute(unittest.TestCase): + def setUp(self): + self.doc = FreeCAD.newDocument("TestAttribute") + self.doc.UndoMode = 0 + + def testValidAttribute(self): + obj = self.doc.addObject("App::FeatureTestAttribute", "Attribute") + obj.Object = obj + obj.Attribute = "Name" + self.doc.recompute() + self.assertIn("Up-to-date", obj.State) + + def testInvalidAttribute(self): + obj = self.doc.addObject("App::FeatureTestAttribute", "Attribute") + obj.Object = obj + obj.Attribute = "Name123" + self.doc.recompute() + self.assertIn("Invalid", obj.State) + self.assertIn("Touched", obj.State) + + def testRemoval(self): + obj = self.doc.addObject("App::FeatureTestAttribute", "Attribute") + obj.Object = obj + self.assertEqual(self.doc.removeObject("Attribute"), None) + + def tearDown(self): + FreeCAD.closeDocument("TestAttribute")