| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the test suite of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 21 | ** included in the packaging of this file. Please review the following | 
| 22 | ** information to ensure the GNU General Public License requirements will | 
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 24 | ** | 
| 25 | ** $QT_END_LICENSE$ | 
| 26 | ** | 
| 27 | ****************************************************************************/ | 
| 28 |  | 
| 29 | #include <QtTest/QtTest> | 
| 30 |  | 
| 31 | #include <qobject.h> | 
| 32 | #include <qmetaobject.h> | 
| 33 | #include <qabstractproxymodel.h> | 
| 34 | #include <private/qmetaobject_p.h> | 
| 35 |  | 
| 36 | Q_DECLARE_METATYPE(const QMetaObject *) | 
| 37 |  | 
| 38 | struct MyStruct | 
| 39 | { | 
| 40 |     int i; | 
| 41 | }; | 
| 42 |  | 
| 43 | class MyGadget | 
| 44 | { | 
| 45 |     Q_GADGET | 
| 46 | public: | 
| 47 |     Q_INVOKABLE MyGadget() {} | 
| 48 | }; | 
| 49 |  | 
| 50 | namespace MyNamespace { | 
| 51 |     // Used in tst_QMetaObject::checkScope | 
| 52 |     class MyClass : public QObject | 
| 53 |     { | 
| 54 |         Q_OBJECT | 
| 55 |         Q_PROPERTY(MyEnum myEnum READ myEnum WRITE setMyEnum) | 
| 56 |         Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags) | 
| 57 |  | 
| 58 |     public: | 
| 59 |         enum MyEnum { | 
| 60 |             MyEnum1, | 
| 61 |             MyEnum2, | 
| 62 |             MyEnum3 | 
| 63 |         }; | 
| 64 |         enum class MyScopedEnum { | 
| 65 |             Enum1, | 
| 66 |             Enum2, | 
| 67 |             Enum3 | 
| 68 |         }; | 
| 69 |         enum MyAnotherEnum { | 
| 70 |             MyAnotherEnum1 = 1, | 
| 71 |             MyAnotherEnum2 = 2, | 
| 72 |             MyAnotherEnum3 = -1 | 
| 73 |         }; | 
| 74 |         enum MyFlag { | 
| 75 |             MyFlag1 = 0x01, | 
| 76 |             MyFlag2 = 0x02, | 
| 77 |             MyFlag3 = 0x04 | 
| 78 |         }; | 
| 79 |         enum class MyScopedFlag { | 
| 80 |             MyFlag1 = 0x10, | 
| 81 |             MyFlag2 = 0x20, | 
| 82 |             MyFlag3 = 0x40 | 
| 83 |         }; | 
| 84 |         Q_DECLARE_FLAGS(MyFlags, MyFlag) | 
| 85 |         Q_DECLARE_FLAGS(MyScopedFlags, MyScopedFlag) | 
| 86 |  | 
| 87 |         MyEnum myEnum() const { return m_enum; } | 
| 88 |         void setMyEnum(MyEnum val) { m_enum = val; } | 
| 89 |  | 
| 90 |         MyFlags myFlags() const { return m_flags; } | 
| 91 |         void setMyFlags(MyFlags val) { m_flags = val; } | 
| 92 |  | 
| 93 |         MyClass(QObject *parent = 0) | 
| 94 |             : QObject(parent), | 
| 95 |               m_enum(MyEnum1), | 
| 96 |               m_flags(MyFlag1|MyFlag2) | 
| 97 |                 { } | 
| 98 |     private: | 
| 99 |         Q_ENUM(MyEnum) | 
| 100 |         Q_ENUM(MyScopedEnum) | 
| 101 |         Q_ENUM(MyAnotherEnum) | 
| 102 |         Q_FLAG(MyFlags) | 
| 103 |         Q_FLAG(MyScopedFlags) | 
| 104 |  | 
| 105 |         MyEnum m_enum; | 
| 106 |         MyFlags m_flags; | 
| 107 |     }; | 
| 108 |     Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::MyFlags) | 
| 109 |  | 
| 110 |  | 
| 111 |     // test the old Q_ENUMS macro | 
| 112 |     class MyClass2 : public QObject | 
| 113 |     { | 
| 114 |         Q_OBJECT | 
| 115 |         Q_PROPERTY(MyEnum myEnum READ myEnum WRITE setMyEnum) | 
| 116 |         Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags) | 
| 117 |  | 
| 118 |     public: | 
| 119 |         enum MyEnum { | 
| 120 |             MyEnum1, | 
| 121 |             MyEnum2, | 
| 122 |             MyEnum3 | 
| 123 |         }; | 
| 124 |         enum MyAnotherEnum { | 
| 125 |             MyAnotherEnum1 = 1, | 
| 126 |             MyAnotherEnum2 = 2, | 
| 127 |             MyAnotherEnum3 = -1 | 
| 128 |         }; | 
| 129 |         enum MyFlag { | 
| 130 |             MyFlag1 = 0x01, | 
| 131 |             MyFlag2 = 0x02, | 
| 132 |             MyFlag3 = 0x04 | 
| 133 |         }; | 
| 134 |         Q_DECLARE_FLAGS(MyFlags, MyFlag) | 
| 135 |  | 
| 136 |         MyEnum myEnum() const { return m_enum; } | 
| 137 |         void setMyEnum(MyEnum val) { m_enum = val; } | 
| 138 |  | 
| 139 |         MyFlags myFlags() const { return m_flags; } | 
| 140 |         void setMyFlags(MyFlags val) { m_flags = val; } | 
| 141 |  | 
| 142 |         MyClass2(QObject *parent = 0) | 
| 143 |             : QObject(parent), | 
| 144 |               m_enum(MyEnum1), | 
| 145 |               m_flags(MyFlag1|MyFlag2) | 
| 146 |         { } | 
| 147 |     private: | 
| 148 |         Q_ENUMS(MyEnum MyAnotherEnum) | 
| 149 |         Q_FLAGS(MyFlags) | 
| 150 |  | 
| 151 |         MyEnum m_enum; | 
| 152 |         MyFlags m_flags; | 
| 153 |     }; | 
| 154 |  | 
| 155 |     // Test inherits | 
| 156 |     class MyClassSubclass : public MyClass | 
| 157 |     { | 
| 158 |         Q_OBJECT | 
| 159 |     }; | 
| 160 |  | 
| 161 |     class MyClassSubclass2 : public MyClass2 | 
| 162 |     { | 
| 163 |         Q_OBJECT | 
| 164 |     }; | 
| 165 |  | 
| 166 |     class MyClass2Subclass : public MyClass | 
| 167 |     { | 
| 168 |         Q_OBJECT | 
| 169 |     }; | 
| 170 |  | 
| 171 |     class ClassWithSetterGetterSignals : public QObject | 
| 172 |     { | 
| 173 |         Q_OBJECT | 
| 174 |  | 
| 175 |         public: | 
| 176 |             int value1() const { return m_value1; } | 
| 177 |             void setValue1(int v) { | 
| 178 |                 if (v != m_value1) { | 
| 179 |                     m_value1 = v; | 
| 180 |                     Q_EMIT value1Changed(); | 
| 181 |                 } | 
| 182 |             } | 
| 183 |  | 
| 184 |             int value2() const { return m_value2; } | 
| 185 |             void setValue2(int v) { | 
| 186 |                 if (v != m_value2) { | 
| 187 |                     m_value2 = v; | 
| 188 |                     Q_EMIT value2Changed(); | 
| 189 |                 } | 
| 190 |             } | 
| 191 |  | 
| 192 |         Q_SIGNALS: | 
| 193 |             void value1Changed(); | 
| 194 |             void value2Changed(); | 
| 195 |  | 
| 196 |         private: | 
| 197 |             int m_value1 = 0; | 
| 198 |             int m_value2 = 0; | 
| 199 |     }; | 
| 200 |  | 
| 201 |     class ClassWithSetterGetterSignalsAddsProperties : public ClassWithSetterGetterSignals | 
| 202 |     { | 
| 203 |         Q_OBJECT | 
| 204 |         Q_PROPERTY(int value1 READ value1 WRITE setValue1 NOTIFY value1Changed) | 
| 205 |         Q_PROPERTY(int value2 READ value2 WRITE setValue2 NOTIFY value2Changed) | 
| 206 |     }; | 
| 207 |  | 
| 208 |     class ClassWithChangedSignal : public QObject | 
| 209 |     { | 
| 210 |         Q_OBJECT | 
| 211 |  | 
| 212 |         public: | 
| 213 |             int value1() const { return m_value1; } | 
| 214 |             void setValue1(int v) { | 
| 215 |                 if (v != m_value1) { | 
| 216 |                     m_value1 = v; | 
| 217 |                     Q_EMIT propertiesChanged(); | 
| 218 |                 } | 
| 219 |             } | 
| 220 |  | 
| 221 |             void thisIsNotASignal() { } | 
| 222 |  | 
| 223 |         Q_SIGNALS: | 
| 224 |             void propertiesChanged(); | 
| 225 |  | 
| 226 |         private: | 
| 227 |             int m_value1 = 0; | 
| 228 |     }; | 
| 229 |  | 
| 230 |     class ClassWithChangedSignalNewValue : public ClassWithChangedSignal | 
| 231 |     { | 
| 232 |         Q_OBJECT | 
| 233 |  | 
| 234 |         Q_PROPERTY(int value2 MEMBER m_value2 NOTIFY propertiesChanged) | 
| 235 |         Q_PROPERTY(int value3 MEMBER m_value3 NOTIFY thisIsNotASignal) | 
| 236 |  | 
| 237 |         private: | 
| 238 |             int m_value2 = 0; | 
| 239 |             int m_value3 = 0; | 
| 240 |     }; | 
| 241 | } | 
| 242 |  | 
| 243 |  | 
| 244 | class tst_QMetaObject : public QObject | 
| 245 | { | 
| 246 |     Q_OBJECT | 
| 247 |     Q_PROPERTY(EnumType value WRITE setValue READ getValue) | 
| 248 |     Q_PROPERTY(EnumType value2 WRITE set_value READ get_value) | 
| 249 |     Q_PROPERTY(MyStruct value3 WRITE setVal3 READ val3) | 
| 250 |     Q_PROPERTY(QList<QVariant> value4 WRITE setVal4 READ val4) | 
| 251 |     Q_PROPERTY(QVariantList value5 WRITE setVal5 READ val5) | 
| 252 |     Q_PROPERTY(int value6 READ value6 NOTIFY value6Changed) | 
| 253 |     Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed) | 
| 254 |     Q_PROPERTY(int value8 READ value8) | 
| 255 |     Q_PROPERTY(int value9 READ value9 CONSTANT) | 
| 256 |     Q_PROPERTY(int value10 READ value10 FINAL) | 
| 257 |  | 
| 258 | public: | 
| 259 |     enum EnumType { EnumType1 }; | 
| 260 |     Q_ENUM(EnumType); | 
| 261 |  | 
| 262 |     void setValue(EnumType) {} | 
| 263 |     EnumType getValue() const { return EnumType1; } | 
| 264 |  | 
| 265 |     void set_value(EnumType) {} | 
| 266 |     EnumType get_value() const { return EnumType1; } | 
| 267 |  | 
| 268 |     void setVal3(MyStruct) {} | 
| 269 |     MyStruct val3() const { MyStruct s = {.i: 42}; return s; } | 
| 270 |  | 
| 271 |     void setVal4(const QList<QVariant> &list) { value4 = list; } | 
| 272 |     QList<QVariant> val4() const { return value4; } | 
| 273 |  | 
| 274 |     void setVal5(const QVariantList &list) { value5 = list; } | 
| 275 |     QVariantList val5() const { return value5; } | 
| 276 |  | 
| 277 |     int value6() const { return 1; } | 
| 278 |  | 
| 279 |     void setVal7(MyStruct) {} | 
| 280 |     MyStruct value7() const { MyStruct s = {.i: 42}; return s; } | 
| 281 |  | 
| 282 |     int value8() const { return 1; } | 
| 283 |  | 
| 284 |     int value9() const { return 1; } | 
| 285 |  | 
| 286 |     int value10() const { return 1; } | 
| 287 |  | 
| 288 |     QList<QVariant> value4; | 
| 289 |     QVariantList value5; | 
| 290 |  | 
| 291 | private slots: | 
| 292 |     void connectSlotsByName(); | 
| 293 |     void invokeMetaMember(); | 
| 294 |     void invokePointer(); | 
| 295 |     void invokeQueuedMetaMember(); | 
| 296 |     void invokeQueuedPointer(); | 
| 297 |     void invokeBlockingQueuedMetaMember(); | 
| 298 |     void invokeBlockingQueuedPointer(); | 
| 299 |     void invokeCustomTypes(); | 
| 300 |     void invokeMetaConstructor(); | 
| 301 |     void invokeTypedefTypes(); | 
| 302 |     void invokeException(); | 
| 303 |     void invokeQueuedAutoRegister(); | 
| 304 |     void qtMetaObjectInheritance(); | 
| 305 |     void normalizedSignature_data(); | 
| 306 |     void normalizedSignature(); | 
| 307 |     void normalizedType_data(); | 
| 308 |     void normalizedType(); | 
| 309 |     void customPropertyType(); | 
| 310 |     void checkScope_data(); | 
| 311 |     void checkScope(); | 
| 312 |     void propertyNotify(); | 
| 313 |     void propertyConstant(); | 
| 314 |     void propertyFinal(); | 
| 315 |  | 
| 316 |     void stdSet(); | 
| 317 |     void classInfo(); | 
| 318 |  | 
| 319 |     void metaMethod(); | 
| 320 |  | 
| 321 |     void indexOfMethod_data(); | 
| 322 |     void indexOfMethod(); | 
| 323 |  | 
| 324 |     void indexOfMethodPMF(); | 
| 325 |  | 
| 326 |     void signalOffset_data(); | 
| 327 |     void signalOffset(); | 
| 328 |     void signalCount_data(); | 
| 329 |     void signalCount(); | 
| 330 |     void signal_data(); | 
| 331 |     void signal(); | 
| 332 |     void signalIndex_data(); | 
| 333 |     void signalIndex(); | 
| 334 |     void enumDebugStream_data(); | 
| 335 |     void enumDebugStream(); | 
| 336 |  | 
| 337 |     void inherits_data(); | 
| 338 |     void inherits(); | 
| 339 |  | 
| 340 |     void notifySignalsInParentClass(); | 
| 341 |  | 
| 342 | signals: | 
| 343 |     void value6Changed(); | 
| 344 |     void value7Changed(const QString &); | 
| 345 | }; | 
| 346 |  | 
| 347 | void tst_QMetaObject::stdSet() | 
| 348 | { | 
| 349 |     const QMetaObject *mo = metaObject(); | 
| 350 |  | 
| 351 |     QMetaProperty prop = mo->property(index: mo->indexOfProperty(name: "value" )); | 
| 352 |     QVERIFY(prop.isValid()); | 
| 353 |     QVERIFY(prop.hasStdCppSet()); | 
| 354 |  | 
| 355 |     prop = mo->property(index: mo->indexOfProperty(name: "value2" )); | 
| 356 |     QVERIFY(prop.isValid()); | 
| 357 |     QVERIFY(!prop.hasStdCppSet()); | 
| 358 | } | 
| 359 |  | 
| 360 | class CTestObject: public QObject | 
| 361 | { | 
| 362 |     Q_OBJECT | 
| 363 |  | 
| 364 | public: | 
| 365 |     CTestObject(): QObject(), invokeCount1(0), invokeCount2(0) | 
| 366 |     { | 
| 367 |     } | 
| 368 |  | 
| 369 |     void fire(const QString &name) | 
| 370 |     { | 
| 371 |         child = new QObject(this); | 
| 372 |         child->setObjectName(name); | 
| 373 |         QMetaObject::connectSlotsByName(o: this); | 
| 374 |         delete child; child = 0; | 
| 375 |     } | 
| 376 |  | 
| 377 |     int invokeCount1; | 
| 378 |     int invokeCount2; | 
| 379 |     QObject *child; | 
| 380 |  | 
| 381 | public slots: | 
| 382 |     void on_child1_destroyed(QObject *obj = 0) | 
| 383 |     { | 
| 384 |         ++invokeCount1; | 
| 385 |         if (!obj || obj != child) | 
| 386 |             qWarning() << "on_child1_destroyed invoked with wrong child object" ; | 
| 387 |     } | 
| 388 |     void on_child2_destroyed() { ++invokeCount2; } | 
| 389 | }; | 
| 390 |  | 
| 391 | class CTestObjectOverloads: public QObject | 
| 392 | { | 
| 393 |     Q_OBJECT | 
| 394 |  | 
| 395 | public: | 
| 396 |     CTestObjectOverloads(): invokeCount1(0), invokeCount2(0) {} | 
| 397 |  | 
| 398 |     int invokeCount1; | 
| 399 |     int invokeCount2; | 
| 400 |     QObject *child; | 
| 401 |  | 
| 402 |     void fire(const QString &name) | 
| 403 |     { | 
| 404 |         child = new QObject(this); | 
| 405 |         child->setObjectName(name); | 
| 406 |         QMetaObject::connectSlotsByName(o: this); | 
| 407 |         delete child; child = 0; | 
| 408 |     } | 
| 409 |  | 
| 410 | private slots: | 
| 411 |     void on_child1_destroyed(QObject *obj) | 
| 412 |     { | 
| 413 |         ++invokeCount1; | 
| 414 |         if (!obj || obj != child) | 
| 415 |             qWarning() << "on_child1_destroyed invoked with wrong child object" ; | 
| 416 |     } | 
| 417 |     void on_child1_destroyed() { ++invokeCount2; } | 
| 418 | }; | 
| 419 |  | 
| 420 | #define FUNCTION(x) "QMetaObject::" x ": " | 
| 421 |  | 
| 422 | void tst_QMetaObject::connectSlotsByName() | 
| 423 | { | 
| 424 |     CTestObject obj; | 
| 425 |     QCOMPARE(obj.invokeCount1, 0); | 
| 426 |     QCOMPARE(obj.invokeCount2, 0); | 
| 427 |  | 
| 428 |     QTest::ignoreMessage(type: QtWarningMsg, FUNCTION("connectSlotsByName" ) "No matching signal for on_child1_destroyed(QObject*)" ); | 
| 429 |     QTest::ignoreMessage(type: QtWarningMsg, FUNCTION("connectSlotsByName" ) "No matching signal for on_child2_destroyed()" ); | 
| 430 |     obj.fire(name: "bubu" ); | 
| 431 |     QCOMPARE(obj.invokeCount1, 0); | 
| 432 |     QCOMPARE(obj.invokeCount2, 0); | 
| 433 |  | 
| 434 |     QTest::ignoreMessage(type: QtWarningMsg, FUNCTION("connectSlotsByName" ) "No matching signal for on_child2_destroyed()" ); | 
| 435 |     obj.fire(name: "child1" ); | 
| 436 |     QCOMPARE(obj.invokeCount1, 1); | 
| 437 |     QCOMPARE(obj.invokeCount2, 0); | 
| 438 |  | 
| 439 |     QTest::ignoreMessage(type: QtWarningMsg, FUNCTION("connectSlotsByName" ) "No matching signal for on_child1_destroyed(QObject*)" ); | 
| 440 |     obj.fire(name: "child2" ); | 
| 441 |     QCOMPARE(obj.invokeCount1, 1); | 
| 442 |     QCOMPARE(obj.invokeCount2, 1); | 
| 443 |  | 
| 444 |     QTest::ignoreMessage(type: QtWarningMsg, FUNCTION("connectSlotsByName" ) "No matching signal for on_child2_destroyed()" ); | 
| 445 |     obj.fire(name: "child1" ); | 
| 446 |     QCOMPARE(obj.invokeCount1, 2); | 
| 447 |     QCOMPARE(obj.invokeCount2, 1); | 
| 448 |  | 
| 449 |     // now test with real overloads | 
| 450 |     CTestObjectOverloads obj2; | 
| 451 |     obj2.fire(name: "child1" ); | 
| 452 |     QCOMPARE(obj2.invokeCount1, 1); | 
| 453 |     QCOMPARE(obj2.invokeCount2, 1); | 
| 454 | } | 
| 455 |  | 
| 456 | struct MyUnregisteredType { }; | 
| 457 |  | 
| 458 | static int countedStructObjectsCount = 0; | 
| 459 | struct CountedStruct | 
| 460 | { | 
| 461 |     CountedStruct() { ++countedStructObjectsCount; } | 
| 462 |     CountedStruct(const CountedStruct &) { ++countedStructObjectsCount; } | 
| 463 |     CountedStruct &operator=(const CountedStruct &) { return *this; } | 
| 464 |     ~CountedStruct() { --countedStructObjectsCount; } | 
| 465 | }; | 
| 466 |  | 
| 467 | #ifndef QT_NO_EXCEPTIONS | 
| 468 | class ObjectException : public std::exception { }; | 
| 469 | #endif | 
| 470 |  | 
| 471 | class QtTestObject: public QObject | 
| 472 | { | 
| 473 |     friend class tst_QMetaObject; | 
| 474 |     Q_OBJECT | 
| 475 |  | 
| 476 | public: | 
| 477 |     QtTestObject(); | 
| 478 |     QtTestObject(const QString &s) : slotResult(s) {} | 
| 479 |     Q_INVOKABLE QtTestObject(QObject *parent); | 
| 480 |  | 
| 481 | public slots: | 
| 482 |     void sl0(); | 
| 483 |     QString sl1(QString s1); | 
| 484 |     void sl2(QString s1, QString s2); | 
| 485 |     void sl3(QString s1, QString s2, QString s3); | 
| 486 |     void sl4(QString s1, QString s2, QString s3, const QString s4); | 
| 487 |     void sl5(QString s1, QString s2, QString s3, QString s4, const QString &s5); | 
| 488 |     void sl6(QString s1, QString s2, QString s3, QString s4, const QString s5, QString s6); | 
| 489 |     void sl7(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7); | 
| 490 |     void sl8(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, | 
| 491 |             QString s8); | 
| 492 |     void sl9(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, | 
| 493 |             QString s8, QString s9); | 
| 494 |     void sl10(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, | 
| 495 |             QString s8, QString s9, QString s10); | 
| 496 |     QObject *sl11(); | 
| 497 |     const char *sl12(); | 
| 498 |     QList<QString> sl13(QList<QString> l1); | 
| 499 |     qint64 sl14(); | 
| 500 |     void testSender(); | 
| 501 |  | 
| 502 |     void testReference(QString &str); | 
| 503 |  | 
| 504 |     void testLongLong(qint64 ll1, quint64 ll2); | 
| 505 |  | 
| 506 |     void moveToThread(QThread *t) | 
| 507 |     { QObject::moveToThread(thread: t); } | 
| 508 |  | 
| 509 |     void slotWithUnregisteredParameterType(MyUnregisteredType); | 
| 510 |     void slotWithOneUnregisteredParameterType(QString a1, MyUnregisteredType a2); | 
| 511 |  | 
| 512 |     CountedStruct throwingSlot(const CountedStruct &, CountedStruct s2) { | 
| 513 | #ifndef QT_NO_EXCEPTIONS | 
| 514 |         throw ObjectException(); | 
| 515 | #endif | 
| 516 |         return s2; | 
| 517 |     } | 
| 518 |  | 
| 519 |     void slotWithRegistrableArgument(QtTestObject *o1, QPointer<QtTestObject> o2, | 
| 520 |                                      QSharedPointer<QtTestObject> o3, QWeakPointer<QtTestObject> o4, | 
| 521 |                                      QVector<QtTestObject *> o5, QList<QtTestObject *> o6) | 
| 522 |     { | 
| 523 |         slotResult = QLatin1String("slotWithRegistrableArgument:" ) + o1->slotResult + o2->slotResult | 
| 524 |             + o3->slotResult + o4.toStrongRef()->slotResult + QString::number(o5.size()) | 
| 525 |             + QString::number(o6.size()); | 
| 526 |     } | 
| 527 |  | 
| 528 | public: | 
| 529 |     static void staticFunction0(); | 
| 530 |     static qint64 staticFunction1(); | 
| 531 |  | 
| 532 | signals: | 
| 533 |     void sig0(); | 
| 534 |     QString sig1(QString s1); | 
| 535 |     void sig10(QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, | 
| 536 |                QString s8, QString s9, QString s10); | 
| 537 |  | 
| 538 | protected: | 
| 539 |     QtTestObject(QVariant) {} | 
| 540 | private: | 
| 541 |     QtTestObject(QVariant, QVariant) {} | 
| 542 |  | 
| 543 | public: | 
| 544 |     QString slotResult; | 
| 545 |     static QString staticResult; | 
| 546 | }; | 
| 547 |  | 
| 548 | QString QtTestObject::staticResult; | 
| 549 |  | 
| 550 | QtTestObject::QtTestObject() | 
| 551 | { | 
| 552 |     connect(sender: this, SIGNAL(sig0()), receiver: this, SLOT(sl0())); | 
| 553 |     connect(sender: this, SIGNAL(sig1(QString)), receiver: this, SLOT(sl1(QString))); | 
| 554 | } | 
| 555 |  | 
| 556 | QtTestObject::QtTestObject(QObject *parent) | 
| 557 |     : QObject(parent) | 
| 558 | { | 
| 559 | } | 
| 560 |  | 
| 561 | void QtTestObject::sl0() { slotResult = "sl0" ; }; | 
| 562 | QString QtTestObject::sl1(QString s1) { slotResult = "sl1:"  + s1; return "yessir" ; } | 
| 563 | void QtTestObject::sl2(QString s1, QString s2) { slotResult = "sl2:"  + s1 + s2; } | 
| 564 | void QtTestObject::sl3(QString s1, QString s2, QString s3) | 
| 565 | { slotResult = "sl3:"  + s1 + s2 + s3; } | 
| 566 | void QtTestObject::sl4(QString s1, QString s2, QString s3, const QString s4) | 
| 567 | { slotResult = "sl4:"  + s1 + s2 + s3 + s4; } | 
| 568 | void QtTestObject::sl5(QString s1, QString s2, QString s3, QString s4, const QString &s5) | 
| 569 | { slotResult = "sl5:"  + s1 + s2 + s3 + s4 + s5; } | 
| 570 | void QtTestObject::sl6(QString s1, QString s2, QString s3, QString s4, | 
| 571 |                       const QString s5, QString s6) | 
| 572 | { slotResult = "sl6:"  + s1 + s2 + s3 + s4 + s5 + s6; } | 
| 573 | void QtTestObject::sl7(QString s1, QString s2, QString s3, QString s4, QString s5, | 
| 574 |                       QString s6, QString s7) | 
| 575 | { slotResult = "sl7:"  + s1 + s2 + s3 + s4 + s5 + s6 + s7; } | 
| 576 | void QtTestObject::sl8(QString s1, QString s2, QString s3, QString s4, QString s5, | 
| 577 |                       QString s6, QString s7, QString s8) | 
| 578 | { slotResult = "sl8:"  + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8; } | 
| 579 | void QtTestObject::sl9(QString s1, QString s2, QString s3, QString s4, QString s5, | 
| 580 |                       QString s6, QString s7, QString s8, QString s9) | 
| 581 | { slotResult = "sl9:"  + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; } | 
| 582 | void QtTestObject::sl10(QString s1, QString s2, QString s3, QString s4, QString s5, | 
| 583 |                       QString s6, QString s7, QString s8, QString s9, QString s10) | 
| 584 | { slotResult = "sl10:"  + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; } | 
| 585 | QObject *QtTestObject::sl11() | 
| 586 | { slotResult = "sl11" ; return this; } | 
| 587 | const char *QtTestObject::sl12() | 
| 588 | { slotResult = "sl12" ; return "foo" ; } | 
| 589 | QList<QString> QtTestObject::sl13(QList<QString> l1) | 
| 590 | { slotResult = "sl13" ; return l1; } | 
| 591 | qint64 QtTestObject::sl14() | 
| 592 | { slotResult = "sl14" ; return Q_INT64_C(123456789)*123456789; } | 
| 593 |  | 
| 594 | void QtTestObject::testReference(QString &str) | 
| 595 | { slotResult = "testReference:"  + str; str = "gotcha" ; } | 
| 596 |  | 
| 597 | void QtTestObject::testLongLong(qint64 ll1, quint64 ll2) | 
| 598 | { slotResult = "testLongLong:"  + QString::number(ll1) + ","  + QString::number(ll2); } | 
| 599 |  | 
| 600 | void QtTestObject::testSender() | 
| 601 | { | 
| 602 |     slotResult = QString::asprintf(format: "%p" , sender()); | 
| 603 | } | 
| 604 |  | 
| 605 | void QtTestObject::slotWithUnregisteredParameterType(MyUnregisteredType) | 
| 606 | { slotResult = "slotWithUnregisteredReturnType" ; } | 
| 607 |  | 
| 608 | void QtTestObject::slotWithOneUnregisteredParameterType(QString a1, MyUnregisteredType) | 
| 609 | { slotResult = "slotWithUnregisteredReturnType-"  + a1; } | 
| 610 |  | 
| 611 | void QtTestObject::staticFunction0() | 
| 612 | { | 
| 613 |     staticResult = "staticFunction0" ; | 
| 614 | } | 
| 615 |  | 
| 616 | qint64 QtTestObject::staticFunction1() | 
| 617 | { staticResult = "staticFunction1" ; return Q_INT64_C(123456789)*123456789; } | 
| 618 |  | 
| 619 | void tst_QMetaObject::invokeMetaMember() | 
| 620 | { | 
| 621 |     QtTestObject obj; | 
| 622 |  | 
| 623 |     QString t1("1" ); QString t2("2" ); QString t3("3" ); QString t4("4" ); QString t5("5" ); | 
| 624 |     QString t6("6" ); QString t7("7" ); QString t8("8" ); QString t9("9" ); QString t10("X" ); | 
| 625 |  | 
| 626 |     // Test nullptr | 
| 627 |     char *nullCharArray = nullptr; | 
| 628 |     const char *nullConstCharArray = nullptr; | 
| 629 |     QVERIFY(!QMetaObject::invokeMethod(nullptr, nullCharArray)); | 
| 630 |     QVERIFY(!QMetaObject::invokeMethod(nullptr, nullConstCharArray)); | 
| 631 |     QVERIFY(!QMetaObject::invokeMethod(nullptr, "sl0" )); | 
| 632 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray)); | 
| 633 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray)); | 
| 634 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray, Qt::AutoConnection)); | 
| 635 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray, Qt::AutoConnection)); | 
| 636 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray, Qt::AutoConnection, QGenericReturnArgument())); | 
| 637 |     QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray, Qt::AutoConnection, QGenericReturnArgument())); | 
| 638 |  | 
| 639 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl0" )); | 
| 640 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 641 |  | 
| 642 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Q_ARG(QString, t1))); | 
| 643 |     QCOMPARE(obj.slotResult, QString("sl1:1" )); | 
| 644 |  | 
| 645 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl2" , Q_ARG(const QString, t1), Q_ARG(QString, t2))); | 
| 646 |     QCOMPARE(obj.slotResult, QString("sl2:12" )); | 
| 647 |  | 
| 648 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl3" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3))); | 
| 649 |     QCOMPARE(obj.slotResult, QString("sl3:123" )); | 
| 650 |  | 
| 651 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl4" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 652 |                        Q_ARG(QString, t4))); | 
| 653 |     QCOMPARE(obj.slotResult, QString("sl4:1234" )); | 
| 654 |  | 
| 655 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl5" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 656 |                        Q_ARG(QString, t4), Q_ARG(QString, "5" ))); | 
| 657 |     QCOMPARE(obj.slotResult, QString("sl5:12345" )); | 
| 658 |  | 
| 659 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl6" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 660 |                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6))); | 
| 661 |     QCOMPARE(obj.slotResult, QString("sl6:123456" )); | 
| 662 |  | 
| 663 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl7" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 664 |                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 665 |                        Q_ARG(QString, t7))); | 
| 666 |     QCOMPARE(obj.slotResult, QString("sl7:1234567" )); | 
| 667 |  | 
| 668 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl8" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 669 |                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 670 |                        Q_ARG(QString, t7), Q_ARG(QString, t8))); | 
| 671 |     QCOMPARE(obj.slotResult, QString("sl8:12345678" )); | 
| 672 |  | 
| 673 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl9" , Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3), | 
| 674 |                        Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 675 |                        Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9))); | 
| 676 |     QCOMPARE(obj.slotResult, QString("sl9:123456789" )); | 
| 677 |  | 
| 678 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" )); | 
| 679 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 680 |  | 
| 681 |     QVERIFY(QMetaObject::invokeMethod(&obj, "testSender" )); | 
| 682 |     QCOMPARE(obj.slotResult, QString("0x0" )); | 
| 683 |  | 
| 684 |     QString refStr("whatever" ); | 
| 685 |     QVERIFY(QMetaObject::invokeMethod(&obj, "testReference" , QGenericArgument("QString&" , &refStr))); | 
| 686 |     QCOMPARE(obj.slotResult, QString("testReference:whatever" )); | 
| 687 |     QCOMPARE(refStr, QString("gotcha" )); | 
| 688 |  | 
| 689 |     qint64 ll1 = -1; | 
| 690 |     quint64 ll2 = 0; | 
| 691 |     QVERIFY(QMetaObject::invokeMethod(&obj, | 
| 692 |                                       "testLongLong" , | 
| 693 |                                       Q_ARG(qint64, ll1), | 
| 694 |                                       Q_ARG(quint64, ll2))); | 
| 695 |     QCOMPARE(obj.slotResult, QString("testLongLong:-1,0" )); | 
| 696 |  | 
| 697 |     QString exp; | 
| 698 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Q_RETURN_ARG(QString, exp), Q_ARG(QString, "bubu" ))); | 
| 699 |     QCOMPARE(exp, QString("yessir" )); | 
| 700 |     QCOMPARE(obj.slotResult, QString("sl1:bubu" )); | 
| 701 |  | 
| 702 |     QObject *ptr = 0; | 
| 703 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" , Q_RETURN_ARG(QObject*,ptr))); | 
| 704 |     QCOMPARE(ptr, (QObject *)&obj); | 
| 705 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 706 |     // try again with a space: | 
| 707 |     ptr = 0; | 
| 708 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" , Q_RETURN_ARG(QObject * , ptr))); | 
| 709 |     QCOMPARE(ptr, (QObject *)&obj); | 
| 710 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 711 |  | 
| 712 |     const char *ptr2 = 0; | 
| 713 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12" , Q_RETURN_ARG(const char*, ptr2))); | 
| 714 |     QVERIFY(ptr2 != 0); | 
| 715 |     QCOMPARE(obj.slotResult, QString("sl12" )); | 
| 716 |     // try again with a space: | 
| 717 |     ptr2 = 0; | 
| 718 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12" , Q_RETURN_ARG(char const * , ptr2))); | 
| 719 |     QVERIFY(ptr2 != 0); | 
| 720 |     QCOMPARE(obj.slotResult, QString("sl12" )); | 
| 721 |  | 
| 722 |     // test w/ template args | 
| 723 |     QList<QString> returnValue, argument; | 
| 724 |     argument << QString("one" ) << QString("two" ) << QString("three" ); | 
| 725 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl13" , | 
| 726 |                                       Q_RETURN_ARG(QList<QString>, returnValue), | 
| 727 |                                       Q_ARG(QList<QString>, argument))); | 
| 728 |     QCOMPARE(returnValue, argument); | 
| 729 |     QCOMPARE(obj.slotResult, QString("sl13" )); | 
| 730 |  | 
| 731 |     // return qint64 | 
| 732 |     qint64 return64; | 
| 733 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl14" , | 
| 734 |                                       Q_RETURN_ARG(qint64, return64))); | 
| 735 |     QCOMPARE(return64, Q_INT64_C(123456789)*123456789); | 
| 736 |     QCOMPARE(obj.slotResult, QString("sl14" )); | 
| 737 |  | 
| 738 |     //test signals | 
| 739 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig0" )); | 
| 740 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 741 |  | 
| 742 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1" , Q_ARG(QString, "baba" ))); | 
| 743 |     QCOMPARE(obj.slotResult, QString("sl1:baba" )); | 
| 744 |  | 
| 745 |     exp.clear(); | 
| 746 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1" , Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe" ))); | 
| 747 |     QCOMPARE(exp, QString("yessir" )); | 
| 748 |     QCOMPARE(obj.slotResult, QString("sl1:hehe" )); | 
| 749 |  | 
| 750 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()" ); | 
| 751 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist" )); | 
| 752 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)" ); | 
| 753 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)" , Q_ARG(QString, "arg" ))); | 
| 754 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n"  | 
| 755 |                          "Candidates are:\n    sl3(QString,QString,QString)" ); | 
| 756 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3" , Q_ARG(QString, "arg" ))); | 
| 757 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"  | 
| 758 |                          "Candidates are:\n    sl1(QString)" ); | 
| 759 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1" , Q_ARG(QString, "arg" ), Q_ARG(QString, "arg" ), Q_ARG(QString, "arg" ))); | 
| 760 |  | 
| 761 |     //should not have changed since last test. | 
| 762 |     QCOMPARE(exp, QString("yessir" )); | 
| 763 |     QCOMPARE(obj.slotResult, QString("sl1:hehe" )); | 
| 764 | } | 
| 765 |  | 
| 766 | void testFunction(){} | 
| 767 |  | 
| 768 |  | 
| 769 | void tst_QMetaObject::invokePointer() | 
| 770 | { | 
| 771 |     QtTestObject obj; | 
| 772 |     QtTestObject *const nullTestObject = nullptr; | 
| 773 |  | 
| 774 |     QString t1("1" ); | 
| 775 |  | 
| 776 |     // Test member functions | 
| 777 |     QVERIFY(!QMetaObject::invokeMethod(nullTestObject, &QtTestObject::sl0)); | 
| 778 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl0)); | 
| 779 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 780 |  | 
| 781 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::testSender)); | 
| 782 |     QCOMPARE(obj.slotResult, QString("0x0" )); | 
| 783 |  | 
| 784 |     qint64 return64 = 0; | 
| 785 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl14, &return64)); | 
| 786 |     QCOMPARE(return64, Q_INT64_C(123456789)*123456789); | 
| 787 |     QCOMPARE(obj.slotResult, QString("sl14" )); | 
| 788 |  | 
| 789 |     // signals | 
| 790 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sig0)); | 
| 791 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 792 |  | 
| 793 |     // Test function pointers | 
| 794 |     QVERIFY(!QMetaObject::invokeMethod(0, &testFunction)); | 
| 795 |     QVERIFY(QMetaObject::invokeMethod(&obj, &testFunction)); | 
| 796 |  | 
| 797 |     QVERIFY(!QMetaObject::invokeMethod(0, &QtTestObject::staticFunction0)); | 
| 798 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::staticFunction0)); | 
| 799 |     QCOMPARE(QtTestObject::staticResult, QString("staticFunction0" )); | 
| 800 |  | 
| 801 |     return64 = 0; | 
| 802 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::staticFunction1, &return64)); | 
| 803 |     QCOMPARE(return64, Q_INT64_C(123456789)*123456789); | 
| 804 |     QCOMPARE(QtTestObject::staticResult, QString("staticFunction1" )); | 
| 805 |  | 
| 806 |     // Test lambdas | 
| 807 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 808 |     { | 
| 809 |         CountedStruct str; | 
| 810 |         QVERIFY(QMetaObject::invokeMethod(&obj, [str, &t1, &obj]() { obj.sl1(t1); })); | 
| 811 |         QCOMPARE(obj.slotResult, QString("sl1:1" )); | 
| 812 |     } | 
| 813 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 814 |     { | 
| 815 |         CountedStruct str; | 
| 816 |         QString exp; | 
| 817 |         QVERIFY(QMetaObject::invokeMethod( | 
| 818 |             &obj, [str, &obj]() -> QString { return obj.sl1("bubu" ); }, &exp)); | 
| 819 |         QCOMPARE(exp, QString("yessir" )); | 
| 820 |         QCOMPARE(obj.slotResult, QString("sl1:bubu" )); | 
| 821 |     } | 
| 822 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 823 | #ifdef __cpp_init_captures | 
| 824 |     { | 
| 825 |         CountedStruct str; | 
| 826 |         std::unique_ptr<int> ptr( new int ); | 
| 827 |         QVERIFY(QMetaObject::invokeMethod(&obj, [str, &t1, &obj, p = std::move(ptr)]() { obj.sl1(t1); })); | 
| 828 |         QCOMPARE(obj.slotResult, QString("sl1:1" )); | 
| 829 |     } | 
| 830 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 831 | #endif | 
| 832 | } | 
| 833 |  | 
| 834 | void tst_QMetaObject::invokeQueuedMetaMember() | 
| 835 | { | 
| 836 |     QtTestObject obj; | 
| 837 |  | 
| 838 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl0" , Qt::QueuedConnection)); | 
| 839 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 840 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 841 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 842 |     obj.slotResult = QString(); | 
| 843 |  | 
| 844 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Qt::QueuedConnection, Q_ARG(QString, QString("hallo" )))); | 
| 845 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 846 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 847 |     QCOMPARE(obj.slotResult, QString("sl1:hallo" )); | 
| 848 |     obj.slotResult = QString(); | 
| 849 |  | 
| 850 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl9" , Qt::QueuedConnection, Q_ARG(QString, "1" ), Q_ARG(QString, "2" ), | 
| 851 |                        Q_ARG(QString, "3" ), Q_ARG(QString, "4" ), Q_ARG(QString, "5" ), | 
| 852 |                        Q_ARG(QString, "6" ), Q_ARG(QString, "7" ), Q_ARG(QString, "8" ), | 
| 853 |                        Q_ARG(QString, "9" ))); | 
| 854 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 855 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 856 |     QCOMPARE(obj.slotResult, QString("sl9:123456789" )); | 
| 857 |  | 
| 858 |     // signals | 
| 859 |  | 
| 860 |     obj.slotResult.clear(); | 
| 861 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig0" , Qt::QueuedConnection)); | 
| 862 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 863 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 864 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 865 |  | 
| 866 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1" , Qt::QueuedConnection, Q_ARG(QString, "gogo" ))); | 
| 867 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 868 |     QCOMPARE(obj.slotResult, QString("sl1:gogo" )); | 
| 869 |  | 
| 870 |     QString exp; | 
| 871 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaMethod::invoke: Unable to invoke methods with return values in queued connections" ); | 
| 872 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sig1" , Qt::QueuedConnection, Q_RETURN_ARG(QString, exp), | 
| 873 |                               Q_ARG(QString, "nono" ))); | 
| 874 |  | 
| 875 |     qint64 ll1 = -1; | 
| 876 |     quint64 ll2 = 0; | 
| 877 |     QVERIFY(QMetaObject::invokeMethod(&obj, | 
| 878 |                                       "testLongLong" , | 
| 879 |                                       Qt::QueuedConnection, | 
| 880 |                                       Q_ARG(qint64, ll1), | 
| 881 |                                       Q_ARG(quint64, ll2))); | 
| 882 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 883 |     QCOMPARE(obj.slotResult, QString("testLongLong:-1,0" )); | 
| 884 |  | 
| 885 |     obj.slotResult.clear(); | 
| 886 |     { | 
| 887 |         MyUnregisteredType t; | 
| 888 |         QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyUnregisteredType'" ); | 
| 889 |         QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithUnregisteredParameterType" , Qt::QueuedConnection, Q_ARG(MyUnregisteredType, t))); | 
| 890 |         QVERIFY(obj.slotResult.isEmpty()); | 
| 891 |     } | 
| 892 |  | 
| 893 |     obj.slotResult.clear(); | 
| 894 |     { | 
| 895 |         QString a1("Cannot happen" ); | 
| 896 |         MyUnregisteredType t; | 
| 897 |         QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyUnregisteredType'" ); | 
| 898 |         QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithOneUnregisteredParameterType" , Qt::QueuedConnection, | 
| 899 |                                            Q_ARG(QString, a1), Q_ARG(MyUnregisteredType, t))); | 
| 900 |         QVERIFY(obj.slotResult.isEmpty()); | 
| 901 |     } | 
| 902 | } | 
| 903 |  | 
| 904 | void tst_QMetaObject::invokeQueuedPointer() | 
| 905 | { | 
| 906 |     QtTestObject obj; | 
| 907 |  | 
| 908 |     // Test member function | 
| 909 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl0, Qt::QueuedConnection)); | 
| 910 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 911 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 912 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 913 |  | 
| 914 |     // signals | 
| 915 |     obj.slotResult.clear(); | 
| 916 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sig0, Qt::QueuedConnection)); | 
| 917 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 918 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 919 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 920 |  | 
| 921 |     // Test function pointers | 
| 922 |     QtTestObject::staticResult.clear(); | 
| 923 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::staticFunction0, Qt::QueuedConnection)); | 
| 924 |     QVERIFY(QtTestObject::staticResult.isEmpty()); | 
| 925 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 926 |     QCOMPARE(QtTestObject::staticResult, QString("staticFunction0" )); | 
| 927 |  | 
| 928 |     // Test lambda | 
| 929 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 930 |     { | 
| 931 |         CountedStruct str; | 
| 932 |         obj.slotResult.clear(); | 
| 933 |         QVERIFY( | 
| 934 |             QMetaObject::invokeMethod(&obj, [str, &obj]() { obj.sl0(); }, Qt::QueuedConnection)); | 
| 935 |         QVERIFY(obj.slotResult.isEmpty()); | 
| 936 |         qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 937 |         QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 938 |     } | 
| 939 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 940 |     { | 
| 941 |         CountedStruct str; | 
| 942 |         qint32 var = 0; | 
| 943 |         QTest::ignoreMessage(type: QtWarningMsg, | 
| 944 |                              message: "QMetaObject::invokeMethod: Unable to invoke methods with return "  | 
| 945 |                              "values in queued connections" ); | 
| 946 |         QVERIFY(!QMetaObject::invokeMethod(&obj, [str]() -> qint32 { return 1; }, | 
| 947 |                                            Qt::QueuedConnection, &var)); | 
| 948 |         QCOMPARE(var, 0); | 
| 949 |     } | 
| 950 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 951 | } | 
| 952 |  | 
| 953 |  | 
| 954 | void tst_QMetaObject::invokeBlockingQueuedMetaMember() | 
| 955 | { | 
| 956 |     QThread t; | 
| 957 |     t.start(); | 
| 958 |     QtTestObject obj; | 
| 959 |     obj.moveToThread(t: &t); | 
| 960 |  | 
| 961 |     QString t1("1" ); QString t2("2" ); QString t3("3" ); QString t4("4" ); QString t5("5" ); | 
| 962 |     QString t6("6" ); QString t7("7" ); QString t8("8" ); QString t9("9" ); QString t10("X" ); | 
| 963 |  | 
| 964 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1))); | 
| 965 |     QCOMPARE(obj.slotResult, QString("sl1:1" )); | 
| 966 |  | 
| 967 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl2" , Qt::BlockingQueuedConnection, Q_ARG(const QString, t1), Q_ARG(QString, t2))); | 
| 968 |     QCOMPARE(obj.slotResult, QString("sl2:12" )); | 
| 969 |  | 
| 970 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl3" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3))); | 
| 971 |     QCOMPARE(obj.slotResult, QString("sl3:123" )); | 
| 972 |  | 
| 973 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl4" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 974 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4))); | 
| 975 |     QCOMPARE(obj.slotResult, QString("sl4:1234" )); | 
| 976 |  | 
| 977 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl5" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 978 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, "5" ))); | 
| 979 |     QCOMPARE(obj.slotResult, QString("sl5:12345" )); | 
| 980 |  | 
| 981 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl6" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 982 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6))); | 
| 983 |     QCOMPARE(obj.slotResult, QString("sl6:123456" )); | 
| 984 |  | 
| 985 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl7" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 986 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 987 |                                       Q_ARG(QString, t7))); | 
| 988 |     QCOMPARE(obj.slotResult, QString("sl7:1234567" )); | 
| 989 |  | 
| 990 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl8" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 991 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 992 |                                       Q_ARG(QString, t7), Q_ARG(QString, t8))); | 
| 993 |     QCOMPARE(obj.slotResult, QString("sl8:12345678" )); | 
| 994 |  | 
| 995 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl9" , Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), | 
| 996 |                                       Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), | 
| 997 |                                       Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9))); | 
| 998 |     QCOMPARE(obj.slotResult, QString("sl9:123456789" )); | 
| 999 |  | 
| 1000 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" , Qt::BlockingQueuedConnection)); | 
| 1001 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 1002 |  | 
| 1003 |     QVERIFY(QMetaObject::invokeMethod(&obj, "testSender" , Qt::BlockingQueuedConnection)); | 
| 1004 |     QCOMPARE(obj.slotResult, QString("0x0" )); | 
| 1005 |  | 
| 1006 |     QString refStr("whatever" ); | 
| 1007 |     QVERIFY(QMetaObject::invokeMethod(&obj, "testReference" , Qt::BlockingQueuedConnection, QGenericArgument("QString&" , &refStr))); | 
| 1008 |     QCOMPARE(obj.slotResult, QString("testReference:whatever" )); | 
| 1009 |     QCOMPARE(refStr, QString("gotcha" )); | 
| 1010 |  | 
| 1011 |     qint64 ll1 = -1; | 
| 1012 |     quint64 ll2 = 0; | 
| 1013 |     QVERIFY(QMetaObject::invokeMethod(&obj, | 
| 1014 |                                       "testLongLong" , | 
| 1015 |                                       Qt::BlockingQueuedConnection, | 
| 1016 |                                       Q_ARG(qint64, ll1), | 
| 1017 |                                       Q_ARG(quint64, ll2))); | 
| 1018 |     QCOMPARE(obj.slotResult, QString("testLongLong:-1,0" )); | 
| 1019 |  | 
| 1020 |     QString exp; | 
| 1021 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "bubu" ))); | 
| 1022 |     QCOMPARE(exp, QString("yessir" )); | 
| 1023 |     QCOMPARE(obj.slotResult, QString("sl1:bubu" )); | 
| 1024 |  | 
| 1025 |     QObject *ptr = 0; | 
| 1026 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject*,ptr))); | 
| 1027 |     QCOMPARE(ptr, (QObject *)&obj); | 
| 1028 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 1029 |     // try again with a space: | 
| 1030 |     ptr = 0; | 
| 1031 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject * , ptr))); | 
| 1032 |     QCOMPARE(ptr, (QObject *)&obj); | 
| 1033 |     QCOMPARE(obj.slotResult, QString("sl11" )); | 
| 1034 |  | 
| 1035 |     const char *ptr2 = 0; | 
| 1036 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(const char*, ptr2))); | 
| 1037 |     QVERIFY(ptr2 != 0); | 
| 1038 |     QCOMPARE(obj.slotResult, QString("sl12" )); | 
| 1039 |     // try again with a space: | 
| 1040 |     ptr2 = 0; | 
| 1041 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl12" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(char const * , ptr2))); | 
| 1042 |     QVERIFY(ptr2 != 0); | 
| 1043 |     QCOMPARE(obj.slotResult, QString("sl12" )); | 
| 1044 |  | 
| 1045 |     // test w/ template args | 
| 1046 |     QList<QString> returnValue, argument; | 
| 1047 |     argument << QString("one" ) << QString("two" ) << QString("three" ); | 
| 1048 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl13" , Qt::BlockingQueuedConnection, | 
| 1049 |                                       Q_RETURN_ARG(QList<QString>, returnValue), | 
| 1050 |                                       Q_ARG(QList<QString>, argument))); | 
| 1051 |     QCOMPARE(returnValue, argument); | 
| 1052 |     QCOMPARE(obj.slotResult, QString("sl13" )); | 
| 1053 |  | 
| 1054 |     //test signals | 
| 1055 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig0" , Qt::BlockingQueuedConnection)); | 
| 1056 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 1057 |  | 
| 1058 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1" , Qt::BlockingQueuedConnection, Q_ARG(QString, "baba" ))); | 
| 1059 |     QCOMPARE(obj.slotResult, QString("sl1:baba" )); | 
| 1060 |  | 
| 1061 |     exp.clear(); | 
| 1062 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig1" , Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe" ))); | 
| 1063 |     QCOMPARE(exp, QString("yessir" )); | 
| 1064 |     QCOMPARE(obj.slotResult, QString("sl1:hehe" )); | 
| 1065 |  | 
| 1066 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()" ); | 
| 1067 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist" , Qt::BlockingQueuedConnection)); | 
| 1068 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)" ); | 
| 1069 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)" , Qt::BlockingQueuedConnection, Q_ARG(QString, "arg" ))); | 
| 1070 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n"  | 
| 1071 |                          "Candidates are:\n    sl3(QString,QString,QString)" ); | 
| 1072 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3" , Qt::BlockingQueuedConnection, Q_ARG(QString, "arg" ))); | 
| 1073 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"  | 
| 1074 |                          "Candidates are:\n    sl1(QString)" ); | 
| 1075 |     QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1" , Qt::BlockingQueuedConnection, Q_ARG(QString, "arg" ), Q_ARG(QString, "arg" ), Q_ARG(QString, "arg" ))); | 
| 1076 |  | 
| 1077 |     //should not have changed since last test. | 
| 1078 |     QCOMPARE(exp, QString("yessir" )); | 
| 1079 |     QCOMPARE(obj.slotResult, QString("sl1:hehe" )); | 
| 1080 |  | 
| 1081 |     QVERIFY(QMetaObject::invokeMethod(&obj, "moveToThread" , Qt::BlockingQueuedConnection, Q_ARG(QThread*, QThread::currentThread()))); | 
| 1082 |     t.quit(); | 
| 1083 |     QVERIFY(t.wait()); | 
| 1084 |  | 
| 1085 | } | 
| 1086 |  | 
| 1087 | void tst_QMetaObject::invokeBlockingQueuedPointer() | 
| 1088 | { | 
| 1089 |     QtTestObject *const nullTestObject = nullptr; | 
| 1090 |  | 
| 1091 |     QThread t; | 
| 1092 |     t.start(); | 
| 1093 |     QtTestObject obj; | 
| 1094 |     obj.moveToThread(t: &t); | 
| 1095 |  | 
| 1096 |     QString t1("1" ); | 
| 1097 |  | 
| 1098 |     // Test member functions | 
| 1099 |     QVERIFY(!QMetaObject::invokeMethod(nullTestObject, &QtTestObject::sl0, Qt::BlockingQueuedConnection)); | 
| 1100 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl0, Qt::BlockingQueuedConnection)); | 
| 1101 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 1102 |  | 
| 1103 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::testSender, Qt::BlockingQueuedConnection)); | 
| 1104 |     QCOMPARE(obj.slotResult, QString("0x0" )); | 
| 1105 |  | 
| 1106 |     // return qint64 | 
| 1107 |     qint64 return64 = 0; | 
| 1108 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl14, Qt::BlockingQueuedConnection, | 
| 1109 |                                       &return64)); | 
| 1110 |     QCOMPARE(return64, Q_INT64_C(123456789)*123456789); | 
| 1111 |     QCOMPARE(obj.slotResult, QString("sl14" )); | 
| 1112 |  | 
| 1113 |     //test signals | 
| 1114 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sig0, Qt::BlockingQueuedConnection)); | 
| 1115 |     QCOMPARE(obj.slotResult, QString("sl0" )); | 
| 1116 |  | 
| 1117 |     // Test function pointers | 
| 1118 |     QVERIFY(!QMetaObject::invokeMethod(0, &testFunction, Qt::BlockingQueuedConnection)); | 
| 1119 |     QVERIFY(QMetaObject::invokeMethod(&obj, &testFunction, Qt::BlockingQueuedConnection)); | 
| 1120 |  | 
| 1121 |     QVERIFY(!QMetaObject::invokeMethod(0, &QtTestObject::staticFunction0, Qt::BlockingQueuedConnection)); | 
| 1122 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::staticFunction0, Qt::BlockingQueuedConnection)); | 
| 1123 |     QCOMPARE(QtTestObject::staticResult, QString("staticFunction0" )); | 
| 1124 |  | 
| 1125 |     return64 = 0; | 
| 1126 |     QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::staticFunction1, Qt::BlockingQueuedConnection, &return64)); | 
| 1127 |     QCOMPARE(return64, Q_INT64_C(123456789)*123456789); | 
| 1128 |     QCOMPARE(QtTestObject::staticResult, QString("staticFunction1" )); | 
| 1129 |  | 
| 1130 |     // Test lambdas | 
| 1131 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 1132 |     { | 
| 1133 |         CountedStruct str; | 
| 1134 |         QVERIFY(QMetaObject::invokeMethod(&obj, [str, &obj, &t1]() { obj.sl1(t1); }, | 
| 1135 |                                           Qt::BlockingQueuedConnection)); | 
| 1136 |         QCOMPARE(obj.slotResult, QString("sl1:1" )); | 
| 1137 |     } | 
| 1138 |     { | 
| 1139 |         CountedStruct str; | 
| 1140 |         QString exp; | 
| 1141 |         QVERIFY(QMetaObject::invokeMethod(&obj, | 
| 1142 |                                           [&obj, str]() -> QString { return obj.sl1("bubu" ); }, | 
| 1143 |                                           Qt::BlockingQueuedConnection, &exp)); | 
| 1144 |         QCOMPARE(exp, QString("yessir" )); | 
| 1145 |         QCOMPARE(obj.slotResult, QString("sl1:bubu" )); | 
| 1146 |     } | 
| 1147 | #ifdef __cpp_init_captures | 
| 1148 |     { | 
| 1149 |         std::unique_ptr<int> ptr(new int); | 
| 1150 |         QVERIFY(QMetaObject::invokeMethod(&obj, | 
| 1151 |                                           [&obj, p = std::move(ptr)]() { return obj.sl1("hehe" ); }, | 
| 1152 |                                           Qt::BlockingQueuedConnection)); | 
| 1153 |         QCOMPARE(obj.slotResult, QString("sl1:hehe" )); | 
| 1154 |     } | 
| 1155 | #endif | 
| 1156 |     QVERIFY(QMetaObject::invokeMethod(&obj, [&](){obj.moveToThread(QThread::currentThread());}, Qt::BlockingQueuedConnection)); | 
| 1157 |     t.quit(); | 
| 1158 |     QVERIFY(t.wait()); | 
| 1159 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 1160 | } | 
| 1161 |  | 
| 1162 |  | 
| 1163 | void tst_QMetaObject::qtMetaObjectInheritance() | 
| 1164 | { | 
| 1165 |     QVERIFY(!QObject::staticMetaObject.superClass()); | 
| 1166 |     QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("Qt::CaseSensitivity" ), -1); | 
| 1167 |     QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("CaseSensitivity" ), -1); | 
| 1168 |     int indexOfSortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.indexOfProperty(name: "sortCaseSensitivity" ); | 
| 1169 |     QVERIFY(indexOfSortCaseSensitivity != -1); | 
| 1170 |     QMetaProperty sortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.property(index: indexOfSortCaseSensitivity); | 
| 1171 |     QVERIFY(sortCaseSensitivity.isValid()); | 
| 1172 |     QCOMPARE(sortCaseSensitivity.enumerator().name(), "CaseSensitivity" ); | 
| 1173 | } | 
| 1174 |  | 
| 1175 | struct MyType | 
| 1176 | { | 
| 1177 |     int i1, i2, i3; | 
| 1178 | }; | 
| 1179 |  | 
| 1180 | typedef QString CustomString; | 
| 1181 |  | 
| 1182 | class QtTestCustomObject: public QObject | 
| 1183 | { | 
| 1184 |     Q_OBJECT | 
| 1185 |     friend class tst_QMetaObject; | 
| 1186 | public: | 
| 1187 |     QtTestCustomObject(): QObject(), sum(0) {} | 
| 1188 |  | 
| 1189 | public slots: | 
| 1190 |     void sl1(MyType myType); | 
| 1191 |  | 
| 1192 | signals: | 
| 1193 |     void sig_custom(const CustomString &string); | 
| 1194 |  | 
| 1195 | public: | 
| 1196 |     int sum; | 
| 1197 | }; | 
| 1198 |  | 
| 1199 | void QtTestCustomObject::sl1(MyType myType) | 
| 1200 | { | 
| 1201 |     sum = myType.i1 + myType.i2 + myType.i3; | 
| 1202 | } | 
| 1203 |  | 
| 1204 | void tst_QMetaObject::invokeCustomTypes() | 
| 1205 | { | 
| 1206 |     QtTestCustomObject obj; | 
| 1207 |     MyType tp = {.i1: 1, .i2: 1, .i3: 1}; | 
| 1208 |  | 
| 1209 |     QCOMPARE(obj.sum, 0); | 
| 1210 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sl1" , Q_ARG(MyType, tp))); | 
| 1211 |     QCOMPARE(obj.sum, 3); | 
| 1212 | } | 
| 1213 |  | 
| 1214 | namespace NamespaceWithConstructibleClass | 
| 1215 | { | 
| 1216 |  | 
| 1217 | class ConstructibleClass : public QObject | 
| 1218 | { | 
| 1219 |     Q_OBJECT | 
| 1220 | public: | 
| 1221 |     Q_INVOKABLE ConstructibleClass(QObject *parent = 0) | 
| 1222 |         : QObject(parent) {} | 
| 1223 | }; | 
| 1224 |  | 
| 1225 | } | 
| 1226 |  | 
| 1227 | void tst_QMetaObject::invokeMetaConstructor() | 
| 1228 | { | 
| 1229 |     const QMetaObject *mo = &QtTestObject::staticMetaObject; | 
| 1230 |     { | 
| 1231 |         QObject *obj = mo->newInstance(); | 
| 1232 |         QVERIFY(!obj); | 
| 1233 |     } | 
| 1234 |     { | 
| 1235 |         QtTestObject obj; | 
| 1236 |         QObject *obj2 = mo->newInstance(Q_ARG(QObject*, &obj)); | 
| 1237 |         QVERIFY(obj2 != 0); | 
| 1238 |         QCOMPARE(obj2->parent(), (QObject*)&obj); | 
| 1239 |         QVERIFY(qobject_cast<QtTestObject*>(obj2) != 0); | 
| 1240 |     } | 
| 1241 |     // class in namespace | 
| 1242 |     const QMetaObject *nsmo = &NamespaceWithConstructibleClass::ConstructibleClass::staticMetaObject; | 
| 1243 |     { | 
| 1244 |         QtTestObject obj; | 
| 1245 |         QObject *obj2 = nsmo->newInstance(Q_ARG(QObject*, &obj)); | 
| 1246 |         QVERIFY(obj2 != 0); | 
| 1247 |         QCOMPARE(obj2->parent(), (QObject*)&obj); | 
| 1248 |         QVERIFY(qobject_cast<NamespaceWithConstructibleClass::ConstructibleClass*>(obj2) != 0); | 
| 1249 |     } | 
| 1250 |     // gadget shouldn't return a valid pointer | 
| 1251 |     { | 
| 1252 |         QCOMPARE(MyGadget::staticMetaObject.constructorCount(), 1); | 
| 1253 |         QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaObject::newInstance: type MyGadget does not inherit QObject" ); | 
| 1254 |         QVERIFY(!MyGadget::staticMetaObject.newInstance()); | 
| 1255 |     } | 
| 1256 | } | 
| 1257 |  | 
| 1258 | void tst_QMetaObject::invokeTypedefTypes() | 
| 1259 | { | 
| 1260 |     qRegisterMetaType<CustomString>(typeName: "CustomString" ); | 
| 1261 |     QtTestCustomObject obj; | 
| 1262 |     QSignalSpy spy(&obj, &QtTestCustomObject::sig_custom); | 
| 1263 |     QVERIFY(spy.isValid()); | 
| 1264 |  | 
| 1265 |     QCOMPARE(spy.count(), 0); | 
| 1266 |     CustomString arg("hello" ); | 
| 1267 |     QVERIFY(QMetaObject::invokeMethod(&obj, "sig_custom" , Q_ARG(CustomString, arg))); | 
| 1268 |     QCOMPARE(spy.count(), 1); | 
| 1269 |     QCOMPARE(spy.at(0).count(), 1); | 
| 1270 |     QCOMPARE(spy.at(0).at(0), QVariant(arg)); | 
| 1271 | } | 
| 1272 |  | 
| 1273 | void tst_QMetaObject::invokeException() | 
| 1274 | { | 
| 1275 | #ifndef QT_NO_EXCEPTIONS | 
| 1276 |     QtTestObject obj; | 
| 1277 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 1278 |     try { | 
| 1279 |         CountedStruct s; | 
| 1280 |         QVERIFY(QMetaObject::invokeMethod(&obj, "throwingSlot" , Q_RETURN_ARG(CountedStruct, s), | 
| 1281 |                                           Q_ARG(CountedStruct, s), Q_ARG(CountedStruct, s))); | 
| 1282 |         QFAIL("Did not throw" ); | 
| 1283 |     } catch(ObjectException &) {} | 
| 1284 |     QCOMPARE(countedStructObjectsCount, 0); | 
| 1285 | #else | 
| 1286 |     QSKIP("Needs exceptions" ); | 
| 1287 | #endif | 
| 1288 | } | 
| 1289 |  | 
| 1290 | void tst_QMetaObject::invokeQueuedAutoRegister() | 
| 1291 | { | 
| 1292 |     QtTestObject obj; | 
| 1293 |  | 
| 1294 |     auto shared = QSharedPointer<QtTestObject>::create(QStringLiteral("myShared-" )); | 
| 1295 |  | 
| 1296 |     QVERIFY(QMetaObject::invokeMethod( | 
| 1297 |         &obj, "slotWithRegistrableArgument" , Qt::QueuedConnection, | 
| 1298 |         Q_ARG(QtTestObject *, shared.data()), Q_ARG(QPointer<QtTestObject>, shared.data()), | 
| 1299 |         Q_ARG(QSharedPointer<QtTestObject>, shared), Q_ARG(QWeakPointer<QtTestObject>, shared), | 
| 1300 |         Q_ARG(QVector<QtTestObject *>, QVector<QtTestObject *>()), | 
| 1301 |         Q_ARG(QList<QtTestObject *>, QList<QtTestObject *>()))); | 
| 1302 |     QVERIFY(obj.slotResult.isEmpty()); | 
| 1303 |     qApp->processEvents(flags: QEventLoop::AllEvents); | 
| 1304 |     QCOMPARE(obj.slotResult, | 
| 1305 |              QString("slotWithRegistrableArgument:myShared-myShared-myShared-myShared-00" )); | 
| 1306 | } | 
| 1307 |  | 
| 1308 | void tst_QMetaObject::normalizedSignature_data() | 
| 1309 | { | 
| 1310 |     QTest::addColumn<QString>(name: "signature" ); | 
| 1311 |     QTest::addColumn<QString>(name: "result" ); | 
| 1312 |  | 
| 1313 |     QTest::newRow(dataTag: "function" ) << "void foo()"  << "void foo()" ; | 
| 1314 |     QTest::newRow(dataTag: "spaces" ) << " void  foo( ) "  << "void foo()" ; | 
| 1315 |     QTest::newRow(dataTag: "void" ) << "void foo(void)"  << "void foo()" ; | 
| 1316 |     QTest::newRow(dataTag: "void spaces" ) << "void foo( void )"  << "void foo()" ; | 
| 1317 |     QTest::newRow(dataTag: "void*" ) << "void foo(void*)"  << "void foo(void*)" ; | 
| 1318 |     QTest::newRow(dataTag: "void* spaces" ) << "void foo( void * )"  << "void foo(void*)" ; | 
| 1319 |     QTest::newRow(dataTag: "function ptr" ) << "void foo(void(*)(void))"  << "void foo(void(*)())" ; | 
| 1320 |     QTest::newRow(dataTag: "function ptr spaces" ) << "void foo( void ( * ) ( void ))"  << "void foo(void(*)())" ; | 
| 1321 |     QTest::newRow(dataTag: "function ptr void*" ) << "void foo(void(*)(void*))"  << "void foo(void(*)(void*))" ; | 
| 1322 |     QTest::newRow(dataTag: "function ptr void* spaces" ) << "void foo( void ( * ) ( void * ))"  << "void foo(void(*)(void*))" ; | 
| 1323 |     QTest::newRow(dataTag: "template args" ) << " void  foo( QMap<a, a>, QList<b>) "  | 
| 1324 |                                    << "void foo(QMap<a,a>,QList<b>)" ; | 
| 1325 |     QTest::newRow(dataTag: "void template args" ) << " void  foo( Foo<void>, Bar<void> ) "  | 
| 1326 |                                    << "void foo(Foo<void>,Bar<void>)" ; | 
| 1327 |     QTest::newRow(dataTag: "void* template args" ) << " void  foo( Foo<void*>, Bar<void *> ) "  | 
| 1328 |                                    << "void foo(Foo<void*>,Bar<void*>)" ; | 
| 1329 |     QTest::newRow(dataTag: "rettype" ) << "QList<int, int> foo()"  << "QList<int,int>foo()" ; | 
| 1330 |     QTest::newRow(dataTag: "rettype void template" ) << "Foo<void> foo()"  << "Foo<void>foo()" ; | 
| 1331 |     QTest::newRow(dataTag: "const rettype" ) << "const QString *foo()"  << "const QString*foo()" ; | 
| 1332 |     QTest::newRow(dataTag: "const ref" ) << "const QString &foo()"  << "const QString&foo()" ; | 
| 1333 |     QTest::newRow(dataTag: "reference" ) << "QString &foo()"  << "QString&foo()" ; | 
| 1334 |     QTest::newRow(dataTag: "const1" ) << "void foo(QString const *)"  << "void foo(const QString*)" ; | 
| 1335 |     QTest::newRow(dataTag: "const2" ) << "void foo(QString * const)"  << "void foo(QString*const)" ; | 
| 1336 |     QTest::newRow(dataTag: "const3" ) << "void foo(QString const &)"  << "void foo(QString)" ; | 
| 1337 |     QTest::newRow(dataTag: "const4" ) << "void foo(const int)"  << "void foo(int)" ; | 
| 1338 |     QTest::newRow(dataTag: "const5" ) << "void foo(const int, int const, const int &, int const &)"  | 
| 1339 |                             << "void foo(int,int,int,int)" ; | 
| 1340 |     QTest::newRow(dataTag: "const6" ) << "void foo(QList<const int>)"  << "void foo(QList<const int>)" ; | 
| 1341 |     QTest::newRow(dataTag: "const7" ) << "void foo(QList<const int*>)"  << "void foo(QList<const int*>)" ; | 
| 1342 |     QTest::newRow(dataTag: "const8" ) << "void foo(QList<int const*>)"  << "void foo(QList<const int*>)" ; | 
| 1343 |     QTest::newRow(dataTag: "const9" ) << "void foo(const Foo<Bar>)"  << "void foo(Foo<Bar>)" ; | 
| 1344 |     QTest::newRow(dataTag: "const10" ) << "void foo(Foo<Bar>const)"  << "void foo(Foo<Bar>)" ; | 
| 1345 |     QTest::newRow(dataTag: "const11" ) << "void foo(Foo<Bar> *const)"  << "void foo(Foo<Bar>*const)" ; | 
| 1346 |     QTest::newRow(dataTag: "const12" ) << "void foo(Foo<Bar>const*const *const)"  << "void foo(Foo<Bar>*const*const)" ; | 
| 1347 |     QTest::newRow(dataTag: "const13" ) << "void foo(const Foo<Bar>&)"  << "void foo(Foo<Bar>)" ; | 
| 1348 |     QTest::newRow(dataTag: "const14" ) << "void foo(Foo<Bar>const&)"  << "void foo(Foo<Bar>)" ; | 
| 1349 |  | 
| 1350 |     QTest::newRow(dataTag: "invalid1" ) << "a( b"  << "a(b" ; | 
| 1351 | } | 
| 1352 |  | 
| 1353 | void tst_QMetaObject::normalizedSignature() | 
| 1354 | { | 
| 1355 |     QFETCH(QString, signature); | 
| 1356 |     QFETCH(QString, result); | 
| 1357 |  | 
| 1358 |     QCOMPARE(QMetaObject::normalizedSignature(signature.toLatin1()), result.toLatin1()); | 
| 1359 | } | 
| 1360 |  | 
| 1361 | void tst_QMetaObject::normalizedType_data() | 
| 1362 | { | 
| 1363 |     QTest::addColumn<QString>(name: "type" ); | 
| 1364 |     QTest::addColumn<QString>(name: "result" ); | 
| 1365 |  | 
| 1366 |     QTest::newRow(dataTag: "simple" ) << "int"  << "int" ; | 
| 1367 |     QTest::newRow(dataTag: "white" ) << "  int  "  << "int" ; | 
| 1368 |     QTest::newRow(dataTag: "const1" ) << "int const *"  << "const int*" ; | 
| 1369 |     QTest::newRow(dataTag: "const2" ) << "const int *"  << "const int*" ; | 
| 1370 |     QTest::newRow(dataTag: "template1" ) << "QList<int const *>"  << "QList<const int*>" ; | 
| 1371 |     QTest::newRow(dataTag: "template2" ) << "QList<const int *>"  << "QList<const int*>" ; | 
| 1372 |     QTest::newRow(dataTag: "template3" ) << "QMap<QString, int>"  << "QMap<QString,int>" ; | 
| 1373 |     QTest::newRow(dataTag: "template4" ) << "const QMap<QString, int> &"  << "QMap<QString,int>" ; | 
| 1374 |     QTest::newRow(dataTag: "template5" ) << "QList< ::Foo::Bar>"  << "QList< ::Foo::Bar>" ; | 
| 1375 |     QTest::newRow(dataTag: "template6" ) << "QList<::Foo::Bar>"  << "QList<::Foo::Bar>" ; | 
| 1376 |     QTest::newRow(dataTag: "template7" ) << "QList<QList<int> >"  << "QList<QList<int> >" ; | 
| 1377 |     QTest::newRow(dataTag: "template8" ) << "QMap<const int, const short*>"  << "QMap<const int,const short*>" ; | 
| 1378 |     QTest::newRow(dataTag: "template9" ) << "QPair<const QPair<int, int const *> , QPair<QHash<int, const char*>  >  >"  << "QPair<const QPair<int,const int*>,QPair<QHash<int,const char*> > >" ; | 
| 1379 |     QTest::newRow(dataTag: "value1" ) << "const QString &"  << "QString" ; | 
| 1380 |     QTest::newRow(dataTag: "value2" ) << "QString const &"  << "QString" ; | 
| 1381 |     QTest::newRow(dataTag: "constInName1" ) << "constconst"  << "constconst" ; | 
| 1382 |     QTest::newRow(dataTag: "constInName2" ) << "constconst*"  << "constconst*" ; | 
| 1383 |     QTest::newRow(dataTag: "constInName3" ) << "const constconst&"  << "constconst" ; | 
| 1384 |     QTest::newRow(dataTag: "constInName4" ) << "constconst const*const"  << "constconst*const" ; | 
| 1385 |     QTest::newRow(dataTag: "class" ) << "const class foo&"  << "foo" ; | 
| 1386 |     QTest::newRow(dataTag: "struct" ) << "const struct foo*"  << "const foo*" ; | 
| 1387 |     QTest::newRow(dataTag: "struct2" ) << "struct foo const*"  << "const foo*" ; | 
| 1388 |     QTest::newRow(dataTag: "enum" ) << "enum foo"  << "foo" ; | 
| 1389 |     QTest::newRow(dataTag: "void" ) << "void"  << "void" ; | 
| 1390 | } | 
| 1391 |  | 
| 1392 | void tst_QMetaObject::normalizedType() | 
| 1393 | { | 
| 1394 |     QFETCH(QString, type); | 
| 1395 |     QFETCH(QString, result); | 
| 1396 |  | 
| 1397 |     QCOMPARE(QMetaObject::normalizedType(type.toLatin1()), result.toLatin1()); | 
| 1398 | } | 
| 1399 |  | 
| 1400 | void tst_QMetaObject::customPropertyType() | 
| 1401 | { | 
| 1402 |     QMetaProperty prop = metaObject()->property(index: metaObject()->indexOfProperty(name: "value3" )); | 
| 1403 |  | 
| 1404 |     QCOMPARE(prop.type(), QVariant::UserType); | 
| 1405 |     QCOMPARE(prop.userType(), 0); | 
| 1406 |  | 
| 1407 |     qRegisterMetaType<MyStruct>(typeName: "MyStruct" ); | 
| 1408 |     QCOMPARE(prop.userType(), QMetaType::type("MyStruct" )); | 
| 1409 |  | 
| 1410 |     prop = metaObject()->property(index: metaObject()->indexOfProperty(name: "value4" )); | 
| 1411 |     QCOMPARE(prop.type(), QVariant::List); | 
| 1412 |  | 
| 1413 |     prop = metaObject()->property(index: metaObject()->indexOfProperty(name: "value5" )); | 
| 1414 |     QCOMPARE(prop.type(), QVariant::List); | 
| 1415 | } | 
| 1416 |  | 
| 1417 | void tst_QMetaObject::checkScope_data() | 
| 1418 | { | 
| 1419 |     QTest::addColumn<QObject *>(name: "object" ); | 
| 1420 |     QTest::addColumn<QByteArray>(name: "name" ); | 
| 1421 |  | 
| 1422 |     static MyNamespace::MyClass obj1; | 
| 1423 |     static MyNamespace::MyClass2 obj2; | 
| 1424 |  | 
| 1425 |     QTest::newRow(dataTag: "MyClass" ) << static_cast<QObject*>(&obj1) << QByteArray("MyClass" ); | 
| 1426 |     QTest::newRow(dataTag: "MyClass2" ) << static_cast<QObject*>(&obj2) << QByteArray("MyClass2" ); | 
| 1427 |  | 
| 1428 | } | 
| 1429 |  | 
| 1430 |  | 
| 1431 | void tst_QMetaObject::checkScope() | 
| 1432 | { | 
| 1433 |     QFETCH(QObject *, object); | 
| 1434 |     QFETCH(QByteArray, name); | 
| 1435 |     QObject  &obj = *object; | 
| 1436 |     bool ok; | 
| 1437 |  | 
| 1438 |     const QMetaObject *mo = obj.metaObject(); | 
| 1439 |     QMetaEnum me = mo->enumerator(index: mo->indexOfEnumerator(name: "MyEnum" )); | 
| 1440 |     QVERIFY(me.isValid()); | 
| 1441 |     QVERIFY(!me.isFlag()); | 
| 1442 |     QCOMPARE(QByteArray(me.scope()), QByteArray("MyNamespace::"  + name)); | 
| 1443 |     QCOMPARE(me.keyToValue("MyNamespace::"  + name + "::MyEnum2" , &ok), 1); | 
| 1444 |     QCOMPARE(ok, true); | 
| 1445 |     QCOMPARE(me.keyToValue(name + "::MyEnum2" , &ok), -1); | 
| 1446 |     QCOMPARE(ok, false); | 
| 1447 |     QCOMPARE(me.keyToValue("MyNamespace::MyEnum2" , &ok), -1); | 
| 1448 |     QCOMPARE(ok, false); | 
| 1449 |     QCOMPARE(me.keyToValue("MyEnum2" , &ok), 1); | 
| 1450 |     QCOMPARE(ok, true); | 
| 1451 |     QCOMPARE(me.keyToValue("MyEnum" , &ok), -1); | 
| 1452 |     QCOMPARE(ok, false); | 
| 1453 |     QCOMPARE(QLatin1String(me.valueToKey(1)), QLatin1String("MyEnum2" )); | 
| 1454 |  | 
| 1455 |     QMetaEnum me2 = mo->enumerator(index: mo->indexOfEnumerator(name: "MyAnotherEnum" )); | 
| 1456 |     QVERIFY(me2.isValid()); | 
| 1457 |     QVERIFY(!me2.isFlag()); | 
| 1458 |     QCOMPARE(me2.keyToValue("MyAnotherEnum1" , &ok), 1); | 
| 1459 |     QCOMPARE(ok, true); | 
| 1460 |     QCOMPARE(me2.keyToValue("MyAnotherEnum2" , &ok), 2); | 
| 1461 |     QCOMPARE(ok, true); | 
| 1462 |     QCOMPARE(me2.keyToValue("MyAnotherEnum3" , &ok), -1); | 
| 1463 |     QCOMPARE(ok, true); | 
| 1464 |     QCOMPARE(me2.keyToValue("MyAnotherEnum" , &ok), -1); | 
| 1465 |     QCOMPARE(ok, false); | 
| 1466 |  | 
| 1467 |     QMetaEnum mf = mo->enumerator(index: mo->indexOfEnumerator(name: "MyFlags" )); | 
| 1468 |     QVERIFY(mf.isValid()); | 
| 1469 |     QVERIFY(mf.isFlag()); | 
| 1470 |     QCOMPARE(QByteArray(mf.scope()), QByteArray("MyNamespace::"  + name)); | 
| 1471 |     QCOMPARE(mf.keysToValue("MyNamespace::"  + name + "::MyFlag2" , &ok), 2); | 
| 1472 |     QCOMPARE(ok, true); | 
| 1473 |     QCOMPARE(mf.keysToValue(name + "::MyFlag2" , &ok), -1); | 
| 1474 |     QCOMPARE(ok, false); | 
| 1475 |     QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2" , &ok), -1); | 
| 1476 |     QCOMPARE(ok, false); | 
| 1477 |     QCOMPARE(mf.keysToValue("MyFlag2" , &ok), 2); | 
| 1478 |     QCOMPARE(ok, true); | 
| 1479 |     QCOMPARE(mf.keysToValue("MyFlag" , &ok), -1); | 
| 1480 |     QCOMPARE(ok, false); | 
| 1481 |     QCOMPARE(QLatin1String(mf.valueToKey(2)), QLatin1String("MyFlag2" )); | 
| 1482 |     QCOMPARE(mf.keysToValue("MyNamespace::"  + name + "::MyFlag1|MyNamespace::"  + name + "::MyFlag2" , &ok), 3); | 
| 1483 |     QCOMPARE(ok, true); | 
| 1484 |     QCOMPARE(mf.keysToValue(name + "::MyFlag1|"  + name + "::MyFlag2" , &ok), -1); | 
| 1485 |     QCOMPARE(ok, false); | 
| 1486 |     QCOMPARE(mf.keysToValue("MyNamespace::MyFlag1|MyNamespace::MyFlag2" , &ok), -1); | 
| 1487 |     QCOMPARE(ok, false); | 
| 1488 |     QCOMPARE(mf.keysToValue("MyFlag1|MyFlag2" , &ok), 3); | 
| 1489 |     QCOMPARE(ok, true); | 
| 1490 |     QCOMPARE(mf.keysToValue("MyFlag2|MyFlag2" , &ok), 2); | 
| 1491 |     QCOMPARE(ok, true); | 
| 1492 |     QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::"  + name + "::MyFlag2" , &ok), 3); | 
| 1493 |     QCOMPARE(ok, true); | 
| 1494 |     QCOMPARE(mf.keysToValue("MyNamespace::"  + name + "::MyFlag2|MyNamespace::"  + name + "::MyFlag2" , &ok), 2); | 
| 1495 |     QCOMPARE(ok, true); | 
| 1496 |     QCOMPARE(QLatin1String(mf.valueToKeys(3)), QLatin1String("MyFlag1|MyFlag2" )); | 
| 1497 | } | 
| 1498 |  | 
| 1499 | void tst_QMetaObject::propertyNotify() | 
| 1500 | { | 
| 1501 |     const QMetaObject *mo = metaObject(); | 
| 1502 |  | 
| 1503 |     QMetaProperty prop = mo->property(index: mo->indexOfProperty(name: "value6" )); | 
| 1504 |     QVERIFY(prop.isValid()); | 
| 1505 |     QVERIFY(prop.hasNotifySignal()); | 
| 1506 |     QMetaMethod signal = prop.notifySignal(); | 
| 1507 |     QCOMPARE(signal.methodSignature(), QByteArray("value6Changed()" )); | 
| 1508 |  | 
| 1509 |     prop = mo->property(index: mo->indexOfProperty(name: "value7" )); | 
| 1510 |     QVERIFY(prop.isValid()); | 
| 1511 |     QVERIFY(prop.hasNotifySignal()); | 
| 1512 |     signal = prop.notifySignal(); | 
| 1513 |     QCOMPARE(signal.methodSignature(), QByteArray("value7Changed(QString)" )); | 
| 1514 |  | 
| 1515 |     prop = mo->property(index: mo->indexOfProperty(name: "value8" )); | 
| 1516 |     QVERIFY(prop.isValid()); | 
| 1517 |     QVERIFY(!prop.hasNotifySignal()); | 
| 1518 |     signal = prop.notifySignal(); | 
| 1519 |     QCOMPARE(signal.methodSignature(), QByteArray()); | 
| 1520 |  | 
| 1521 |     prop = mo->property(index: mo->indexOfProperty(name: "value" )); | 
| 1522 |     QVERIFY(prop.isValid()); | 
| 1523 |     QVERIFY(!prop.hasNotifySignal()); | 
| 1524 |     signal = prop.notifySignal(); | 
| 1525 |     QCOMPARE(signal.methodSignature(), QByteArray()); | 
| 1526 | } | 
| 1527 |  | 
| 1528 | void tst_QMetaObject::propertyConstant() | 
| 1529 | { | 
| 1530 |     const QMetaObject *mo = metaObject(); | 
| 1531 |  | 
| 1532 |     QMetaProperty prop = mo->property(index: mo->indexOfProperty(name: "value8" )); | 
| 1533 |     QVERIFY(prop.isValid()); | 
| 1534 |     QVERIFY(!prop.isConstant()); | 
| 1535 |  | 
| 1536 |     prop = mo->property(index: mo->indexOfProperty(name: "value9" )); | 
| 1537 |     QVERIFY(prop.isValid()); | 
| 1538 |     QVERIFY(prop.isConstant()); | 
| 1539 | } | 
| 1540 |  | 
| 1541 | void tst_QMetaObject::propertyFinal() | 
| 1542 | { | 
| 1543 |     const QMetaObject *mo = metaObject(); | 
| 1544 |  | 
| 1545 |     QMetaProperty prop = mo->property(index: mo->indexOfProperty(name: "value10" )); | 
| 1546 |     QVERIFY(prop.isValid()); | 
| 1547 |     QVERIFY(prop.isFinal()); | 
| 1548 |  | 
| 1549 |     prop = mo->property(index: mo->indexOfProperty(name: "value9" )); | 
| 1550 |     QVERIFY(prop.isValid()); | 
| 1551 |     QVERIFY(!prop.isFinal()); | 
| 1552 | } | 
| 1553 |  | 
| 1554 | class ClassInfoTestObjectA : public QObject | 
| 1555 | { | 
| 1556 |     Q_OBJECT | 
| 1557 |     Q_CLASSINFO("Author" , "Christopher Pike" ) | 
| 1558 | }; | 
| 1559 |  | 
| 1560 | class ClassInfoTestObjectB : public ClassInfoTestObjectA | 
| 1561 | { | 
| 1562 |     Q_OBJECT | 
| 1563 | }; | 
| 1564 |  | 
| 1565 | void tst_QMetaObject::classInfo() | 
| 1566 | { | 
| 1567 |     ClassInfoTestObjectB b; | 
| 1568 |     int index = b.metaObject()->indexOfClassInfo(name: "Author" ); | 
| 1569 |     QCOMPARE(index, 0); | 
| 1570 |     QVERIFY(index <= b.metaObject()->classInfoOffset()); | 
| 1571 |     QCOMPARE(QLatin1String(b.metaObject()->classInfo(index).value()), QLatin1String("Christopher Pike" )); | 
| 1572 | } | 
| 1573 |  | 
| 1574 | void tst_QMetaObject::metaMethod() | 
| 1575 | { | 
| 1576 |     QString str("foo" ); | 
| 1577 |     QString ret("bar" ); | 
| 1578 |     QMetaMethod method; | 
| 1579 |     QVERIFY(!method.invoke(this)); | 
| 1580 |     QVERIFY(!method.invoke(this, Q_ARG(QString, str))); | 
| 1581 |     QVERIFY(!method.invoke(this, Q_RETURN_ARG(QString, ret), Q_ARG(QString, str))); | 
| 1582 |     QCOMPARE(str, QString("foo" )); | 
| 1583 |     QCOMPARE(ret, QString("bar" )); | 
| 1584 |  | 
| 1585 |     QtTestObject obj; | 
| 1586 |     QString t1("1" ); QString t2("2" ); QString t3("3" ); QString t4("4" ); QString t5("5" ); | 
| 1587 |     QString t6("6" ); QString t7("7" ); QString t8("8" ); QString t9("9" ); QString t10("X" ); | 
| 1588 |  | 
| 1589 |     int index = QtTestObject::staticMetaObject.indexOfMethod(method: "sl5(QString,QString,QString,QString,QString)" ); | 
| 1590 |     QVERIFY(index > 0); | 
| 1591 |     method = QtTestObject::staticMetaObject.method(index); | 
| 1592 |     //wrong args | 
| 1593 |     QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1" ), Q_ARG(QString, "2" ), Q_ARG(QString, "3" ), Q_ARG(QString, "4" ))); | 
| 1594 |     //QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(QString, "5"), Q_ARG(QString, "6"))); | 
| 1595 |     //QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(int, 5))); | 
| 1596 |     QVERIFY(!method.invoke(&obj, Q_RETURN_ARG(QString, ret), Q_ARG(QString, "1" ), Q_ARG(QString, "2" ), Q_ARG(QString, "3" ), Q_ARG(QString, "4" ), Q_ARG(QString, "5" ))); | 
| 1597 |  | 
| 1598 |     //wrong object | 
| 1599 |     //QVERIFY(!method.invoke(this, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(QString, "5"))); | 
| 1600 |     QVERIFY(!method.invoke(0, Q_ARG(QString, "1" ), Q_ARG(QString, "2" ), Q_ARG(QString, "3" ), Q_ARG(QString, "4" ), Q_ARG(QString, "5" ))); | 
| 1601 |     QCOMPARE(ret, QString("bar" )); | 
| 1602 |     QCOMPARE(obj.slotResult, QString()); | 
| 1603 |  | 
| 1604 |     QVERIFY(method.invoke(&obj, Q_ARG(QString, "1" ), Q_ARG(QString, "2" ), Q_ARG(QString, "3" ), Q_ARG(QString, "4" ), Q_ARG(QString, "5" ))); | 
| 1605 |     QCOMPARE(obj.slotResult, QString("sl5:12345" )); | 
| 1606 |  | 
| 1607 |     index = QtTestObject::staticMetaObject.indexOfMethod(method: "sl13(QList<QString>)" ); | 
| 1608 |     QVERIFY(index > 0); | 
| 1609 |     QMetaMethod sl13 = QtTestObject::staticMetaObject.method(index); | 
| 1610 |     QList<QString> returnValue, argument; | 
| 1611 |     argument << QString("one" ) << QString("two" ) << QString("three" ); | 
| 1612 |     //wrong object | 
| 1613 |     //QVERIFY(!sl13.invoke(this, Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument))); | 
| 1614 |     QVERIFY(!sl13.invoke(0,  Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument))); | 
| 1615 |     QVERIFY(returnValue.isEmpty()); | 
| 1616 |  | 
| 1617 |     QVERIFY(sl13.invoke(&obj, Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument))); | 
| 1618 |     QCOMPARE(returnValue, argument); | 
| 1619 |     QCOMPARE(obj.slotResult, QString("sl13" )); | 
| 1620 | } | 
| 1621 |  | 
| 1622 | void tst_QMetaObject::indexOfMethod_data() | 
| 1623 | { | 
| 1624 |     QTest::addColumn<QObject *>(name: "object" ); | 
| 1625 |     QTest::addColumn<QByteArray>(name: "name" ); | 
| 1626 |     QTest::addColumn<bool>(name: "isSignal" ); | 
| 1627 |     QTest::newRow(dataTag: "indexOfMethod_data" ) << (QObject*)this << QByteArray("indexOfMethod_data()" ) << false; | 
| 1628 |     QTest::newRow(dataTag: "deleteLater" ) << (QObject*)this << QByteArray("deleteLater()" ) << false; | 
| 1629 |     QTest::newRow(dataTag: "value6changed" ) << (QObject*)this << QByteArray("value6Changed()" ) << true; | 
| 1630 |     QTest::newRow(dataTag: "value7changed" ) << (QObject*)this << QByteArray("value7Changed(QString)" ) << true; | 
| 1631 |     QTest::newRow(dataTag: "destroyed" ) << (QObject*)this << QByteArray("destroyed()" ) << true; | 
| 1632 |     QTest::newRow(dataTag: "destroyed2" ) << (QObject*)this << QByteArray("destroyed(QObject*)" ) << true; | 
| 1633 | } | 
| 1634 |  | 
| 1635 | void tst_QMetaObject::indexOfMethod() | 
| 1636 | { | 
| 1637 |     QFETCH(QObject *, object); | 
| 1638 |     QFETCH(QByteArray, name); | 
| 1639 |     QFETCH(bool, isSignal); | 
| 1640 |     int idx = object->metaObject()->indexOfMethod(method: name); | 
| 1641 |     QVERIFY(idx >= 0); | 
| 1642 |     QCOMPARE(object->metaObject()->method(idx).methodSignature(), name); | 
| 1643 |     QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx); | 
| 1644 |     QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx); | 
| 1645 | } | 
| 1646 |  | 
| 1647 | void tst_QMetaObject::indexOfMethodPMF() | 
| 1648 | { | 
| 1649 | #define INDEXOFMETHODPMF_HELPER(ObjectType, Name, Arguments)  { \ | 
| 1650 |         int idx = -1; \ | 
| 1651 |         void (ObjectType::*signal)Arguments = &ObjectType::Name; \ | 
| 1652 |         void *signal_p = &signal; \ | 
| 1653 |         void *args[] = { &idx, signal_p, 0}; \ | 
| 1654 |         ObjectType::qt_static_metacall(0, QMetaObject::IndexOfMethod, 0, args); \ | 
| 1655 |         QCOMPARE(ObjectType::staticMetaObject.indexOfMethod(QMetaObject::normalizedSignature(#Name #Arguments)), \ | 
| 1656 |                  ObjectType::staticMetaObject.methodOffset() + idx); \ | 
| 1657 |     } | 
| 1658 |  | 
| 1659 |     INDEXOFMETHODPMF_HELPER(tst_QMetaObject, value7Changed, (const QString&)) | 
| 1660 |     INDEXOFMETHODPMF_HELPER(QtTestObject, sig0, ()) | 
| 1661 |     INDEXOFMETHODPMF_HELPER(QtTestObject, sig10, (QString,QString,QString,QString,QString,QString,QString,QString,QString,QString)) | 
| 1662 |     INDEXOFMETHODPMF_HELPER(QtTestCustomObject, sig_custom, (const CustomString &)) | 
| 1663 | } | 
| 1664 |  | 
| 1665 | namespace SignalTestHelper | 
| 1666 | { | 
| 1667 | // These functions use the public QMetaObject/QMetaMethod API to implement | 
| 1668 | // the functionality of the internal API, and are used to check the results. | 
| 1669 |  | 
| 1670 | static int signalCount(const QMetaObject *mo) | 
| 1671 | { | 
| 1672 |     int n = 0; | 
| 1673 |     for (int i = 0; i < mo->methodCount(); ++i) { | 
| 1674 |         QMetaMethod mm = mo->method(index: i); | 
| 1675 |         if (mm.methodType() == QMetaMethod::Signal) | 
| 1676 |             ++n; | 
| 1677 |     } | 
| 1678 |     return n; | 
| 1679 | } | 
| 1680 |  | 
| 1681 | static int signalOffset(const QMetaObject *mo) | 
| 1682 | { | 
| 1683 |     return mo->superClass() ? signalCount(mo: mo->superClass()) : 0; | 
| 1684 | } | 
| 1685 |  | 
| 1686 | static QMetaMethod signal(const QMetaObject *mo, int index) | 
| 1687 | { | 
| 1688 |     int k = 0; | 
| 1689 |     for (int i = 0; i < mo->methodCount(); ++i) { | 
| 1690 |         QMetaMethod mm = mo->method(index: i); | 
| 1691 |         if (mm.methodType() != QMetaMethod::Signal) | 
| 1692 |             continue; | 
| 1693 |         if (k == index) | 
| 1694 |             return mm; | 
| 1695 |         ++k; | 
| 1696 |     } | 
| 1697 |     return QMetaMethod(); | 
| 1698 | } | 
| 1699 |  | 
| 1700 | static int signalIndex(const QMetaMethod &mm) | 
| 1701 | { | 
| 1702 |     int k = mm.methodIndex(); | 
| 1703 |     const QMetaObject *mo = mm.enclosingMetaObject(); | 
| 1704 |     for (int i = 0; i < mm.methodIndex(); ++i) { | 
| 1705 |         if (mo->method(index: i).methodType() != QMetaMethod::Signal) | 
| 1706 |             --k; | 
| 1707 |     } | 
| 1708 |     return k; | 
| 1709 | } | 
| 1710 |  | 
| 1711 | } // namespace SignalTestHelper | 
| 1712 |  | 
| 1713 | void tst_QMetaObject::signalOffset_data() | 
| 1714 | { | 
| 1715 |     QTest::addColumn<const QMetaObject *>(name: "metaObject" ); | 
| 1716 |  | 
| 1717 |     QTest::newRow(dataTag: "QObject" ) << &QObject::staticMetaObject; | 
| 1718 |     QTest::newRow(dataTag: "tst_QMetaObject" ) << &tst_QMetaObject::staticMetaObject; | 
| 1719 |     QTest::newRow(dataTag: "QtTestObject" ) << &QtTestObject::staticMetaObject; | 
| 1720 | } | 
| 1721 |  | 
| 1722 | void tst_QMetaObject::signalOffset() | 
| 1723 | { | 
| 1724 |     QFETCH(const QMetaObject *, metaObject); | 
| 1725 |     QCOMPARE(QMetaObjectPrivate::signalOffset(metaObject), | 
| 1726 |              SignalTestHelper::signalOffset(metaObject)); | 
| 1727 | } | 
| 1728 |  | 
| 1729 | void tst_QMetaObject::signalCount_data() | 
| 1730 | { | 
| 1731 |     signalOffset_data(); | 
| 1732 | } | 
| 1733 |  | 
| 1734 | void tst_QMetaObject::signalCount() | 
| 1735 | { | 
| 1736 |     QFETCH(const QMetaObject *, metaObject); | 
| 1737 |     QCOMPARE(QMetaObjectPrivate::absoluteSignalCount(metaObject), | 
| 1738 |              SignalTestHelper::signalCount(metaObject)); | 
| 1739 | } | 
| 1740 |  | 
| 1741 | void tst_QMetaObject::signal_data() | 
| 1742 | { | 
| 1743 |     QTest::addColumn<const QMetaObject *>(name: "metaObject" ); | 
| 1744 |     QTest::addColumn<int>(name: "index" ); | 
| 1745 |  | 
| 1746 |     struct SignalTestDataHelper | 
| 1747 |     { | 
| 1748 |         static void addSignals(const QMetaObject *mo) | 
| 1749 |         { | 
| 1750 |             int count = SignalTestHelper::signalCount(mo); | 
| 1751 |             for (int i = 0; i < count; ++i) { | 
| 1752 |                 QMetaMethod mm = SignalTestHelper::signal(mo, index: i); | 
| 1753 |                 QByteArray tag(mo->className()); | 
| 1754 |                 tag.append(s: "::" ); | 
| 1755 |                 tag.append(a: mm.methodSignature()); | 
| 1756 |                 QTest::newRow(dataTag: tag.constData()) << mo << i; | 
| 1757 |             } | 
| 1758 |         } | 
| 1759 |     }; | 
| 1760 |  | 
| 1761 |     SignalTestDataHelper::addSignals(mo: &QObject::staticMetaObject); | 
| 1762 |     SignalTestDataHelper::addSignals(mo: &tst_QMetaObject::staticMetaObject); | 
| 1763 |     SignalTestDataHelper::addSignals(mo: &QtTestObject::staticMetaObject); | 
| 1764 | } | 
| 1765 |  | 
| 1766 | void tst_QMetaObject::signal() | 
| 1767 | { | 
| 1768 |     QFETCH(const QMetaObject *, metaObject); | 
| 1769 |     QFETCH(int, index); | 
| 1770 |  | 
| 1771 |     QCOMPARE(QMetaObjectPrivate::signal(metaObject, index), | 
| 1772 |              SignalTestHelper::signal(metaObject, index)); | 
| 1773 | } | 
| 1774 |  | 
| 1775 | void tst_QMetaObject::signalIndex_data() | 
| 1776 | { | 
| 1777 |     signal_data(); | 
| 1778 | } | 
| 1779 |  | 
| 1780 | void tst_QMetaObject::signalIndex() | 
| 1781 | { | 
| 1782 |     QFETCH(const QMetaObject *, metaObject); | 
| 1783 |     QFETCH(int, index); | 
| 1784 |  | 
| 1785 |     QMetaMethod mm = SignalTestHelper::signal(mo: metaObject, index); | 
| 1786 |     QCOMPARE(QMetaObjectPrivate::signalIndex(mm), | 
| 1787 |              SignalTestHelper::signalIndex(mm)); | 
| 1788 | } | 
| 1789 |  | 
| 1790 | void tst_QMetaObject::enumDebugStream_data() | 
| 1791 | { | 
| 1792 |     QTest::addColumn<int>(name: "verbosity" ); | 
| 1793 |     QTest::addColumn<QString>(name: "normalEnumMsg" ); | 
| 1794 |     QTest::addColumn<QString>(name: "scopedEnumMsg" ); | 
| 1795 |     QTest::addColumn<QString>(name: "globalEnumMsg" ); | 
| 1796 |     QTest::addColumn<QString>(name: "normalFlagMsg" ); | 
| 1797 |     QTest::addColumn<QString>(name: "normalFlagsMsg" ); | 
| 1798 |     QTest::addColumn<QString>(name: "scopedFlagMsg" ); | 
| 1799 |     QTest::addColumn<QString>(name: "scopedFlagsMsg" ); | 
| 1800 |     QTest::addColumn<QString>(name: "flagAsEnumMsg" ); | 
| 1801 |  | 
| 1802 |     QTest::newRow(dataTag: "verbosity=0" ) << 0 | 
| 1803 |         << "hello MyEnum2 world"  | 
| 1804 |         << "hello MyScopedEnum::Enum3 scoped world"  | 
| 1805 |         << "WindowTitleHint Window Desktop WindowSystemMenuHint"  | 
| 1806 |         << "hello MyFlag1 world"  | 
| 1807 |         << "MyFlag1 MyFlag2|MyFlag3"  | 
| 1808 |         << "MyScopedFlag(MyFlag2)"  | 
| 1809 |         << "MyScopedFlag(MyFlag2|MyFlag3)"  | 
| 1810 |         << "MyFlag1" ; | 
| 1811 |  | 
| 1812 |     QTest::newRow(dataTag: "verbosity=1" ) << 1 | 
| 1813 |         << "hello MyEnum::MyEnum2 world"  | 
| 1814 |         << "hello MyScopedEnum::Enum3 scoped world"  | 
| 1815 |         << "WindowType::WindowTitleHint WindowType::Window WindowType::Desktop WindowType::WindowSystemMenuHint"  | 
| 1816 |         << "hello MyFlag(MyFlag1) world"  | 
| 1817 |         << "MyFlag(MyFlag1) MyFlag(MyFlag2|MyFlag3)"  | 
| 1818 |         << "MyScopedFlag(MyFlag2)"  | 
| 1819 |         << "MyScopedFlag(MyFlag2|MyFlag3)"  | 
| 1820 |         << "MyFlag::MyFlag1" ; | 
| 1821 |  | 
| 1822 |     QTest::newRow(dataTag: "verbosity=2" ) << 2 | 
| 1823 |         << "hello MyNamespace::MyClass::MyEnum2 world"  | 
| 1824 |         << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world"  | 
| 1825 |         << "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"  | 
| 1826 |         << "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world"  | 
| 1827 |         << "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)"  | 
| 1828 |         << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)"  | 
| 1829 |         << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)"  | 
| 1830 |         << "MyNamespace::MyClass::MyFlag1" ; | 
| 1831 |  | 
| 1832 |     QTest::newRow(dataTag: "verbosity=3" ) << 3 | 
| 1833 |         << "hello MyNamespace::MyClass::MyEnum::MyEnum2 world"  | 
| 1834 |         << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world"  | 
| 1835 |         << "Qt::WindowType::WindowTitleHint Qt::WindowType::Window Qt::WindowType::Desktop Qt::WindowType::WindowSystemMenuHint"  | 
| 1836 |         << "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world"  | 
| 1837 |         << "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)"  | 
| 1838 |         << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)"  | 
| 1839 |         << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)"  | 
| 1840 |         << "MyNamespace::MyClass::MyFlag::MyFlag1" ; | 
| 1841 | } | 
| 1842 |  | 
| 1843 | void tst_QMetaObject::enumDebugStream() | 
| 1844 | { | 
| 1845 |     QFETCH(int, verbosity); | 
| 1846 |  | 
| 1847 |     QFETCH(QString, normalEnumMsg); | 
| 1848 |     QFETCH(QString, scopedEnumMsg); | 
| 1849 |     QFETCH(QString, globalEnumMsg); | 
| 1850 |  | 
| 1851 |     QFETCH(QString, normalFlagMsg); | 
| 1852 |     QFETCH(QString, normalFlagsMsg); | 
| 1853 |     QFETCH(QString, scopedFlagMsg); | 
| 1854 |     QFETCH(QString, scopedFlagsMsg); | 
| 1855 |     QFETCH(QString, flagAsEnumMsg); | 
| 1856 |  | 
| 1857 |     // Enums | 
| 1858 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(normalEnumMsg)); | 
| 1859 |     qDebug().verbosity(verbosityLevel: verbosity) << "hello"  << MyNamespace::MyClass::MyEnum2 << "world" ; | 
| 1860 |  | 
| 1861 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(scopedEnumMsg)); | 
| 1862 |     qDebug().verbosity(verbosityLevel: verbosity) << "hello"  << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world" ; | 
| 1863 |  | 
| 1864 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(globalEnumMsg)); | 
| 1865 |     qDebug().verbosity(verbosityLevel: verbosity) << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint; | 
| 1866 |  | 
| 1867 |     // Flags | 
| 1868 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(normalFlagMsg)); | 
| 1869 |     MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1; | 
| 1870 |     qDebug().verbosity(verbosityLevel: verbosity) << "hello"  << f1 << "world" ; | 
| 1871 |  | 
| 1872 |     MyNamespace::MyClass::MyFlags f2 = MyNamespace::MyClass::MyFlag2 | MyNamespace::MyClass::MyFlag3; | 
| 1873 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(normalFlagsMsg)); | 
| 1874 |     qDebug().verbosity(verbosityLevel: verbosity) << f1 << f2; | 
| 1875 |  | 
| 1876 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(scopedFlagMsg)); | 
| 1877 |     MyNamespace::MyClass::MyScopedFlags f3 = MyNamespace::MyClass::MyScopedFlag::MyFlag2; | 
| 1878 |     qDebug().verbosity(verbosityLevel: verbosity) << f3; | 
| 1879 |  | 
| 1880 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(scopedFlagsMsg)); | 
| 1881 |     f3 |= MyNamespace::MyClass::MyScopedFlag::MyFlag3; | 
| 1882 |     qDebug().verbosity(verbosityLevel: verbosity) << f3; | 
| 1883 |  | 
| 1884 |     // Single flag recognized as enum: | 
| 1885 |     QTest::ignoreMessage(type: QtDebugMsg, qPrintable(flagAsEnumMsg)); | 
| 1886 |     MyNamespace::MyClass::MyFlag f4 = MyNamespace::MyClass::MyFlag1; | 
| 1887 |     qDebug().verbosity(verbosityLevel: verbosity) << f4; | 
| 1888 | } | 
| 1889 |  | 
| 1890 | void tst_QMetaObject::inherits_data() | 
| 1891 | { | 
| 1892 |     QTest::addColumn<const QMetaObject *>(name: "derivedMetaObject" ); | 
| 1893 |     QTest::addColumn<const QMetaObject *>(name: "baseMetaObject" ); | 
| 1894 |     QTest::addColumn<bool>(name: "inheritsResult" ); | 
| 1895 |  | 
| 1896 |     QTest::newRow(dataTag: "MyClass inherits QObject" ) | 
| 1897 |         << &MyNamespace::MyClass::staticMetaObject << &QObject::staticMetaObject << true; | 
| 1898 |     QTest::newRow(dataTag: "QObject inherits MyClass" ) | 
| 1899 |         << &QObject::staticMetaObject << &MyNamespace::MyClass::staticMetaObject << false; | 
| 1900 |     QTest::newRow(dataTag: "MyClass inherits MyClass" ) | 
| 1901 |         << &MyNamespace::MyClass::staticMetaObject << &MyNamespace::MyClass::staticMetaObject << true; | 
| 1902 |     QTest::newRow(dataTag: "MyClassSubclass inherits QObject" ) | 
| 1903 |         << &MyNamespace::MyClassSubclass::staticMetaObject << &QObject::staticMetaObject << true; | 
| 1904 |     QTest::newRow(dataTag: "MyClassSubclass2 inherits QObject" ) | 
| 1905 |         << &MyNamespace::MyClassSubclass2::staticMetaObject << &QObject::staticMetaObject << true; | 
| 1906 |     QTest::newRow(dataTag: "MyClassSubclass2 inherits MyClass2" ) | 
| 1907 |         << &MyNamespace::MyClassSubclass2::staticMetaObject << &MyNamespace::MyClass2Subclass::staticMetaObject << false; | 
| 1908 | } | 
| 1909 |  | 
| 1910 | void tst_QMetaObject::inherits() | 
| 1911 | { | 
| 1912 |     QFETCH(const QMetaObject *, derivedMetaObject); | 
| 1913 |     QFETCH(const QMetaObject *, baseMetaObject); | 
| 1914 |     QFETCH(bool, inheritsResult); | 
| 1915 |  | 
| 1916 |     QCOMPARE(derivedMetaObject->inherits(baseMetaObject), inheritsResult); | 
| 1917 | } | 
| 1918 |  | 
| 1919 | void tst_QMetaObject::notifySignalsInParentClass() | 
| 1920 | { | 
| 1921 |     MyNamespace::ClassWithSetterGetterSignalsAddsProperties obj; | 
| 1922 |     QCOMPARE(obj.metaObject()->property(obj.metaObject()->indexOfProperty("value1" )).notifySignal().name(), QByteArray("value1Changed" )); | 
| 1923 |     QCOMPARE(obj.metaObject()->property(obj.metaObject()->indexOfProperty("value2" )).notifySignal().name(), QByteArray("value2Changed" )); | 
| 1924 |  | 
| 1925 |     MyNamespace::ClassWithChangedSignalNewValue obj2; | 
| 1926 |     QCOMPARE(obj2.metaObject()->property(obj2.metaObject()->indexOfProperty("value2" )).notifySignal().name(), QByteArray("propertiesChanged" )); | 
| 1927 |  | 
| 1928 |     QTest::ignoreMessage(type: QtWarningMsg, message: "QMetaProperty::notifySignal: cannot find the NOTIFY signal thisIsNotASignal in class MyNamespace::ClassWithChangedSignalNewValue for property 'value3'" ); | 
| 1929 |     obj2.metaObject()->property(index: obj2.metaObject()->indexOfProperty(name: "value3" )).notifySignal(); | 
| 1930 | } | 
| 1931 |  | 
| 1932 | QTEST_MAIN(tst_QMetaObject) | 
| 1933 | #include "tst_qmetaobject.moc" | 
| 1934 |  |