File indexing completed on 2024-04-28 07:39:35

0001 /*
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "test_metaobject.h"
0008 
0009 #include "stepcore/object.h"
0010 
0011 #include <QString>
0012 #include <QMetaType>
0013 #include <QTest>
0014 
0015 struct MetaObjectTestType
0016 {
0017     int value;
0018     MetaObjectTestType(int v): value(v) {}
0019     MetaObjectTestType(): value(0) {}
0020 };
0021 Q_DECLARE_METATYPE( MetaObjectTestType ) 
0022 
0023 class MetaObjectTestInterface
0024 {
0025     STEPCORE_OBJECT(MetaObjectTestInterface)
0026 
0027 public:
0028     virtual ~MetaObjectTestInterface() {}
0029     double property1() const { return _property1; }
0030     void setProperty1(double property1) { _property1 = property1; }
0031 
0032 protected:
0033     double _property1;
0034 };
0035 
0036 class MetaObjectTestObject: public StepCore::Object, public MetaObjectTestInterface
0037 {
0038     STEPCORE_OBJECT(MetaObjectTestObject)
0039 
0040 public:
0041     int property2() const { return 2; }
0042 
0043     const MetaObjectTestType& property3() const { return _property3; }
0044     void setProperty3(const MetaObjectTestType& property3) { _property3 = property3; }
0045 
0046     MetaObjectTestType property4() const { return _property4; }
0047     bool setProperty4(MetaObjectTestType property4) {
0048         if(property4.value < 0) return false;
0049         _property4 = property4; return true;
0050     }
0051 
0052 protected:
0053     double             _property2;
0054     MetaObjectTestType _property3;
0055     MetaObjectTestType _property4;
0056 };
0057 
0058 namespace StepCore {
0059 template<> inline QString typeToString(const MetaObjectTestType& v)
0060 {
0061     return QString::number(v.value);
0062 }
0063 
0064 template<> inline MetaObjectTestType stringToType(const QString& s, bool* ok)
0065 {
0066     return MetaObjectTestType(s.toInt(ok));
0067 }
0068 
0069 template<> inline MetaObjectTestType variantToType(const QVariant& v, bool* ok)
0070 {
0071     if(v.userType() == qMetaTypeId<MetaObjectTestType>()) {
0072         *ok = true; return v.value<MetaObjectTestType>();
0073     }
0074     QVariant vc(v); *ok = vc.convert(QVariant::Int);
0075     return MetaObjectTestType(vc.value<int>());
0076 }
0077 
0078 }
0079 
0080 STEPCORE_META_OBJECT(MetaObjectTestInterface, "MetaObjectTestInterface", "TestInterface", StepCore::MetaObject::ABSTRACT,,
0081         STEPCORE_PROPERTY_RW(double, property1, "property1", "m", "Property1", property1, setProperty1))
0082 
0083 STEPCORE_META_OBJECT(MetaObjectTestObject, "MetaObjectTestObject", "TestObject", 0,
0084         STEPCORE_SUPER_CLASS(StepCore::Object) STEPCORE_SUPER_CLASS(MetaObjectTestInterface),
0085         STEPCORE_PROPERTY_R (int,   property2, "property2", STEPCORE_UNITS_1, "Property2", property2)
0086         STEPCORE_PROPERTY_RW(MetaObjectTestType, property3, "property3", STEPCORE_UNITS_NULL, "Property3", property3, setProperty3)
0087         STEPCORE_PROPERTY_RW(MetaObjectTestType, property4, "property4", STEPCORE_UNITS_NULL, "Property4", property4, setProperty4)
0088         )
0089 
0090 void TestMetaobject::testMetaObject()
0091 {
0092     /* Abstract class: can't create */
0093     QVERIFY( MetaObjectTestInterface::staticMetaObject()->isAbstract() );
0094     QVERIFY( MetaObjectTestInterface::staticMetaObject()->newObject() == nullptr );
0095 
0096     /* Normal class: should create */
0097     QVERIFY( !MetaObjectTestObject::staticMetaObject()->isAbstract() );
0098     StepCore::Object* object = MetaObjectTestObject::staticMetaObject()->newObject();
0099     QVERIFY( object != nullptr);
0100     MetaObjectTestObject* testObject = dynamic_cast<MetaObjectTestObject*>(object);
0101     QVERIFY( testObject != nullptr );
0102     
0103     QVERIFY( object->metaObject() == MetaObjectTestObject::staticMetaObject() );
0104 
0105     /* Class name */
0106     const StepCore::MetaObject* metaObject = testObject->metaObject();
0107     QCOMPARE( QString(metaObject->className()), QString("MetaObjectTestObject") );
0108 
0109     /* Super classes list */
0110     QCOMPARE( metaObject->superClassCount(), 2 );
0111     QCOMPARE( QString(metaObject->superClass(0)->className()), QString("Object") );
0112     QCOMPARE( QString(metaObject->superClass(1)->className()), QString("MetaObjectTestInterface") );
0113 
0114     /* Inheritance */
0115     QVERIFY( metaObject->inherits(StepCore::Object::staticMetaObject()) );
0116     QVERIFY( metaObject->inherits(MetaObjectTestInterface::staticMetaObject()) );
0117     QVERIFY( metaObject->inherits(metaObject) );
0118     QVERIFY( !MetaObjectTestInterface::staticMetaObject()->inherits(metaObject) );
0119 
0120     QVERIFY( metaObject->inherits("Object") );
0121     QVERIFY( metaObject->inherits("MetaObjectTestInterface") );
0122     QVERIFY( metaObject->inherits("MetaObjectTestObject") );
0123     QVERIFY( !metaObject->inherits("NotClass") );
0124     QVERIFY( !MetaObjectTestInterface::staticMetaObject()->inherits("MetaObjectTestObject") );
0125 
0126     /* Property count */
0127     QCOMPARE( metaObject->classPropertyCount(), 3 );
0128     QCOMPARE( metaObject->propertyCount(), 5 );
0129 
0130     /* Property lookup */
0131     QVERIFY( metaObject->property("name") == metaObject->property(0) );
0132     QVERIFY( metaObject->property("property1") == metaObject->property(1) );
0133     QVERIFY( metaObject->property("property2") == metaObject->property(2) );
0134     QVERIFY( metaObject->property("property3") == metaObject->property(3) );
0135     QVERIFY( metaObject->property("property4") == metaObject->property(4) );
0136     QVERIFY( metaObject->property("notProperty") == nullptr );
0137 
0138     const StepCore::MetaProperty* property;
0139 
0140     /* QString property inherited from first base class */ 
0141     property = testObject->metaObject()->property(0);
0142     QCOMPARE( QString(property->name()), QString("name") );
0143     QVERIFY( property->isReadable() );
0144     QVERIFY( property->isWritable() );
0145     QVERIFY( property->isStored() );
0146 
0147     QVERIFY( property->writeString(testObject, "test1") );
0148     QCOMPARE( object->name(), QString("test1") );
0149     QVERIFY( property->writeVariant(testObject, QVariant(QString("test2"))) );
0150     QCOMPARE( object->name(), QString("test2") );
0151 
0152     QCOMPARE( property->readString(object), QString("test2") );
0153     QCOMPARE( property->readVariant(object), QVariant(QString("test2")) );
0154 
0155     /* double property inherited from second base class */
0156     property = testObject->metaObject()->property(1);
0157     QCOMPARE( QString(property->name()), QString("property1") );
0158 
0159     QVERIFY( property->writeString(object, "1.1") );
0160     QCOMPARE( testObject->property1(), 1.1 );
0161     QVERIFY( property->writeVariant(object, QVariant(2.2)) );
0162     QCOMPARE( testObject->property1(), 2.2 );
0163     QCOMPARE( property->readString(object), QString("2.2") );
0164     QCOMPARE( property->readVariant(object), QVariant(2.2) );
0165 
0166     QVERIFY( !property->writeString(object, "not number") );
0167     QCOMPARE( testObject->property1(), 2.2 );
0168     QVERIFY( !property->writeVariant(object, QVariant("not number")) );
0169     QCOMPARE( testObject->property1(), 2.2 );
0170 
0171     /* double read-only property */
0172     property = testObject->metaObject()->property(2);
0173     QCOMPARE( QString(property->name()), QString("property2") );
0174     QVERIFY( property->isReadable() );
0175     QVERIFY( !property->isWritable() );
0176     QVERIFY( !property->isStored() );
0177 
0178     QVERIFY( !property->writeString(object, "10") );
0179     QCOMPARE( testObject->property2(), 2 );
0180     QCOMPARE( property->readString(object), QString("2") );
0181 
0182     /* MetaObjectTestType property */
0183     property = testObject->metaObject()->property(3);
0184     QCOMPARE( QString(property->name()), QString("property3") );
0185     
0186     QVERIFY( property->writeString(object, "2") );
0187     QCOMPARE( testObject->property3().value, 2 );
0188     QVERIFY( property->writeVariant(object, 3) );
0189     QCOMPARE( testObject->property3().value, 3 );
0190 
0191     QCOMPARE( property->readString(object), QString("3") );
0192     QCOMPARE( property->readVariant(object).value<MetaObjectTestType>().value, 3 );
0193 
0194     /* CloneObject */
0195     StepCore::Object* clone = object->metaObject()->cloneObject(*object);
0196     QCOMPARE( clone->name(), object->name() );
0197     QCOMPARE( dynamic_cast<MetaObjectTestObject*>(clone)->property1(),
0198               dynamic_cast<MetaObjectTestObject*>(object)->property1());
0199     QCOMPARE( dynamic_cast<MetaObjectTestObject*>(clone)->property2(),
0200               dynamic_cast<MetaObjectTestObject*>(object)->property2());
0201     QCOMPARE( dynamic_cast<MetaObjectTestObject*>(clone)->property3().value,
0202               dynamic_cast<MetaObjectTestObject*>(object)->property3().value);
0203     QCOMPARE( dynamic_cast<MetaObjectTestObject*>(clone)->property4().value,
0204               dynamic_cast<MetaObjectTestObject*>(object)->property4().value);
0205 
0206     delete object;
0207     delete clone;
0208 }
0209 
0210 QTEST_MAIN(TestMetaobject)
0211 
0212 #include "moc_test_metaobject.cpp"