1
/***************************************************************************
2
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
26
#include <boost/core/ignore_unused.hpp>
30
#include <Base/Console.h>
31
#include <Base/Exception.h>
32
#include <Base/Interpreter.h>
34
#include <CXX/Objects.hxx>
36
#include "FeatureTest.h"
41
#pragma warning( disable : 4700 )
42
#pragma warning( disable : 4723 )
48
PROPERTY_SOURCE(App::FeatureTest, App::DocumentObject)
50
const char* enums[]= {"Zero","One","Two","Three","Four",nullptr};
51
const PropertyIntegerConstraint::Constraints intPercent = {0,100,1};
52
const PropertyFloatConstraint::Constraints floatPercent = {0.0,100.0,1.0};
55
FeatureTest::FeatureTest()
57
ADD_PROPERTY(Integer,(4711) );
58
ADD_PROPERTY(Float ,(47.11f) );
59
ADD_PROPERTY(Bool ,(true) );
60
ADD_PROPERTY(BoolList,(false));
61
ADD_PROPERTY(String ,("4711"));
62
ADD_PROPERTY(Path ,("c:\\temp"));
63
ADD_PROPERTY(StringList ,("4711"));
65
ADD_PROPERTY(Enum ,(4));
67
ADD_PROPERTY(ConstraintInt ,(5));
68
ConstraintInt.setConstraints(&intPercent);
69
ADD_PROPERTY(ConstraintFloat ,(5.0));
70
ConstraintFloat.setConstraints(&floatPercent);
73
App::Material mat(App::Material::GOLD);
74
ADD_PROPERTY(Colour ,(c) );
75
ADD_PROPERTY(ColourList ,(c) );
76
ADD_PROPERTY(Material ,(mat));
77
ADD_PROPERTY(MaterialList,(mat));
79
ADD_PROPERTY(Distance,(47.11f) );
80
ADD_PROPERTY(Angle ,(3.0f) );
82
ADD_PROPERTY(IntegerList,(4711) );
83
ADD_PROPERTY(FloatList ,(47.11f) );
85
ADD_PROPERTY(Link ,(nullptr));
86
ADD_PROPERTY(LinkSub ,(nullptr));
87
ADD_PROPERTY(LinkList ,(nullptr));
88
ADD_PROPERTY(LinkSubList,(nullptr));
90
ADD_PROPERTY(Vector ,(1.0,2.0,3.0));
91
ADD_PROPERTY(VectorList,(3.0,2.0,1.0));
92
ADD_PROPERTY(Matrix ,(Base::Matrix4D(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)));
93
ADD_PROPERTY(Placement ,(Base::Placement()));
95
// properties for recompute testing
96
static const char* group = "Feature Test";
97
ADD_PROPERTY_TYPE(Source1 ,(nullptr),group,Prop_None,"Source for testing links");
98
ADD_PROPERTY_TYPE(Source2 ,(nullptr),group,Prop_None,"Source for testing links");
99
ADD_PROPERTY_TYPE(SourceN ,(nullptr),group,Prop_None,"Source for testing links");
100
ADD_PROPERTY_TYPE(ExecResult ,("empty"),group,Prop_None,"Result of the execution");
101
ADD_PROPERTY_TYPE(ExceptionType ,(0),group,Prop_None,"The type of exception the execution method throws");
102
ADD_PROPERTY_TYPE(ExecCount ,(0),group,Prop_None,"Number of executions");
104
// properties with types
105
ADD_PROPERTY_TYPE(TypeHidden ,(4711),group,Prop_Hidden,"An example property which has the type 'Hidden'" );
106
ADD_PROPERTY_TYPE(TypeReadOnly,(4711),group,Prop_ReadOnly ,"An example property which has the type 'ReadOnly'" );
107
ADD_PROPERTY_TYPE(TypeOutput ,(4711),group,Prop_Output ,"An example property which has the type 'Output'" );
108
ADD_PROPERTY_TYPE(TypeTransient,(4711),group,Prop_Transient ,"An example property which has the type 'Transient'" );
109
ADD_PROPERTY_TYPE(TypeNoRecompute,(4711),group,Prop_NoRecompute,"An example property which has the type 'NoRecompute'");
110
ADD_PROPERTY_TYPE(TypeAll ,(4711),group,(App::PropertyType) (Prop_Output|Prop_ReadOnly |Prop_Hidden ),
111
"An example property which has the types 'Output', 'ReadOnly' and 'Hidden'");
113
ADD_PROPERTY(QuantityLength,(1.0));
114
QuantityLength.setUnit(Base::Unit::Length);
115
ADD_PROPERTY(QuantityOther,(5.0));
116
QuantityOther.setUnit(Base::Unit(-3,1));
119
FeatureTest::~FeatureTest() = default;
121
short FeatureTest::mustExecute() const
123
return DocumentObject::mustExecute();
126
DocumentObjectExecReturn *FeatureTest::execute()
129
Enumeration enumObj1 = Enum.getEnum();
130
enumObj1.setValue(7, false);
131
enumObj1.setValue(4, true);
133
Enumeration enumObj2 = Enum.getEnum();
134
enumObj2.setValue(4, true);
136
Enumeration enumObj3(enumObj2);
137
const char* val = enumObj3.getCStr();
138
enumObj3.isValue(val);
139
enumObj3.getEnumVector();
141
Enumeration enumObj4("Single item");
142
enumObj4.setEnums(enums);
143
boost::ignore_unused(enumObj4 == enumObj2);
144
enumObj4.setEnums(nullptr);
146
boost::ignore_unused(enumObj4 == enumObj4.getCStr());
148
Enumeration enumObj5(enums, enums[3]);
149
enumObj5.isValue(enums[2]);
150
enumObj5.isValue(enums[3]);
151
enumObj5.contains(enums[1]);
153
Enumeration enumObj6;
154
enumObj6.setEnums(enums);
155
enumObj6.setValue(enums[1]);
156
std::vector<std::string> list;
157
list.emplace_back("Hello");
158
list.emplace_back("World");
159
enumObj6.setEnums(list);
160
enumObj6.setValue(list.back());
167
// Code analyzers may complain about some errors. This can be ignored
168
// because this is done on purpose to test the error handling mechanism
169
switch(ExceptionType.getValue())
172
case 1: throw std::runtime_error("Test Exception");
173
case 2: throw Base::RuntimeError("FeatureTestException::execute(): Testexception");
174
default: (void)i; (void)j; (void)f; (void)s; (void)t; break;
177
ExecCount.setValue(ExecCount.getValue() + 1);
179
ExecResult.setValue("Exec");
181
return DocumentObject::StdReturn;
184
// ----------------------------------------------------------------------------
186
PROPERTY_SOURCE(App::FeatureTestException, App::FeatureTest)
189
FeatureTestException::FeatureTestException()
191
ADD_PROPERTY(ExceptionType,(Base::Exception::getClassTypeId().getKey()) );
194
DocumentObjectExecReturn *FeatureTestException::execute()
197
throw Base::RuntimeError("FeatureTestException::execute(): Testexception ;-)");
202
// ----------------------------------------------------------------------------
204
PROPERTY_SOURCE(App::FeatureTestColumn, App::DocumentObject)
207
FeatureTestColumn::FeatureTestColumn()
209
ADD_PROPERTY_TYPE(Column, ("A"), "Test", App::Prop_None, "");
210
ADD_PROPERTY_TYPE(Silent, (false), "Test", App::Prop_None, "");
211
ADD_PROPERTY_TYPE(Value, (0L), "Test", App::Prop_Output, "");
214
DocumentObjectExecReturn *FeatureTestColumn::execute()
216
Value.setValue(decodeColumn(Column.getStrValue(), Silent.getValue()));
220
// ----------------------------------------------------------------------------
222
PROPERTY_SOURCE(App::FeatureTestRow, App::DocumentObject)
225
FeatureTestRow::FeatureTestRow()
227
ADD_PROPERTY_TYPE(Row, ("1"), "Test", App::Prop_None, "");
228
ADD_PROPERTY_TYPE(Silent, (false), "Test", App::Prop_None, "");
229
ADD_PROPERTY_TYPE(Value, (0L), "Test", App::Prop_Output, "");
232
DocumentObjectExecReturn *FeatureTestRow::execute()
234
Value.setValue(decodeRow(Row.getStrValue(), Silent.getValue()));
238
// ----------------------------------------------------------------------------
240
PROPERTY_SOURCE(App::FeatureTestAbsAddress, App::DocumentObject)
243
FeatureTestAbsAddress::FeatureTestAbsAddress()
245
ADD_PROPERTY_TYPE(Address, (""), "Test", Prop_None, "");
246
ADD_PROPERTY_TYPE(Valid, (false), "Test", PropertyType(Prop_Output | Prop_ReadOnly), "");
249
DocumentObjectExecReturn *FeatureTestAbsAddress::execute()
252
Valid.setValue(address.parseAbsoluteAddress(Address.getValue()));
256
// ----------------------------------------------------------------------------
258
PROPERTY_SOURCE(App::FeatureTestPlacement, App::DocumentObject)
261
FeatureTestPlacement::FeatureTestPlacement()
263
ADD_PROPERTY_TYPE(Input1, (Base::Placement()), "Test", Prop_None, "");
264
ADD_PROPERTY_TYPE(Input2, (Base::Placement()), "Test", Prop_None, "");
265
ADD_PROPERTY_TYPE(MultLeft, (Base::Placement()), "Test", Prop_Output, "");
266
ADD_PROPERTY_TYPE(MultRight, (Base::Placement()), "Test", Prop_Output, "");
269
DocumentObjectExecReturn *FeatureTestPlacement::execute()
271
Base::Placement p1 = Input1.getValue();
272
Base::Placement q1 = Input1.getValue();
273
Base::Placement p2 = Input2.getValue();
274
MultLeft.setValue(p1.multLeft(p2));
275
MultRight.setValue(q1.multRight(p2));
279
// ----------------------------------------------------------------------------
281
PROPERTY_SOURCE(App::FeatureTestAttribute, App::DocumentObject)
284
FeatureTestAttribute::FeatureTestAttribute()
286
ADD_PROPERTY(Object, (Py::Object()));
287
ADD_PROPERTY(Attribute, ("Name"));
290
FeatureTestAttribute::~FeatureTestAttribute()
292
Base::PyGILStateLocker lock;
294
Object.getValue().getAttr("Name");
295
#if PYCXX_VERSION_MAJOR >= 7
296
Py::ifPyErrorThrowCxxException();
298
if (PyErr_Occurred())
299
throw Py::RuntimeError();
302
catch (Py::RuntimeError& e) {
305
catch (Py::Exception& e) {
307
Base::Console().Error("Unexpected exception in ~FeatureTestRemoval()\n");
311
DocumentObjectExecReturn *FeatureTestAttribute::execute()
313
Base::PyGILStateLocker lock;
315
Object.getValue().getAttr(Attribute.getValue());
316
#if PYCXX_VERSION_MAJOR >= 7
317
Py::ifPyErrorThrowCxxException();
319
if (PyErr_Occurred())
320
throw Py::AttributeError();
323
catch (Py::AttributeError& e) {
325
std::stringstream str;
326
str << "No such attribute '" << Attribute.getValue() << "'";
327
throw Base::AttributeError(str.str());