tests/auto/qmetaobject/tst_qmetaobject.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qobject.h>
       
    46 #include <qmetaobject.h>
       
    47 #include <qlabel.h>
       
    48 
       
    49 //TESTED_CLASS=
       
    50 //TESTED_FILES=
       
    51 
       
    52 struct MyStruct
       
    53 {
       
    54     int i;
       
    55 };
       
    56 
       
    57 namespace MyNamespace {
       
    58     class MyClass : public QObject
       
    59     {
       
    60         Q_OBJECT
       
    61         Q_PROPERTY(MyEnum myEnum READ myEnum WRITE setMyEnum)
       
    62         Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags)
       
    63 
       
    64         Q_ENUMS(MyEnum)
       
    65         Q_FLAGS(MyFlags)
       
    66     public:
       
    67         enum MyEnum {
       
    68             MyEnum1,
       
    69             MyEnum2,
       
    70             MyEnum3
       
    71         };
       
    72 
       
    73         enum MyFlag {
       
    74             MyFlag1 = 0x01,
       
    75             MyFlag2 = 0x02,
       
    76             MyFlag3 = 0x04
       
    77         };
       
    78         Q_DECLARE_FLAGS(MyFlags, MyFlag)
       
    79 
       
    80         MyEnum myEnum() const { return m_enum; }
       
    81         void setMyEnum(MyEnum val) { m_enum = val; }
       
    82 
       
    83         MyFlags myFlags() const { return m_flags; }
       
    84         void setMyFlags(MyFlags val) { m_flags = val; }
       
    85 
       
    86         MyClass(QObject *parent = 0)
       
    87             : QObject(parent),
       
    88               m_enum(MyEnum1),
       
    89               m_flags(MyFlag1|MyFlag2)
       
    90                 { }
       
    91     private:
       
    92         MyEnum m_enum;
       
    93         MyFlags m_flags;
       
    94     };
       
    95     Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::MyFlags)
       
    96 }
       
    97 
       
    98 
       
    99 class tst_QMetaObject : public QObject
       
   100 {
       
   101     Q_OBJECT
       
   102     Q_ENUMS(EnumType)
       
   103     Q_PROPERTY(EnumType value WRITE setValue READ getValue)
       
   104     Q_PROPERTY(EnumType value2 WRITE set_value READ get_value)
       
   105     Q_PROPERTY(MyStruct value3 WRITE setVal3 READ val3)
       
   106     Q_PROPERTY(QList<QVariant> value4 WRITE setVal4 READ val4)
       
   107     Q_PROPERTY(QVariantList value5 WRITE setVal5 READ val5)
       
   108     Q_PROPERTY(int value6 READ value6 NOTIFY value6Changed)
       
   109     Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed)
       
   110     Q_PROPERTY(int value8 READ value8 NOTIFY value8Changed)
       
   111     Q_PROPERTY(int value9 READ value9 CONSTANT)
       
   112     Q_PROPERTY(int value10 READ value10 FINAL)
       
   113 
       
   114 public:
       
   115     enum EnumType { EnumType1 };
       
   116 
       
   117     tst_QMetaObject();
       
   118     ~tst_QMetaObject();
       
   119 
       
   120     void setValue(EnumType) {}
       
   121     EnumType getValue() const { return EnumType1; }
       
   122 
       
   123     void set_value(EnumType) {}
       
   124     EnumType get_value() const { return EnumType1; }
       
   125 
       
   126     void setVal3(MyStruct) {}
       
   127     MyStruct val3() const { MyStruct s = {42}; return s; }
       
   128 
       
   129     void setVal4(const QList<QVariant> &list) { value4 = list; }
       
   130     QList<QVariant> val4() const { return value4; }
       
   131 
       
   132     void setVal5(const QVariantList &list) { value5 = list; }
       
   133     QVariantList val5() const { return value5; }
       
   134 
       
   135     int value6() const { return 1; }
       
   136 
       
   137     void setVal7(MyStruct) {}
       
   138     MyStruct value7() const { MyStruct s = {42}; return s; }
       
   139 
       
   140     int value8() const { return 1; }
       
   141 
       
   142     int value9() const { return 1; }
       
   143 
       
   144     int value10() const { return 1; }
       
   145 
       
   146     QList<QVariant> value4;
       
   147     QVariantList value5;
       
   148 
       
   149 public slots:
       
   150     void initTestCase();
       
   151     void cleanupTestCase();
       
   152     void init();
       
   153     void cleanup();
       
   154 private slots:
       
   155     void connectSlotsByName();
       
   156     void invokeMetaMember();
       
   157     void invokeQueuedMetaMember();
       
   158     void invokeCustomTypes();
       
   159     void invokeMetaConstructor();
       
   160     void qtMetaObjectInheritance();
       
   161     void normalizedSignature_data();
       
   162     void normalizedSignature();
       
   163     void normalizedType_data();
       
   164     void normalizedType();
       
   165     void customPropertyType();
       
   166     void checkScope();
       
   167     void propertyNotify();
       
   168     void propertyConstant();
       
   169     void propertyFinal();
       
   170 
       
   171     void stdSet();
       
   172     void classInfo();
       
   173 
       
   174 signals:
       
   175     void value6Changed();
       
   176     void value7Changed(const QString &);
       
   177 };
       
   178 
       
   179 tst_QMetaObject::tst_QMetaObject()
       
   180 {
       
   181 
       
   182 }
       
   183 
       
   184 tst_QMetaObject::~tst_QMetaObject()
       
   185 {
       
   186 
       
   187 }
       
   188 
       
   189 void tst_QMetaObject::initTestCase()
       
   190 {
       
   191 }
       
   192 
       
   193 void tst_QMetaObject::cleanupTestCase()
       
   194 {
       
   195 }
       
   196 
       
   197 void tst_QMetaObject::init()
       
   198 {
       
   199 }
       
   200 
       
   201 void tst_QMetaObject::cleanup()
       
   202 {
       
   203 }
       
   204 
       
   205 void tst_QMetaObject::stdSet()
       
   206 {
       
   207     const QMetaObject *mo = metaObject();
       
   208 
       
   209     QMetaProperty prop = mo->property(mo->indexOfProperty("value"));
       
   210     QVERIFY(prop.isValid());
       
   211     QVERIFY(prop.hasStdCppSet());
       
   212 
       
   213     prop = mo->property(mo->indexOfProperty("value2"));
       
   214     QVERIFY(prop.isValid());
       
   215     QVERIFY(!prop.hasStdCppSet());
       
   216 }
       
   217 
       
   218 class CTestObject: public QObject
       
   219 {
       
   220     Q_OBJECT
       
   221 
       
   222 public:
       
   223     CTestObject(): QObject(), invokeCount1(0), invokeCount2(0)
       
   224     {
       
   225     }
       
   226 
       
   227     void fire(const QString &name)
       
   228     {
       
   229         child = new QObject(this);
       
   230         child->setObjectName(name);
       
   231         QMetaObject::connectSlotsByName(this);
       
   232         delete child; child = 0;
       
   233     }
       
   234 
       
   235     int invokeCount1;
       
   236     int invokeCount2;
       
   237     QObject *child;
       
   238 
       
   239 public slots:
       
   240     void on_child1_destroyed(QObject *obj = 0) { ++invokeCount1; Q_ASSERT(obj && obj == child); }
       
   241     void on_child2_destroyed() { ++invokeCount2; }
       
   242 };
       
   243 
       
   244 class CTestObjectOverloads: public QObject
       
   245 {
       
   246     Q_OBJECT
       
   247 
       
   248 public:
       
   249     CTestObjectOverloads(): invokeCount1(0), invokeCount2(0) {}
       
   250 
       
   251     int invokeCount1;
       
   252     int invokeCount2;
       
   253     QObject *child;
       
   254 
       
   255     void fire(const QString &name)
       
   256     {
       
   257         child = new QObject(this);
       
   258         child->setObjectName(name);
       
   259         QMetaObject::connectSlotsByName(this);
       
   260         delete child; child = 0;
       
   261     }
       
   262 
       
   263 private slots:
       
   264     void on_child1_destroyed(QObject *obj) { ++invokeCount1; Q_ASSERT(obj && obj == child); }
       
   265     void on_child1_destroyed() { ++invokeCount2; }
       
   266 };
       
   267 
       
   268 #define FUNCTION(x) "QMetaObject::" x ": "
       
   269 
       
   270 void tst_QMetaObject::connectSlotsByName()
       
   271 {
       
   272     CTestObject obj;
       
   273     QCOMPARE(obj.invokeCount1, 0);
       
   274     QCOMPARE(obj.invokeCount2, 0);
       
   275 
       
   276     QTest::ignoreMessage(QtWarningMsg, FUNCTION("connectSlotsByName") "No matching signal for on_child1_destroyed(QObject*)");
       
   277     QTest::ignoreMessage(QtWarningMsg, FUNCTION("connectSlotsByName") "No matching signal for on_child2_destroyed()");
       
   278     obj.fire("bubu");
       
   279     QCOMPARE(obj.invokeCount1, 0);
       
   280     QCOMPARE(obj.invokeCount2, 0);
       
   281 
       
   282     QTest::ignoreMessage(QtWarningMsg, FUNCTION("connectSlotsByName") "No matching signal for on_child2_destroyed()");
       
   283     obj.fire("child1");
       
   284     QCOMPARE(obj.invokeCount1, 1);
       
   285     QCOMPARE(obj.invokeCount2, 0);
       
   286 
       
   287     QTest::ignoreMessage(QtWarningMsg, FUNCTION("connectSlotsByName") "No matching signal for on_child1_destroyed(QObject*)");
       
   288     obj.fire("child2");
       
   289     QCOMPARE(obj.invokeCount1, 1);
       
   290     QCOMPARE(obj.invokeCount2, 1);
       
   291 
       
   292     QTest::ignoreMessage(QtWarningMsg, FUNCTION("connectSlotsByName") "No matching signal for on_child2_destroyed()");
       
   293     obj.fire("child1");
       
   294     QCOMPARE(obj.invokeCount1, 2);
       
   295     QCOMPARE(obj.invokeCount2, 1);
       
   296 
       
   297     // now test with real overloads
       
   298     CTestObjectOverloads obj2;
       
   299     obj2.fire("child1");
       
   300     QCOMPARE(obj2.invokeCount1, 1);
       
   301     QCOMPARE(obj2.invokeCount2, 1);
       
   302 }
       
   303 
       
   304 class QtTestObject: public QObject
       
   305 {
       
   306     Q_OBJECT
       
   307 
       
   308 public:
       
   309     QtTestObject();
       
   310     Q_INVOKABLE QtTestObject(QObject *parent);
       
   311 
       
   312 public slots:
       
   313     void sl0();
       
   314     QString sl1(QString s1);
       
   315     void sl2(QString s1, QString s2);
       
   316     void sl3(QString s1, QString s2, QString s3);
       
   317     void sl4(QString s1, QString s2, QString s3, const QString s4);
       
   318     void sl5(QString s1, QString s2, QString s3, QString s4, const QString &s5);
       
   319     void sl6(QString s1, QString s2, QString s3, QString s4, const QString s5, QString s6);
       
   320     void sl7(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7);
       
   321     void sl8(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7,
       
   322             QString s8);
       
   323     void sl9(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7,
       
   324             QString s8, QString s9);
       
   325     void sl10(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7,
       
   326             QString s8, QString s9, QString s10);
       
   327     QObject *sl11();
       
   328     const char *sl12();
       
   329     QList<QString> sl13(QList<QString> l1);
       
   330     void testSender();
       
   331 
       
   332     void testReference(QString &str);
       
   333 
       
   334     void testLongLong(qint64 ll1, quint64 ll2);
       
   335 
       
   336 signals:
       
   337     void sig0();
       
   338     QString sig1(QString s1);
       
   339 
       
   340 protected:
       
   341     QtTestObject(QVariant) {}
       
   342 private:
       
   343     QtTestObject(QVariant, QVariant) {}
       
   344 
       
   345 public:
       
   346     QString slotResult;
       
   347 };
       
   348 
       
   349 QtTestObject::QtTestObject()
       
   350 {
       
   351     connect(this, SIGNAL(sig0()), this, SLOT(sl0()));
       
   352     connect(this, SIGNAL(sig1(QString)), this, SLOT(sl1(QString)));
       
   353 }
       
   354 
       
   355 QtTestObject::QtTestObject(QObject *parent)
       
   356     : QObject(parent)
       
   357 {
       
   358 }
       
   359 
       
   360 void QtTestObject::sl0() { slotResult = "sl0"; };
       
   361 QString QtTestObject::sl1(QString s1) { slotResult = "sl1:" + s1; return "yessir"; }
       
   362 void QtTestObject::sl2(QString s1, QString s2) { slotResult = "sl2:" + s1 + s2; }
       
   363 void QtTestObject::sl3(QString s1, QString s2, QString s3)
       
   364 { slotResult = "sl3:" + s1 + s2 + s3; }
       
   365 void QtTestObject::sl4(QString s1, QString s2, QString s3, const QString s4)
       
   366 { slotResult = "sl4:" + s1 + s2 + s3 + s4; }
       
   367 void QtTestObject::sl5(QString s1, QString s2, QString s3, QString s4, const QString &s5)
       
   368 { slotResult = "sl5:" + s1 + s2 + s3 + s4 + s5; }
       
   369 void QtTestObject::sl6(QString s1, QString s2, QString s3, QString s4,
       
   370                       const QString s5, QString s6)
       
   371 { slotResult = "sl6:" + s1 + s2 + s3 + s4 + s5 + s6; }
       
   372 void QtTestObject::sl7(QString s1, QString s2, QString s3, QString s4, QString s5,
       
   373                       QString s6, QString s7)
       
   374 { slotResult = "sl7:" + s1 + s2 + s3 + s4 + s5 + s6 + s7; }
       
   375 void QtTestObject::sl8(QString s1, QString s2, QString s3, QString s4, QString s5,
       
   376                       QString s6, QString s7, QString s8)
       
   377 { slotResult = "sl8:" + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8; }
       
   378 void QtTestObject::sl9(QString s1, QString s2, QString s3, QString s4, QString s5,
       
   379                       QString s6, QString s7, QString s8, QString s9)
       
   380 { slotResult = "sl9:" + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; }
       
   381 void QtTestObject::sl10(QString s1, QString s2, QString s3, QString s4, QString s5,
       
   382                       QString s6, QString s7, QString s8, QString s9, QString s10)
       
   383 { slotResult = "sl10:" + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; }
       
   384 QObject *QtTestObject::sl11()
       
   385 { slotResult = "sl11"; return this; }
       
   386 const char *QtTestObject::sl12()
       
   387 { slotResult = "sl12"; return "foo"; }
       
   388 QList<QString> QtTestObject::sl13(QList<QString> l1)
       
   389 { slotResult = "sl13"; return l1; }
       
   390 void QtTestObject::testReference(QString &str)
       
   391 { slotResult = "testReference:" + str; str = "gotcha"; }
       
   392 
       
   393 void QtTestObject::testLongLong(qint64 ll1, quint64 ll2)
       
   394 { slotResult = "testLongLong:" + QString::number(ll1) + "," + QString::number(ll2); }
       
   395 
       
   396 void QtTestObject::testSender()
       
   397 {
       
   398   slotResult.sprintf("%p", sender());
       
   399 }
       
   400 
       
   401 
       
   402 void tst_QMetaObject::invokeMetaMember()
       
   403 {
       
   404     QtTestObject obj;
       
   405 
       
   406     QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5");
       
   407     QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X");
       
   408 
       
   409     QVERIFY(!QMetaObject::invokeMethod(0, 0));
       
   410     QVERIFY(!QMetaObject::invokeMethod(0, "sl0"));
       
   411     QVERIFY(!QMetaObject::invokeMethod(&obj, 0));
       
   412 
       
   413     QVERIFY(QMetaObject::invokeMethod(&obj, "sl0"));
       
   414     QCOMPARE(obj.slotResult, QString("sl0"));
       
   415 
       
   416     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(QString, t1)));
       
   417     QCOMPARE(obj.slotResult, QString("sl1:1"));
       
   418 
       
   419     QVERIFY(QMetaObject::invokeMethod(&obj, "sl2", Q_ARG(const QString, t1), Q_ARG(QString, t2)));
       
   420     QCOMPARE(obj.slotResult, QString("sl2:12"));
       
   421 
       
   422     QVERIFY(QMetaObject::invokeMethod(&obj, "sl3", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3)));
       
   423     QCOMPARE(obj.slotResult, QString("sl3:123"));
       
   424 
       
   425     QVERIFY(QMetaObject::invokeMethod(&obj, "sl4", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   426                        Q_ARG(QString, t4)));
       
   427     QCOMPARE(obj.slotResult, QString("sl4:1234"));
       
   428 
       
   429     QVERIFY(QMetaObject::invokeMethod(&obj, "sl5", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   430                        Q_ARG(QString, t4), Q_ARG(QString, "5")));
       
   431     QCOMPARE(obj.slotResult, QString("sl5:12345"));
       
   432 
       
   433     QVERIFY(QMetaObject::invokeMethod(&obj, "sl6", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   434                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6)));
       
   435     QCOMPARE(obj.slotResult, QString("sl6:123456"));
       
   436 
       
   437     QVERIFY(QMetaObject::invokeMethod(&obj, "sl7", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   438                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6),
       
   439                        Q_ARG(QString, t7)));
       
   440     QCOMPARE(obj.slotResult, QString("sl7:1234567"));
       
   441 
       
   442     QVERIFY(QMetaObject::invokeMethod(&obj, "sl8", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   443                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6),
       
   444                        Q_ARG(QString, t7), Q_ARG(QString, t8)));
       
   445     QCOMPARE(obj.slotResult, QString("sl8:12345678"));
       
   446 
       
   447     QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3),
       
   448                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6),
       
   449                        Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9)));
       
   450     QCOMPARE(obj.slotResult, QString("sl9:123456789"));
       
   451 
       
   452     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11"));
       
   453     QCOMPARE(obj.slotResult, QString("sl11"));
       
   454 
       
   455     QVERIFY(QMetaObject::invokeMethod(&obj, "testSender"));
       
   456     QCOMPARE(obj.slotResult, QString("0x0"));
       
   457 
       
   458     QString refStr("whatever");
       
   459     QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", QGenericArgument("QString&", &refStr)));
       
   460     QCOMPARE(obj.slotResult, QString("testReference:whatever"));
       
   461     QCOMPARE(refStr, QString("gotcha"));
       
   462 
       
   463 	qint64 ll1 = -1;
       
   464     quint64 ll2 = 0;
       
   465     QVERIFY(QMetaObject::invokeMethod(&obj,
       
   466                                       "testLongLong",
       
   467                                       Q_ARG(qint64, ll1),
       
   468                                       Q_ARG(quint64, ll2)));
       
   469     QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
       
   470 
       
   471     QString exp;
       
   472     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Q_RETURN_ARG(QString, exp), Q_ARG(QString, "bubu")));
       
   473     QCOMPARE(exp, QString("yessir"));
       
   474     QCOMPARE(obj.slotResult, QString("sl1:bubu"));
       
   475 
       
   476     QObject *ptr = 0;
       
   477     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Q_RETURN_ARG(QObject*,ptr)));
       
   478     QCOMPARE(ptr, (QObject *)&obj);
       
   479     QCOMPARE(obj.slotResult, QString("sl11"));
       
   480     // try again with a space:
       
   481     ptr = 0;
       
   482     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Q_RETURN_ARG(QObject * , ptr)));
       
   483     QCOMPARE(ptr, (QObject *)&obj);
       
   484     QCOMPARE(obj.slotResult, QString("sl11"));
       
   485 
       
   486     const char *ptr2 = 0;
       
   487     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Q_RETURN_ARG(const char*, ptr2)));
       
   488     QVERIFY(ptr2 != 0);
       
   489     QCOMPARE(obj.slotResult, QString("sl12"));
       
   490     // try again with a space:
       
   491     ptr2 = 0;
       
   492     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Q_RETURN_ARG(char const * , ptr2)));
       
   493     QVERIFY(ptr2 != 0);
       
   494     QCOMPARE(obj.slotResult, QString("sl12"));
       
   495 
       
   496     // test w/ template args
       
   497     QList<QString> returnValue, argument;
       
   498     argument << QString("one") << QString("two") << QString("three");
       
   499     QVERIFY(QMetaObject::invokeMethod(&obj, "sl13",
       
   500                                       Q_RETURN_ARG(QList<QString>, returnValue),
       
   501                                       Q_ARG(QList<QString>, argument)));
       
   502     QCOMPARE(returnValue, argument);
       
   503     QCOMPARE(obj.slotResult, QString("sl13"));
       
   504 
       
   505     //test signals
       
   506     QVERIFY(QMetaObject::invokeMethod(&obj, "sig0"));
       
   507     QCOMPARE(obj.slotResult, QString("sl0"));
       
   508 
       
   509     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Q_ARG(QString, "baba")));
       
   510     QCOMPARE(obj.slotResult, QString("sl1:baba"));
       
   511 
       
   512     exp.clear();
       
   513     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe")));
       
   514     QCOMPARE(exp, QString("yessir"));
       
   515     QCOMPARE(obj.slotResult, QString("sl1:hehe"));
       
   516 }
       
   517 
       
   518 void tst_QMetaObject::invokeQueuedMetaMember()
       
   519 {
       
   520     QtTestObject obj;
       
   521 
       
   522     QVERIFY(QMetaObject::invokeMethod(&obj, "sl0", Qt::QueuedConnection));
       
   523     QVERIFY(obj.slotResult.isEmpty());
       
   524     qApp->processEvents(QEventLoop::AllEvents);
       
   525     QCOMPARE(obj.slotResult, QString("sl0"));
       
   526     obj.slotResult = QString();
       
   527 
       
   528     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::QueuedConnection, Q_ARG(QString, QString("hallo"))));
       
   529     QVERIFY(obj.slotResult.isEmpty());
       
   530     qApp->processEvents(QEventLoop::AllEvents);
       
   531     QCOMPARE(obj.slotResult, QString("sl1:hallo"));
       
   532     obj.slotResult = QString();
       
   533 
       
   534     QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Qt::QueuedConnection, Q_ARG(QString, "1"), Q_ARG(QString, "2"),
       
   535                        Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(QString, "5"),
       
   536                        Q_ARG(QString, "6"), Q_ARG(QString, "7"), Q_ARG(QString, "8"),
       
   537                        Q_ARG(QString, "9")));
       
   538     QVERIFY(obj.slotResult.isEmpty());
       
   539     qApp->processEvents(QEventLoop::AllEvents);
       
   540     QCOMPARE(obj.slotResult, QString("sl9:123456789"));
       
   541 
       
   542     // signals
       
   543 
       
   544     obj.slotResult.clear();
       
   545     QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::QueuedConnection));
       
   546     QVERIFY(obj.slotResult.isEmpty());
       
   547     qApp->processEvents(QEventLoop::AllEvents);
       
   548     QCOMPARE(obj.slotResult, QString("sl0"));
       
   549 
       
   550     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::QueuedConnection, Q_ARG(QString, "gogo")));
       
   551     qApp->processEvents(QEventLoop::AllEvents);
       
   552     QCOMPARE(obj.slotResult, QString("sl1:gogo"));
       
   553 
       
   554     QString exp;
       
   555     QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to invoke methods with return values in queued connections");
       
   556     QVERIFY(!QMetaObject::invokeMethod(&obj, "sig1", Qt::QueuedConnection, Q_RETURN_ARG(QString, exp),
       
   557                               Q_ARG(QString, "nono")));
       
   558 
       
   559 	qint64 ll1 = -1;
       
   560     quint64 ll2 = 0;
       
   561     QVERIFY(QMetaObject::invokeMethod(&obj,
       
   562                                       "testLongLong",
       
   563                                       Qt::QueuedConnection,
       
   564                                       Q_ARG(qint64, ll1),
       
   565                                       Q_ARG(quint64, ll2)));
       
   566     qApp->processEvents(QEventLoop::AllEvents);
       
   567     QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
       
   568 }
       
   569 
       
   570 
       
   571 void tst_QMetaObject::qtMetaObjectInheritance()
       
   572 {
       
   573     QVERIFY(QObject::staticMetaObject.superClass() == 0);
       
   574     QCOMPARE(QLabel::staticMetaObject.indexOfEnumerator("Qt::Alignment"), -1);
       
   575     QCOMPARE(QLabel::staticMetaObject.indexOfEnumerator("Alignment"), -1);
       
   576     int indexOfAlignment = QLabel::staticMetaObject.indexOfProperty("alignment");
       
   577     QVERIFY(indexOfAlignment != -1);
       
   578     QMetaProperty alignment = QLabel::staticMetaObject.property(indexOfAlignment);
       
   579     QVERIFY(alignment.isValid());
       
   580     QCOMPARE(alignment.enumerator().name(), "Alignment");
       
   581 }
       
   582 
       
   583 struct MyType
       
   584 {
       
   585     int i1, i2, i3;
       
   586 };
       
   587 
       
   588 class QtTestCustomObject: public QObject
       
   589 {
       
   590     Q_OBJECT
       
   591 public:
       
   592     QtTestCustomObject(): QObject(), sum(0) {}
       
   593 
       
   594 public slots:
       
   595     void sl1(MyType myType);
       
   596 
       
   597 public:
       
   598     int sum;
       
   599 };
       
   600 
       
   601 void QtTestCustomObject::sl1(MyType myType)
       
   602 {
       
   603     sum = myType.i1 + myType.i2 + myType.i3;
       
   604 }
       
   605 
       
   606 void tst_QMetaObject::invokeCustomTypes()
       
   607 {
       
   608     QtTestCustomObject obj;
       
   609     MyType tp = {1, 1, 1};
       
   610 
       
   611     QCOMPARE(obj.sum, 0);
       
   612     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(MyType, tp)));
       
   613     QCOMPARE(obj.sum, 3);
       
   614 }
       
   615 
       
   616 namespace NamespaceWithConstructibleClass
       
   617 {
       
   618 
       
   619 class ConstructibleClass : public QObject
       
   620 {
       
   621     Q_OBJECT
       
   622 public:
       
   623     Q_INVOKABLE ConstructibleClass(QObject *parent = 0)
       
   624         : QObject(parent) {}
       
   625 };
       
   626 
       
   627 }
       
   628 
       
   629 void tst_QMetaObject::invokeMetaConstructor()
       
   630 {
       
   631     const QMetaObject *mo = &QtTestObject::staticMetaObject;
       
   632     {
       
   633         QObject *obj = mo->newInstance();
       
   634         QVERIFY(obj == 0);
       
   635     }
       
   636     {
       
   637         QtTestObject obj;
       
   638         QObject *obj2 = mo->newInstance(Q_ARG(QObject*, &obj));
       
   639         QVERIFY(obj2 != 0);
       
   640         QCOMPARE(obj2->parent(), (QObject*)&obj);
       
   641         QVERIFY(qobject_cast<QtTestObject*>(obj2) != 0);
       
   642     }
       
   643     // class in namespace
       
   644     const QMetaObject *nsmo = &NamespaceWithConstructibleClass::ConstructibleClass::staticMetaObject;
       
   645     {
       
   646         QtTestObject obj;
       
   647         QObject *obj2 = nsmo->newInstance(Q_ARG(QObject*, &obj));
       
   648         QVERIFY(obj2 != 0);
       
   649         QCOMPARE(obj2->parent(), (QObject*)&obj);
       
   650         QVERIFY(qobject_cast<NamespaceWithConstructibleClass::ConstructibleClass*>(obj2) != 0);
       
   651     }
       
   652 }
       
   653 
       
   654 void tst_QMetaObject::normalizedSignature_data()
       
   655 {
       
   656     QTest::addColumn<QString>("signature");
       
   657     QTest::addColumn<QString>("result");
       
   658 
       
   659     QTest::newRow("function") << "void foo()" << "void foo()";
       
   660     QTest::newRow("spaces") << " void  foo( ) " << "void foo()";
       
   661     QTest::newRow("template args") << " void  foo( QMap<a, a>, QList<b>) "
       
   662                                    << "void foo(QMap<a,a>,QList<b>)";
       
   663     QTest::newRow("rettype") << "QList<int, int> foo()" << "QList<int,int>foo()";
       
   664     QTest::newRow("const rettype") << "const QString *foo()" << "const QString*foo()";
       
   665     QTest::newRow("const ref") << "const QString &foo()" << "const QString&foo()";
       
   666     QTest::newRow("reference") << "QString &foo()" << "QString&foo()";
       
   667     QTest::newRow("const2") << "void foo(QString const *)" << "void foo(const QString*)";
       
   668     QTest::newRow("const2") << "void foo(QString * const)" << "void foo(QString*const)";
       
   669     QTest::newRow("const3") << "void foo(QString const &)" << "void foo(QString)";
       
   670     QTest::newRow("const4") << "void foo(const int)" << "void foo(int)";
       
   671     QTest::newRow("const5") << "void foo(const int, int const, const int &, int const &)"
       
   672                             << "void foo(int,int,int,int)";
       
   673     QTest::newRow("const6") << "void foo(QList<const int>)" << "void foo(QList<const int>)";
       
   674     QTest::newRow("const7") << "void foo(QList<const int*>)" << "void foo(QList<const int*>)";
       
   675     QTest::newRow("const7") << "void foo(QList<int const*>)" << "void foo(QList<const int*>)";
       
   676 }
       
   677 
       
   678 void tst_QMetaObject::normalizedSignature()
       
   679 {
       
   680     QFETCH(QString, signature);
       
   681     QFETCH(QString, result);
       
   682 
       
   683     QCOMPARE(QString::fromLatin1(QMetaObject::normalizedSignature(signature.toLatin1())), result);
       
   684 }
       
   685 
       
   686 void tst_QMetaObject::normalizedType_data()
       
   687 {
       
   688     QTest::addColumn<QString>("type");
       
   689     QTest::addColumn<QString>("result");
       
   690 
       
   691     QTest::newRow("simple") << "int" << "int";
       
   692     QTest::newRow("white") << "  int  " << "int";
       
   693     QTest::newRow("const1") << "int const *" << "const int*";
       
   694     QTest::newRow("const2") << "const int *" << "const int*";
       
   695     QTest::newRow("template1") << "QList<int const *>" << "QList<const int*>";
       
   696     QTest::newRow("template2") << "QList<const int *>" << "QList<const int*>";
       
   697     QTest::newRow("template3") << "QMap<QString, int>" << "QMap<QString,int>";
       
   698     QTest::newRow("template4") << "const QMap<QString, int> &" << "QMap<QString,int>";
       
   699     QTest::newRow("template5") << "QList< ::Foo::Bar>" << "QList< ::Foo::Bar>";
       
   700     QTest::newRow("template6") << "QList<::Foo::Bar>" << "QList<::Foo::Bar>";
       
   701     QTest::newRow("template7") << "QList<QList<int> >" << "QList<QList<int> >";
       
   702     QTest::newRow("value1") << "const QString &" << "QString";
       
   703     QTest::newRow("value2") << "QString const &" << "QString";
       
   704 }
       
   705 
       
   706 void tst_QMetaObject::normalizedType()
       
   707 {
       
   708     QFETCH(QString, type);
       
   709     QFETCH(QString, result);
       
   710 
       
   711     QCOMPARE(QString::fromLatin1(QMetaObject::normalizedType(type.toLatin1())), result);
       
   712 }
       
   713 
       
   714 void tst_QMetaObject::customPropertyType()
       
   715 {
       
   716     QMetaProperty prop = metaObject()->property(metaObject()->indexOfProperty("value3"));
       
   717 
       
   718     QCOMPARE(prop.type(), QVariant::UserType);
       
   719     QCOMPARE(prop.userType(), 0);
       
   720 
       
   721     qRegisterMetaType<MyStruct>("MyStruct");
       
   722     QCOMPARE(prop.userType(), QMetaType::type("MyStruct"));
       
   723 
       
   724     prop = metaObject()->property(metaObject()->indexOfProperty("value4"));
       
   725     QCOMPARE(prop.type(), QVariant::List);
       
   726 
       
   727     prop = metaObject()->property(metaObject()->indexOfProperty("value5"));
       
   728     QCOMPARE(prop.type(), QVariant::List);
       
   729 }
       
   730 
       
   731 void tst_QMetaObject::checkScope()
       
   732 {
       
   733     MyNamespace::MyClass obj;
       
   734 
       
   735     const QMetaObject *mo = obj.metaObject();
       
   736     QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("MyEnum"));
       
   737     QVERIFY(me.isValid());
       
   738     QVERIFY(!me.isFlag());
       
   739     QCOMPARE(QLatin1String(me.scope()), QLatin1String("MyNamespace::MyClass"));
       
   740     QCOMPARE(me.keyToValue("MyNamespace::MyClass::MyEnum2"), 1);
       
   741     QCOMPARE(me.keyToValue("MyClass::MyEnum2"), -1);
       
   742     QCOMPARE(me.keyToValue("MyNamespace::MyEnum2"), -1);
       
   743     QCOMPARE(me.keyToValue("MyEnum2"), 1);
       
   744     QCOMPARE(me.keyToValue("MyEnum"), -1);
       
   745     QCOMPARE(QLatin1String(me.valueToKey(1)), QLatin1String("MyEnum2"));
       
   746 
       
   747     QMetaEnum mf = mo->enumerator(mo->indexOfEnumerator("MyFlags"));
       
   748     QVERIFY(mf.isValid());
       
   749     QVERIFY(mf.isFlag());
       
   750     QCOMPARE(QLatin1String(mf.scope()), QLatin1String("MyNamespace::MyClass"));
       
   751     QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2"), 2);
       
   752     QCOMPARE(mf.keysToValue("MyClass::MyFlag2"), -1);
       
   753     QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2"), -1);
       
   754     QCOMPARE(mf.keysToValue("MyFlag2"), 2);
       
   755     QCOMPARE(mf.keysToValue("MyFlag"), -1);
       
   756     QCOMPARE(QLatin1String(mf.valueToKey(2)), QLatin1String("MyFlag2"));
       
   757     QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag1|MyNamespace::MyClass::MyFlag2"), 3);
       
   758     QCOMPARE(mf.keysToValue("MyClass::MyFlag1|MyClass::MyFlag2"), -1);
       
   759     QCOMPARE(mf.keysToValue("MyNamespace::MyFlag1|MyNamespace::MyFlag2"), -1);
       
   760     QCOMPARE(mf.keysToValue("MyFlag1|MyFlag2"), 3);
       
   761     QCOMPARE(mf.keysToValue("MyFlag2|MyFlag2"), 2);
       
   762     QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::MyClass::MyFlag2"), 3);
       
   763     QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2|MyNamespace::MyClass::MyFlag2"), 2);
       
   764     QCOMPARE(QLatin1String(mf.valueToKeys(3)), QLatin1String("MyFlag1|MyFlag2"));
       
   765 }
       
   766 
       
   767 void tst_QMetaObject::propertyNotify()
       
   768 {
       
   769     const QMetaObject *mo = metaObject();
       
   770 
       
   771     QMetaProperty prop = mo->property(mo->indexOfProperty("value6"));
       
   772     QVERIFY(prop.isValid());
       
   773     QVERIFY(prop.hasNotifySignal());
       
   774     QMetaMethod signal = prop.notifySignal();
       
   775     QCOMPARE(signal.signature(), "value6Changed()");
       
   776 
       
   777     prop = mo->property(mo->indexOfProperty("value7"));
       
   778     QVERIFY(prop.isValid());
       
   779     QVERIFY(prop.hasNotifySignal());
       
   780     signal = prop.notifySignal();
       
   781     QCOMPARE(signal.signature(), "value7Changed(QString)");
       
   782 
       
   783     prop = mo->property(mo->indexOfProperty("value8"));
       
   784     QVERIFY(prop.isValid());
       
   785     QVERIFY(!prop.hasNotifySignal());
       
   786     signal = prop.notifySignal();
       
   787     QCOMPARE(signal.signature(), (const char *)0);
       
   788 
       
   789     prop = mo->property(mo->indexOfProperty("value"));
       
   790     QVERIFY(prop.isValid());
       
   791     QVERIFY(!prop.hasNotifySignal());
       
   792     signal = prop.notifySignal();
       
   793     QCOMPARE(signal.signature(), (const char *)0);
       
   794 }
       
   795 
       
   796 void tst_QMetaObject::propertyConstant()
       
   797 {
       
   798     const QMetaObject *mo = metaObject();
       
   799 
       
   800     QMetaProperty prop = mo->property(mo->indexOfProperty("value8"));
       
   801     QVERIFY(prop.isValid());
       
   802     QVERIFY(!prop.isConstant());
       
   803 
       
   804     prop = mo->property(mo->indexOfProperty("value9"));
       
   805     QVERIFY(prop.isValid());
       
   806     QVERIFY(prop.isConstant());
       
   807 }
       
   808 
       
   809 void tst_QMetaObject::propertyFinal()
       
   810 {
       
   811     const QMetaObject *mo = metaObject();
       
   812 
       
   813     QMetaProperty prop = mo->property(mo->indexOfProperty("value10"));
       
   814     QVERIFY(prop.isValid());
       
   815     QVERIFY(prop.isFinal());
       
   816 
       
   817     prop = mo->property(mo->indexOfProperty("value9"));
       
   818     QVERIFY(prop.isValid());
       
   819     QVERIFY(!prop.isFinal());
       
   820 }
       
   821 
       
   822 class ClassInfoTestObjectA : public QObject
       
   823 {
       
   824     Q_OBJECT
       
   825     Q_CLASSINFO("Author", "Christopher Pike")
       
   826 };
       
   827 
       
   828 class ClassInfoTestObjectB : public ClassInfoTestObjectA
       
   829 {
       
   830     Q_OBJECT
       
   831 };
       
   832 
       
   833 void tst_QMetaObject::classInfo()
       
   834 {
       
   835     ClassInfoTestObjectB b;
       
   836     int index = b.metaObject()->indexOfClassInfo("Author");
       
   837     QCOMPARE(index, 0);
       
   838     QVERIFY(index <= b.metaObject()->classInfoOffset());
       
   839     QCOMPARE(QLatin1String(b.metaObject()->classInfo(index).value()), QLatin1String("Christopher Pike"));
       
   840 }
       
   841 
       
   842 QTEST_MAIN(tst_QMetaObject)
       
   843 #include "tst_qmetaobject.moc"