From e121d6d7e82067c557bcd2f5f3aed1e6ebc9d3fc Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 4 Feb 2012 22:51:41 +0100 Subject: [PATCH] Test template-based connect() with qmetaobjectbuilder For template-based connect(), the meta-object is resolved at compile-time (the virtual metaObject() function isn't called). But we can make it work by copying the members of the dynamically constructed meta-object to the statically defined one. Change-Id: Ia4d3263a89008e36e187c584db6d25d9042f32b3 Reviewed-by: Olivier Goffart Reviewed-by: Bradley T. Hughes --- .../tst_qmetaobjectbuilder.cpp | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 02c69b9b1b..97b14a374e 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1341,11 +1341,11 @@ class TestObject : public QObject // Manually expanded from Q_OBJECT macro public: Q_OBJECT_CHECK + static QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); private: - Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData; Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); //Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged) @@ -1378,14 +1378,15 @@ private: int m_voidSlotIntArg; }; -const QMetaObjectExtraData TestObject::staticMetaObjectExtraData = { - 0, qt_static_metacall +QMetaObject TestObject::staticMetaObject = { + { 0, 0, 0, 0 } }; TestObject::TestObject(QObject *parent) : QObject(parent), m_metaObject(buildMetaObject()), m_intProp(-1), m_voidSlotIntArg(-1) { + staticMetaObject = *m_metaObject; } TestObject::~TestObject() @@ -1481,9 +1482,6 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, } } } else if (_c == QMetaObject::IndexOfMethod) { - // This code is currently unreachable because it's only used by the - // template-based versions of connect() and disconnect(), which don't - // work with dynamically generated meta-objects (see test). int *result = reinterpret_cast(_a[0]); void **func = reinterpret_cast(_a[1]); { @@ -1504,7 +1502,6 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, *result = 2; } } - qFatal("You forgot to add one or more IndexOfMethod cases"); } } @@ -1668,11 +1665,22 @@ void tst_QMetaObjectBuilder::usage_templateConnect() { QScopedPointer testObject(new TestObject); - QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in QObject"); QMetaObject::Connection con = QObject::connect(testObject.data(), &TestObject::intPropChanged, testObject.data(), &TestObject::voidSlotInt); - QEXPECT_FAIL("", "template-based connect() fails because meta-object is deduced at compile-time", Abort); QVERIFY(con); + + QVERIFY(testObject->voidSlotIntArgument() == -1); + testObject->setProperty("intProp", 123); + QCOMPARE(testObject->voidSlotIntArgument(), 123); + + QVERIFY(QObject::disconnect(testObject.data(), &TestObject::intPropChanged, + testObject.data(), &TestObject::voidSlotInt)); + + // Something that isn't a signal + QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in TestObject"); + con = QObject::connect(testObject.data(), &TestObject::setIntProp, + testObject.data(), &TestObject::intPropChanged); + QVERIFY(!con); } QTEST_MAIN(tst_QMetaObjectBuilder)