diff options
Diffstat (limited to 'tests/auto/qobject/tst_qobject.cpp')
-rw-r--r-- | tests/auto/qobject/tst_qobject.cpp | 4063 |
1 files changed, 0 insertions, 4063 deletions
diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp deleted file mode 100644 index 3cd4376d80..0000000000 --- a/tests/auto/qobject/tst_qobject.cpp +++ /dev/null @@ -1,4063 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtTest/QtTest> - -#include <qcoreapplication.h> - -#include <qpointer.h> -#include <qtimer.h> -#include <qregexp.h> -#include <qmetaobject.h> -#include <qvariant.h> - -#include <QTcpServer> -#include <QTcpSocket> -#include <QThread> -#include <QMutex> -#include <QWaitCondition> -#include <QProcess> - -#include "qobject.h" -#ifdef QT_BUILD_INTERNAL -#include <private/qobject_p.h> -#endif - - -#include <math.h> - -//TESTED_CLASS= -//TESTED_FILES= - -class tst_QObject : public QObject -{ - Q_OBJECT - -public: - tst_QObject(); - virtual ~tst_QObject(); - - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); -private slots: - void disconnect(); - void connectByName(); - void connectSignalsToSignalsWithDefaultArguments(); - void receivers(); - void normalize(); - void qobject_castTemplate(); - void findChildren(); - void connectDisconnectNotify_data(); - void connectDisconnectNotify(); - void emitInDefinedOrder(); - void customTypes(); - void streamCustomTypes(); - void metamethod(); - void namespaces(); - void threadSignalEmissionCrash(); - void thread(); - void thread0(); - void moveToThread(); - void sender(); - void declareInterface(); - void qpointerResetBeforeDestroyedSignal(); - void testUserData(); - void childDeletesItsSibling(); - void dynamicProperties(); - void floatProperty(); - void qrealProperty(); - void property(); - void recursiveSignalEmission(); - void blockingQueuedConnection(); - void compatibilityChildInsertedEvents(); - void installEventFilter(); - void deleteSelfInSlot(); - void disconnectSelfInSlotAndDeleteAfterEmit(); - void dumpObjectInfo(); - void connectToSender(); - void qobjectConstCast(); - void uniqConnection(); - void interfaceIid(); - void deleteQObjectWhenDeletingEvent(); - void overloads(); - void isSignalConnected(); - void qMetaObjectConnect(); - void qMetaObjectDisconnectOne(); - void sameName(); - void connectByMetaMethods(); - void connectByMetaMethodSlotInsteadOfSignal(); - void connectConstructorByMetaMethod(); - void disconnectByMetaMethod(); - void disconnectNotSignalMetaMethod(); - void autoConnectionBehavior(); - void baseDestroyed(); -protected: -}; - -tst_QObject::tst_QObject() -{ - -} - -tst_QObject::~tst_QObject() -{ - -} - -void tst_QObject::initTestCase() -{ -} - -void tst_QObject::cleanupTestCase() -{ -} - -void tst_QObject::init() -{ -} - -void tst_QObject::cleanup() -{ -} - -class SenderObject : public QObject -{ - Q_OBJECT - -public: - SenderObject() : aPublicSlotCalled(0), recursionCount(0) {} - - void emitSignal1AfterRecursion() - { - if (recursionCount++ < 100) - emitSignal1AfterRecursion(); - else - emitSignal1(); - } - - void emitSignal1() { emit signal1(); } - void emitSignal2() { emit signal2(); } - void emitSignal3() { emit signal3(); } - void emitSignal4() { emit signal4(); } - -signals: - void signal1(); - void signal2(); - void signal3(); - void signal4(); - QT_MOC_COMPAT void signal5(); - -public slots: - void aPublicSlot() { aPublicSlotCalled++; } - -public: - Q_INVOKABLE void invoke1(){} - Q_SCRIPTABLE void sinvoke1(){} - int aPublicSlotCalled; -protected: - Q_INVOKABLE QT_MOC_COMPAT void invoke2(){} - Q_INVOKABLE QT_MOC_COMPAT void invoke2(int){} - Q_SCRIPTABLE QT_MOC_COMPAT void sinvoke2(){} -private: - Q_INVOKABLE void invoke3(int hinz = 0, int kunz = 0){Q_UNUSED(hinz) Q_UNUSED(kunz)} - Q_SCRIPTABLE void sinvoke3(){} - - int recursionCount; -}; - -class ReceiverObject : public QObject -{ - Q_OBJECT - -public: - ReceiverObject() : sequence_slot1( 0 ), - sequence_slot2( 0 ), - sequence_slot3( 0 ), - sequence_slot4( 0 ) {} - - void reset() { - sequence_slot4 = 0; - sequence_slot3 = 0; - sequence_slot2 = 0; - sequence_slot1 = 0; - count_slot1 = 0; - count_slot2 = 0; - count_slot3 = 0; - count_slot4 = 0; - } - - int sequence_slot1; - int sequence_slot2; - int sequence_slot3; - int sequence_slot4; - int count_slot1; - int count_slot2; - int count_slot3; - int count_slot4; - - bool called(int slot) { - switch (slot) { - case 1: return sequence_slot1; - case 2: return sequence_slot2; - case 3: return sequence_slot3; - case 4: return sequence_slot4; - default: return false; - } - } - - static int sequence; - -public slots: - void slot1() { sequence_slot1 = ++sequence; count_slot1++; } - void slot2() { sequence_slot2 = ++sequence; count_slot2++; } - void slot3() { sequence_slot3 = ++sequence; count_slot3++; } - void slot4() { sequence_slot4 = ++sequence; count_slot4++; } - -}; - -int ReceiverObject::sequence = 0; - -void tst_QObject::disconnect() -{ - SenderObject *s = new SenderObject; - ReceiverObject *r1 = new ReceiverObject; - ReceiverObject *r2 = new ReceiverObject; - - connect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) ); - - connect( s, SIGNAL( signal2() ), r1, SLOT( slot2() ) ); - connect( s, SIGNAL( signal3() ), r1, SLOT( slot3() ) ); - connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) ); - - s->emitSignal1(); - s->emitSignal2(); - s->emitSignal3(); - s->emitSignal4(); - - QCOMPARE( r1->called(1), TRUE ); - QCOMPARE( r1->called(2), TRUE ); - QCOMPARE( r1->called(3), TRUE ); - QCOMPARE( r1->called(4), TRUE ); - r1->reset(); - - // usual disconnect with all parameters given - bool ret = QObject::disconnect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) ); - - s->emitSignal1(); - - QCOMPARE( r1->called(1), FALSE ); - r1->reset(); - - QCOMPARE( ret, TRUE ); - ret = QObject::disconnect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) ); - QCOMPARE( ret, FALSE ); - - // disconnect all signals from s from all slots from r1 - QObject::disconnect( s, 0, r1, 0 ); - - s->emitSignal2(); - s->emitSignal3(); - s->emitSignal4(); - - QCOMPARE( r1->called(2), FALSE ); - QCOMPARE( r1->called(3), FALSE ); - QCOMPARE( r1->called(4), FALSE ); - r1->reset(); - - connect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) ); - connect( s, SIGNAL( signal1() ), r1, SLOT( slot2() ) ); - connect( s, SIGNAL( signal1() ), r1, SLOT( slot3() ) ); - connect( s, SIGNAL( signal2() ), r1, SLOT( slot4() ) ); - - // disconnect s's signal1() from all slots of r1 - QObject::disconnect( s, SIGNAL( signal1() ), r1, 0 ); - - s->emitSignal1(); - s->emitSignal2(); - - QCOMPARE( r1->called(1), FALSE ); - QCOMPARE( r1->called(2), FALSE ); - QCOMPARE( r1->called(3), FALSE ); - QCOMPARE( r1->called(4), TRUE ); - r1->reset(); - // make sure all is disconnected again - QObject::disconnect( s, 0, r1, 0 ); - - connect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) ); - connect( s, SIGNAL( signal1() ), r2, SLOT( slot1() ) ); - connect( s, SIGNAL( signal2() ), r1, SLOT( slot2() ) ); - connect( s, SIGNAL( signal2() ), r2, SLOT( slot2() ) ); - connect( s, SIGNAL( signal3() ), r1, SLOT( slot3() ) ); - connect( s, SIGNAL( signal3() ), r2, SLOT( slot3() ) ); - - // disconnect signal1() from all receivers - QObject::disconnect( s, SIGNAL( signal1() ), 0, 0 ); - s->emitSignal1(); - s->emitSignal2(); - s->emitSignal3(); - - QCOMPARE( r1->called(1), FALSE ); - QCOMPARE( r2->called(1), FALSE ); - QCOMPARE( r1->called(2), TRUE ); - QCOMPARE( r2->called(2), TRUE ); - QCOMPARE( r1->called(2), TRUE ); - QCOMPARE( r2->called(2), TRUE ); - - r1->reset(); - r2->reset(); - - // disconnect all signals of s from all receivers - QObject::disconnect( s, 0, 0, 0 ); - - QCOMPARE( r1->called(2), FALSE ); - QCOMPARE( r2->called(2), FALSE ); - QCOMPARE( r1->called(2), FALSE ); - QCOMPARE( r2->called(2), FALSE ); - - delete r2; - delete r1; - delete s; -} - -class AutoConnectSender : public QObject -{ - Q_OBJECT - -public: - AutoConnectSender(QObject *parent) - : QObject(parent) - {} - - void emitSignalNoParams() { emit signalNoParams(); } - void emitSignalWithParams(int i) { emit signalWithParams(i); } - void emitSignalWithParams(int i, QString string) { emit signalWithParams(i, string); } - void emitSignalManyParams(int i1, int i2, int i3, QString string, bool onoff) { emit signalManyParams(i1, i2, i3, string, onoff); } - void emitSignalManyParams2(int i1, int i2, int i3, QString string, bool onoff) { emit signalManyParams2(i1, i2, i3, string, onoff); } - void emitSignalLoopBack() { emit signalLoopBack(); } - -signals: - void signalNoParams(); - void signalWithParams(int i); - void signalWithParams(int i, QString string); - void signalManyParams(int i1, int i2, int i3, QString string, bool onoff); - void signalManyParams(int i1, int i2, int i3, QString string, bool onoff, bool); - void signalManyParams2(int i1, int i2, int i3, QString string, bool onoff); - void signalLoopBack(); -}; - -class AutoConnectReceiver : public QObject -{ - Q_OBJECT - -public: - AutoConnectReceiver() - { - reset(); - - connect(this, SIGNAL(on_Sender_signalLoopBack()), this, SLOT(slotLoopBack())); - } - - void reset() { - called_slot10 = 0; - called_slot9 = 0; - called_slot8 = 0; - called_slot7 = 0; - called_slot6 = 0; - called_slot5 = 0; - called_slot4 = 0; - called_slot3 = 0; - called_slot2 = 0; - called_slot1 = 0; - } - - int called_slot1; - int called_slot2; - int called_slot3; - int called_slot4; - int called_slot5; - int called_slot6; - int called_slot7; - int called_slot8; - int called_slot9; - int called_slot10; - - bool called(int slot) { - switch (slot) { - case 1: return called_slot1; - case 2: return called_slot2; - case 3: return called_slot3; - case 4: return called_slot4; - case 5: return called_slot5; - case 6: return called_slot6; - case 7: return called_slot7; - case 8: return called_slot8; - case 9: return called_slot9; - case 10: return called_slot10; - default: return false; - } - } - -public slots: - void on_Sender_signalNoParams() { ++called_slot1; } - void on_Sender_signalWithParams(int i = 0) { ++called_slot2; Q_UNUSED(i); } - void on_Sender_signalWithParams(int i, QString string) { ++called_slot3; Q_UNUSED(i);Q_UNUSED(string); } - void on_Sender_signalManyParams() { ++called_slot4; } - void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff) { ++called_slot5; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } - void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff, bool dummy) - { ++called_slot6; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); Q_UNUSED(dummy);} - void on_Sender_signalManyParams2(int i1, int i2, int i3, QString string, bool onoff) - { ++called_slot7; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } - void slotLoopBack() { ++called_slot8; } - -protected slots: - void o() { ++called_slot9; } - void on() { ++called_slot10; } - -signals: - void on_Sender_signalLoopBack(); -}; - -void tst_QObject::connectByName() -{ - AutoConnectReceiver receiver; - AutoConnectSender sender(&receiver); - sender.setObjectName("Sender"); - - QMetaObject::connectSlotsByName(&receiver); - - sender.emitSignalNoParams(); - QCOMPARE(receiver.called(1), true); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); - - sender.emitSignalWithParams(0); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), true); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); - - sender.emitSignalWithParams(0, "string"); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), true); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); - - sender.emitSignalManyParams(1, 2, 3, "string", true); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), true); - QCOMPARE(receiver.called(5), true); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); - - sender.emitSignalManyParams2(1, 2, 3, "string", true); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), true); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); - - sender.emitSignalLoopBack(); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), true); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); -} - -void tst_QObject::qobject_castTemplate() -{ - QObject *o = 0; - QVERIFY( !::qobject_cast<QObject*>(o) ); - - o = new SenderObject; - QVERIFY( ::qobject_cast<SenderObject*>(o) ); - QVERIFY( ::qobject_cast<QObject*>(o) ); - QVERIFY( !::qobject_cast<ReceiverObject*>(o) ); - delete o; -} - -void tst_QObject::findChildren() -{ - QObject o; - QObject o1(&o); - QObject o2(&o); - QObject o11(&o1); - QObject o12(&o1); - QObject o111(&o11); - QObject unnamed(&o); - QTimer t1(&o); - QTimer t121(&o12); - QTimer emptyname(&o); - - o.setObjectName("o"); - o1.setObjectName("o1"); - o2.setObjectName("o2"); - o11.setObjectName("o11"); - o12.setObjectName("o12"); - o111.setObjectName("o111"); - t1.setObjectName("t1"); - t121.setObjectName("t121"); - emptyname.setObjectName(""); - - QObject *op = 0; - - op = qFindChild<QObject*>(&o, "o1"); - QCOMPARE(op, &o1); - op = qFindChild<QObject*>(&o, "o2"); - QCOMPARE(op, &o2); - op = qFindChild<QObject*>(&o, "o11"); - QCOMPARE(op, &o11); - op = qFindChild<QObject*>(&o, "o12"); - QCOMPARE(op, &o12); - op = qFindChild<QObject*>(&o, "o111"); - QCOMPARE(op, &o111); - op = qFindChild<QObject*>(&o, "t1"); - QCOMPARE(op, static_cast<QObject *>(&t1)); - op = qFindChild<QObject*>(&o, "t121"); - QCOMPARE(op, static_cast<QObject *>(&t121)); - op = qFindChild<QTimer*>(&o, "t1"); - QCOMPARE(op, static_cast<QObject *>(&t1)); - op = qFindChild<QTimer*>(&o, "t121"); - QCOMPARE(op, static_cast<QObject *>(&t121)); - op = qFindChild<QTimer*>(&o, "o12"); - QCOMPARE(op, static_cast<QObject *>(0)); - op = qFindChild<QObject*>(&o, "o"); - QCOMPARE(op, static_cast<QObject *>(0)); - op = qFindChild<QObject*>(&o, "harry"); - QCOMPARE(op, static_cast<QObject *>(0)); - op = qFindChild<QObject*>(&o, "o1"); - QCOMPARE(op, &o1); - - QList<QObject*> l; - QList<QTimer*> tl; - - l = qFindChildren<QObject*>(&o, "o1"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o1); - l = qFindChildren<QObject*>(&o, "o2"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o2); - l = qFindChildren<QObject*>(&o, "o11"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o11); - l = qFindChildren<QObject*>(&o, "o12"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o12); - l = qFindChildren<QObject*>(&o, "o111"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o111); - l = qFindChildren<QObject*>(&o, "t1"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), static_cast<QObject *>(&t1)); - l = qFindChildren<QObject*>(&o, "t121"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), static_cast<QObject *>(&t121)); - tl = qFindChildren<QTimer*>(&o, "t1"); - QCOMPARE(tl.size(), 1); - QCOMPARE(tl.at(0), &t1); - tl = qFindChildren<QTimer*>(&o, "t121"); - QCOMPARE(tl.size(), 1); - QCOMPARE(tl.at(0), &t121); - l = qFindChildren<QObject*>(&o, "o"); - QCOMPARE(l.size(), 0); - l = qFindChildren<QObject*>(&o, "harry"); - QCOMPARE(l.size(), 0); - tl = qFindChildren<QTimer*>(&o, "o12"); - QCOMPARE(tl.size(), 0); - l = qFindChildren<QObject*>(&o, "o1"); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o1); - - l = qFindChildren<QObject*>(&o, QRegExp("o.*")); - QCOMPARE(l.size(), 5); - QVERIFY(l.contains(&o1)); - QVERIFY(l.contains(&o2)); - QVERIFY(l.contains(&o11)); - QVERIFY(l.contains(&o12)); - QVERIFY(l.contains(&o111)); - l = qFindChildren<QObject*>(&o, QRegExp("t.*")); - QCOMPARE(l.size(), 2); - QVERIFY(l.contains(&t1)); - QVERIFY(l.contains(&t121)); - tl = qFindChildren<QTimer*>(&o, QRegExp(".*")); - QCOMPARE(tl.size(), 3); - QVERIFY(tl.contains(&t1)); - QVERIFY(tl.contains(&t121)); - tl = qFindChildren<QTimer*>(&o, QRegExp("o.*")); - QCOMPARE(tl.size(), 0); - l = qFindChildren<QObject*>(&o, QRegExp("harry")); - QCOMPARE(l.size(), 0); - - // empty and null string check - op = qFindChild<QObject*>(&o); - QCOMPARE(op, &o1); - op = qFindChild<QObject*>(&o, ""); - QCOMPARE(op, &unnamed); - op = qFindChild<QObject*>(&o, "unnamed"); - QCOMPARE(op, static_cast<QObject *>(0)); - - l = qFindChildren<QObject*>(&o); - QCOMPARE(l.size(), 9); - l = qFindChildren<QObject*>(&o, ""); - QCOMPARE(l.size(), 2); - l = qFindChildren<QObject*>(&o, "unnamed"); - QCOMPARE(l.size(), 0); - - tl = o.findChildren<QTimer *>("t1"); - QCOMPARE(tl.size(), 1); - QCOMPARE(tl.at(0), &t1); - - // Find direct child/children - - op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly); - QCOMPARE(op, &o1); - op = o.findChild<QObject*>("o2", Qt::FindDirectChildrenOnly); - QCOMPARE(op, &o2); - op = o.findChild<QObject*>("o11", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("o12", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("o111", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("t1", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(&t1)); - op = o.findChild<QObject*>("t121", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QTimer*>("t1", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(&t1)); - op = o.findChild<QTimer*>("t121", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QTimer*>("o12", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("o", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("harry", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly); - QCOMPARE(op, &o1); - - l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o1); - l = o.findChildren<QObject*>("o2", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o2); - l = o.findChildren<QObject*>("o11", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - l = o.findChildren<QObject*>("o12", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - l = o.findChildren<QObject*>("o111", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - l = o.findChildren<QObject*>("t1", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), static_cast<QObject *>(&t1)); - l = o.findChildren<QObject*>("t121", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - tl = o.findChildren<QTimer*>("t1", Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 1); - QCOMPARE(tl.at(0), &t1); - tl = o.findChildren<QTimer*>("t121", Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 0); - l = o.findChildren<QObject*>("o", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - l = o.findChildren<QObject*>("harry", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - tl = o.findChildren<QTimer*>("o12", Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 0); - l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 1); - QCOMPARE(l.at(0), &o1); - - l = o.findChildren<QObject*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 2); - QVERIFY(l.contains(&o1)); - QVERIFY(l.contains(&o2)); - l = o.findChildren<QObject*>(QRegExp("t.*"), Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 1); - QVERIFY(l.contains(&t1)); - tl = o.findChildren<QTimer*>(QRegExp(".*"), Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 2); - QVERIFY(tl.contains(&t1)); - tl = o.findChildren<QTimer*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 0); - l = o.findChildren<QObject*>(QRegExp("harry"), Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - - // empty and null string check - op = o.findChild<QObject*>(QString(), Qt::FindDirectChildrenOnly); - QCOMPARE(op, &o1); - op = o.findChild<QObject*>("", Qt::FindDirectChildrenOnly); - QCOMPARE(op, &unnamed); - op = o.findChild<QObject*>("unnamed", Qt::FindDirectChildrenOnly); - QCOMPARE(op, static_cast<QObject *>(0)); - - l = o.findChildren<QObject*>(QString(), Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 5); - l = o.findChildren<QObject*>("", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 2); - l = o.findChildren<QObject*>("unnamed", Qt::FindDirectChildrenOnly); - QCOMPARE(l.size(), 0); - - tl = o.findChildren<QTimer *>("t1", Qt::FindDirectChildrenOnly); - QCOMPARE(tl.size(), 1); - QCOMPARE(tl.at(0), &t1); -} - - -class NotifyObject : public SenderObject, public ReceiverObject -{ -public: - NotifyObject() : SenderObject(), ReceiverObject() - {} - - QString org_signal; - QString nw_signal; - -protected: - void connectNotify( const char *signal ) - { - org_signal = signal; - nw_signal = QMetaObject::normalizedSignature(signal); - }; - void disconnectNotify( const char *signal ) - { - org_signal = signal; - nw_signal = QMetaObject::normalizedSignature(signal); - }; -}; - -void tst_QObject::connectDisconnectNotify_data() -{ - QTest::addColumn<QString>("a_signal"); - QTest::addColumn<QString>("a_slot"); - - QTest::newRow("combo1") << SIGNAL( signal1() ) << SLOT( slot1() ); - QTest::newRow("combo2") << SIGNAL( signal2(void) ) << SLOT( slot2( ) ); - QTest::newRow("combo3") << SIGNAL( signal3( ) ) << SLOT( slot3(void) ); - QTest::newRow("combo4") << SIGNAL( signal4( void ) )<< SLOT( slot4( void ) ); -} - -void tst_QObject::connectDisconnectNotify() -{ - NotifyObject *s = new NotifyObject; - NotifyObject *r = new NotifyObject; - - QFETCH(QString, a_signal); - QFETCH(QString, a_slot); - - // Test connectNotify - connect( (SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1() ); - QCOMPARE( s->org_signal, s->nw_signal ); - QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); - - // Test disconnectNotify - QObject::disconnect( (SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1() ); - QCOMPARE( s->org_signal, s->nw_signal ); - QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); - - // Reconnect - connect( (SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1() ); - // Test disconnectNotify for a complete disconnect - ((SenderObject*)s)->disconnect((ReceiverObject*)r); - - // Obtaining meta methods - int signalIndx = ((SenderObject*)s)->metaObject()->indexOfSignal( - QMetaObject::normalizedSignature(a_signal.toLatin1().constData()+1).constData()); - int methodIndx = ((ReceiverObject*)r)->metaObject()->indexOfMethod( - QMetaObject::normalizedSignature(a_slot.toLatin1().constData()+1).constData()); - QMetaMethod signal = ((SenderObject*)s)->metaObject()->method(signalIndx); - QMetaMethod method = ((ReceiverObject*)r)->metaObject()->method(methodIndx); - - // Test connectNotify when connecting by QMetaMethod - connect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); - QCOMPARE( s->org_signal, s->nw_signal ); - QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); - - // Test disconnectNotify when disconnecting by QMetaMethod - QObject::disconnect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); - QCOMPARE( s->org_signal, s->nw_signal ); - QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); - - delete s; - delete r; -} - -class SequenceObject : public ReceiverObject -{ - Q_OBJECT - -public: - QObject *next; - SequenceObject() : next(0) { } - -public slots: - void slot1_disconnectThis() - { - slot1(); - disconnect(sender(), SIGNAL(signal1()), this, SLOT(slot1_disconnectThis())); - } - - void slot2_reconnectThis() - { - slot2(); - - const QObject *s = sender(); - disconnect(s, SIGNAL(signal1()), this, SLOT(slot2_reconnectThis())); - connect(s, SIGNAL(signal1()), this, SLOT(slot2_reconnectThis())); - } - - void slot1_disconnectNext() - { - slot1(); - disconnect(sender(), SIGNAL(signal1()), next, SLOT(slot1())); - } - - void slot2_reconnectNext() - { - slot2(); - - // modify the connection list in 'this' - disconnect(sender(), SIGNAL(signal1()), next, SLOT(slot2())); - connect(sender(), SIGNAL(signal1()), next, SLOT(slot2())); - - // modify the sender list in 'this' - connect(next, SIGNAL(destroyed()), this, SLOT(deleteLater())); - connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(deleteLater())); - disconnect(next, SIGNAL(destroyed()), this, SLOT(deleteLater())); - disconnect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(deleteLater())); - } - - void slot1_deleteNext() - { - slot1(); - delete next; - } - - void slot2_deleteSender() - { - slot2(); - delete sender(); - } -}; - -void tst_QObject::emitInDefinedOrder() -{ - SenderObject sender; - ReceiverObject receiver1, receiver2, receiver3, receiver4; - - connect(&sender, SIGNAL(signal1()), &receiver1, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver2, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver3, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver4, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver1, SLOT(slot2())); - connect(&sender, SIGNAL(signal1()), &receiver2, SLOT(slot2())); - connect(&sender, SIGNAL(signal1()), &receiver3, SLOT(slot2())); - connect(&sender, SIGNAL(signal1()), &receiver4, SLOT(slot2())); - - int sequence; - ReceiverObject::sequence = sequence = 0; - sender.emitSignal1(); - QCOMPARE(receiver1.sequence_slot1, ++sequence); - QCOMPARE(receiver2.sequence_slot1, ++sequence); - QCOMPARE(receiver3.sequence_slot1, ++sequence); - QCOMPARE(receiver4.sequence_slot1, ++sequence); - QCOMPARE(receiver1.sequence_slot2, ++sequence); - QCOMPARE(receiver2.sequence_slot2, ++sequence); - QCOMPARE(receiver3.sequence_slot2, ++sequence); - QCOMPARE(receiver4.sequence_slot2, ++sequence); - - QObject::disconnect(&sender, SIGNAL(signal1()), &receiver2, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver2, SLOT(slot1())); - - ReceiverObject::sequence = sequence = 0; - sender.emitSignal1(); - QCOMPARE(receiver1.sequence_slot1, ++sequence); - QCOMPARE(receiver3.sequence_slot1, ++sequence); - QCOMPARE(receiver4.sequence_slot1, ++sequence); - QCOMPARE(receiver1.sequence_slot2, ++sequence); - QCOMPARE(receiver2.sequence_slot2, ++sequence); - QCOMPARE(receiver3.sequence_slot2, ++sequence); - QCOMPARE(receiver4.sequence_slot2, ++sequence); - QCOMPARE(receiver2.sequence_slot1, ++sequence); - - QObject::disconnect(&sender, SIGNAL(signal1()), &receiver1, SLOT(slot1())); - connect(&sender, SIGNAL(signal1()), &receiver1, SLOT(slot1())); - - ReceiverObject::sequence = sequence = 0; - sender.emitSignal1(); - QCOMPARE(receiver3.sequence_slot1, ++sequence); - QCOMPARE(receiver4.sequence_slot1, ++sequence); - QCOMPARE(receiver1.sequence_slot2, ++sequence); - QCOMPARE(receiver2.sequence_slot2, ++sequence); - QCOMPARE(receiver3.sequence_slot2, ++sequence); - QCOMPARE(receiver4.sequence_slot2, ++sequence); - QCOMPARE(receiver2.sequence_slot1, ++sequence); - QCOMPARE(receiver1.sequence_slot1, ++sequence); - - // ensure emission order even if the connections change during emission - SenderObject *sender2 = new SenderObject; - SequenceObject seq1, seq2, *seq3 = new SequenceObject, seq4; - seq1.next = &seq2; - seq2.next = seq3; - seq3->next = &seq4; - - // try 1 - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot1_disconnectThis())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot1_disconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot2_reconnectThis())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot2_reconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot2())); - - SequenceObject::sequence = sequence = 0; - sender2->emitSignal1(); - QCOMPARE(seq1.called(1), TRUE); - QCOMPARE(seq2.called(1), TRUE); - QCOMPARE(seq3->called(1), FALSE); - QCOMPARE(seq4.called(1), TRUE); - QCOMPARE(seq1.called(2), TRUE); - QCOMPARE(seq2.called(2), TRUE); - QCOMPARE(seq3->called(2), FALSE); - QCOMPARE(seq4.called(2), TRUE); - QCOMPARE(seq1.sequence_slot1, ++sequence); - QCOMPARE(seq2.sequence_slot1, ++sequence); - QCOMPARE(seq4.sequence_slot1, ++sequence); - QCOMPARE(seq1.sequence_slot2, ++sequence); - QCOMPARE(seq2.sequence_slot2, ++sequence); - QCOMPARE(seq4.sequence_slot2, ++sequence); - - QObject::disconnect(sender2, 0, &seq1, 0); - QObject::disconnect(sender2, 0, &seq2, 0); - QObject::disconnect(sender2, 0, seq3, 0); - QObject::disconnect(sender2, 0, &seq4, 0); - seq1.reset(); - seq2.reset(); - seq3->reset(); - seq4.reset(); - - // try 2 - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot2_reconnectThis())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot2_reconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot1_disconnectThis())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot1_disconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot1())); - - SequenceObject::sequence = sequence = 0; - sender2->emitSignal1(); - QCOMPARE(seq1.called(2), TRUE); - QCOMPARE(seq2.called(2), TRUE); - QCOMPARE(seq3->called(2), FALSE); - QCOMPARE(seq4.called(2), TRUE); - QCOMPARE(seq1.called(1), TRUE); - QCOMPARE(seq2.called(1), TRUE); - QCOMPARE(seq3->called(1), FALSE); - QCOMPARE(seq4.called(1), TRUE); - QCOMPARE(seq1.sequence_slot2, ++sequence); - QCOMPARE(seq2.sequence_slot2, ++sequence); - QCOMPARE(seq4.sequence_slot2, ++sequence); - QCOMPARE(seq1.sequence_slot1, ++sequence); - QCOMPARE(seq2.sequence_slot1, ++sequence); - QCOMPARE(seq4.sequence_slot1, ++sequence); - - QObject::disconnect(sender2, 0, &seq1, 0); - QObject::disconnect(sender2, 0, &seq2, 0); - QObject::disconnect(sender2, 0, seq3, 0); - QObject::disconnect(sender2, 0, &seq4, 0); - seq1.reset(); - seq2.reset(); - seq3->reset(); - seq4.reset(); - - // try 3 - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot1_disconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot2_reconnectNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot2())); - - SequenceObject::sequence = sequence = 0; - sender2->emitSignal1(); - QCOMPARE(seq1.called(1), TRUE); - QCOMPARE(seq2.called(1), TRUE); - QCOMPARE(seq3->called(1), FALSE); - QCOMPARE(seq4.called(1), TRUE); - QCOMPARE(seq1.called(2), TRUE); - QCOMPARE(seq2.called(2), TRUE); - QCOMPARE(seq3->called(2), FALSE); - QCOMPARE(seq4.called(2), TRUE); - QCOMPARE(seq1.sequence_slot1, ++sequence); - QCOMPARE(seq2.sequence_slot1, ++sequence); - QCOMPARE(seq4.sequence_slot1, ++sequence); - QCOMPARE(seq1.sequence_slot2, ++sequence); - QCOMPARE(seq2.sequence_slot2, ++sequence); - QCOMPARE(seq4.sequence_slot2, ++sequence); - - // ensure emission order even if objects are destroyed during emission - QObject::disconnect(sender2, 0, &seq1, 0); - QObject::disconnect(sender2, 0, &seq2, 0); - QObject::disconnect(sender2, 0, seq3, 0); - QObject::disconnect(sender2, 0, &seq4, 0); - seq1.reset(); - seq2.reset(); - seq3->reset(); - seq4.reset(); - - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot1_deleteNext())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot1())); - connect(sender2, SIGNAL(signal1()), &seq1, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq2, SLOT(slot2_deleteSender())); - connect(sender2, SIGNAL(signal1()), seq3, SLOT(slot2())); - connect(sender2, SIGNAL(signal1()), &seq4, SLOT(slot2())); - - QPointer<SenderObject> psender = sender2; - QPointer<SequenceObject> pseq3 = seq3; - - SequenceObject::sequence = sequence = 0; - sender2->emitSignal1(); - QCOMPARE(static_cast<QObject *>(psender), static_cast<QObject *>(0)); - QCOMPARE(static_cast<QObject *>(pseq3), static_cast<QObject *>(0)); - QCOMPARE(seq1.called(1), TRUE); - QCOMPARE(seq2.called(1), TRUE); - QCOMPARE(seq4.called(1), TRUE); - QCOMPARE(seq1.called(2), TRUE); - QCOMPARE(seq2.called(2), TRUE); - QCOMPARE(seq4.called(2), FALSE); - QCOMPARE(seq1.sequence_slot1, ++sequence); - QCOMPARE(seq2.sequence_slot1, ++sequence); - QCOMPARE(seq4.sequence_slot1, ++sequence); - QCOMPARE(seq1.sequence_slot2, ++sequence); - QCOMPARE(seq2.sequence_slot2, ++sequence); - - QPointer<SenderObject> psender3 = new SenderObject; - connect(psender3, SIGNAL(signal1()), psender3, SIGNAL(signal2())); - connect(psender3, SIGNAL(signal2()), &seq1, SLOT(slot2_deleteSender())); - psender3->emitSignal1(); - QVERIFY(!psender3); -} - -static int instanceCount = 0; - -struct CustomType -{ - CustomType(int l1 = 0, int l2 = 0, int l3 = 0): i1(l1), i2(l2), i3(l3) - { ++instanceCount; } - CustomType(const CustomType &other): i1(other.i1), i2(other.i2), i3(other.i3) - { ++instanceCount; } - ~CustomType() { --instanceCount; } - - int i1, i2, i3; - int value() { return i1 + i2 + i3; } -}; - -Q_DECLARE_METATYPE(CustomType*) - -class QCustomTypeChecker: public QObject -{ - Q_OBJECT - -public: - QCustomTypeChecker(QObject *parent = 0): QObject(parent) {} - void doEmit(CustomType ct) - { emit signal1(ct); } - -public slots: - void slot1(CustomType ct); - -signals: - void signal1(CustomType ct); - -public: - CustomType received; -}; - -void QCustomTypeChecker::slot1(CustomType ct) -{ received = ct; } - - -void tst_QObject::customTypes() -{ - CustomType t0; - CustomType t1(1, 2, 3); - CustomType t2(2, 3, 4); - - { - QCustomTypeChecker checker; - QCOMPARE(instanceCount, 4); - - connect(&checker, SIGNAL(signal1(CustomType)), &checker, SLOT(slot1(CustomType)), - Qt::DirectConnection); - QCOMPARE(checker.received.value(), 0); - checker.doEmit(t1); - QCOMPARE(checker.received.value(), t1.value()); - checker.received = t0; - - int idx = qRegisterMetaType<CustomType>("CustomType"); - QCOMPARE(QMetaType::type("CustomType"), idx); - - checker.disconnect(); - connect(&checker, SIGNAL(signal1(CustomType)), &checker, SLOT(slot1(CustomType)), - Qt::QueuedConnection); - QCOMPARE(instanceCount, 4); - checker.doEmit(t2); - QCOMPARE(instanceCount, 5); - QCOMPARE(checker.received.value(), t0.value()); - - QCoreApplication::processEvents(); - QCOMPARE(checker.received.value(), t2.value()); - QCOMPARE(instanceCount, 4); - - QVERIFY(QMetaType::isRegistered(idx)); - QCOMPARE(qRegisterMetaType<CustomType>("CustomType"), idx); - QCOMPARE(QMetaType::type("CustomType"), idx); - QVERIFY(QMetaType::isRegistered(idx)); - } - QCOMPARE(instanceCount, 3); -} - -QDataStream &operator<<(QDataStream &stream, const CustomType &ct) -{ - stream << ct.i1 << ct.i2 << ct.i3; - return stream; -} - -QDataStream &operator>>(QDataStream &stream, CustomType &ct) -{ - stream >> ct.i1; - stream >> ct.i2; - stream >> ct.i3; - return stream; -} - -void tst_QObject::streamCustomTypes() -{ - QByteArray ba; - - int idx = qRegisterMetaType<CustomType>("CustomType"); - qRegisterMetaTypeStreamOperators<CustomType>("CustomType"); - - { - CustomType t1(1, 2, 3); - QCOMPARE(instanceCount, 1); - QDataStream stream(&ba, (QIODevice::OpenMode)QIODevice::WriteOnly); - QMetaType::save(stream, idx, &t1); - } - - QCOMPARE(instanceCount, 0); - - { - CustomType t2; - QCOMPARE(instanceCount, 1); - QDataStream stream(&ba, (QIODevice::OpenMode)QIODevice::ReadOnly); - QMetaType::load(stream, idx, &t2); - QCOMPARE(instanceCount, 1); - QCOMPARE(t2.i1, 1); - QCOMPARE(t2.i2, 2); - QCOMPARE(t2.i3, 3); - } - QCOMPARE(instanceCount, 0); -} - -typedef QString CustomString; - -class PropertyObject : public QObject -{ - Q_OBJECT - Q_ENUMS(Alpha Priority) - - Q_PROPERTY(Alpha alpha READ alpha WRITE setAlpha) - Q_PROPERTY(Priority priority READ priority WRITE setPriority) - Q_PROPERTY(int number READ number WRITE setNumber) - Q_PROPERTY(QString string READ string WRITE setString) - Q_PROPERTY(QVariant variant READ variant WRITE setVariant) - Q_PROPERTY(CustomType* custom READ custom WRITE setCustom) - Q_PROPERTY(float myFloat READ myFloat WRITE setMyFloat) - Q_PROPERTY(qreal myQReal READ myQReal WRITE setMyQReal) - Q_PROPERTY(CustomString customString READ customString WRITE setCustomString ) - -public: - enum Alpha { - Alpha0, - Alpha1, - Alpha2 - }; - - enum Priority { High, Low, VeryHigh, VeryLow }; - - PropertyObject() - : m_alpha(Alpha0), m_priority(High), m_number(0), m_custom(0), m_float(42) - {} - - Alpha alpha() const { return m_alpha; } - void setAlpha(Alpha alpha) { m_alpha = alpha; } - - Priority priority() const { return m_priority; } - void setPriority(Priority priority) { m_priority = priority; } - - int number() const { return m_number; } - void setNumber(int number) { m_number = number; } - - QString string() const { return m_string; } - void setString(const QString &string) { m_string = string; } - - QVariant variant() const { return m_variant; } - void setVariant(const QVariant &variant) { m_variant = variant; } - - CustomType *custom() const { return m_custom; } - void setCustom(CustomType *custom) { m_custom = custom; } - - void setMyFloat(float value) { m_float = value; } - inline float myFloat() const { return m_float; } - - void setMyQReal(qreal value) { m_qreal = value; } - qreal myQReal() const { return m_qreal; } - - CustomString customString() const { return m_customString; } - void setCustomString(const QString &string) { m_customString = string; } - -private: - Alpha m_alpha; - Priority m_priority; - int m_number; - QString m_string; - QVariant m_variant; - CustomType *m_custom; - float m_float; - qreal m_qreal; - CustomString m_customString; -}; - -Q_DECLARE_METATYPE(PropertyObject::Priority) - -void tst_QObject::threadSignalEmissionCrash() -{ -#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) - int loopCount = 100; -#else - int loopCount = 1000; -#endif - for (int i = 0; i < loopCount; ++i) { - QTcpSocket socket; - socket.connectToHost("localhost", 80); - } -} - -class TestThread : public QThread -{ - Q_OBJECT -public: - inline void run() - { - *object = new QObject; - *child = new QObject(*object); - mutex.lock(); - cond.wakeOne(); - cond.wait(&mutex); - mutex.unlock(); - } - - QObject **object, **child; - QMutex mutex; - QWaitCondition cond; -}; - -void tst_QObject::thread() -{ - QThread *currentThread = QThread::currentThread(); - // the current thread is the same as the QApplication - // thread... see tst_QApplication::thread() - - { - QObject object; - // thread affinity for objects with no parent should be the - // current thread - QVERIFY(object.thread() != 0); - QCOMPARE(object.thread(), currentThread); - // children inherit their parent's thread - QObject child(&object); - QCOMPARE(child.thread(), object.thread()); - } - - QObject *object = 0; - QObject *child = 0; - - { - TestThread thr; - QVERIFY(thr.thread() != 0); - QCOMPARE(thr.thread(), currentThread); - - thr.object = &object; - thr.child = &child; - - thr.mutex.lock(); - thr.start(); - thr.cond.wait(&thr.mutex); - - // thread affinity for an object with no parent should be the - // thread in which the object was created - QCOMPARE(object->thread(), (QThread *)&thr); - // children inherit their parent's thread - QCOMPARE(child->thread(), object->thread()); - - thr.cond.wakeOne(); - thr.mutex.unlock(); - thr.wait(); - - // even though the thread is no longer running, the affinity - // should not change - QCOMPARE(object->thread(), (QThread *)&thr); - QCOMPARE(child->thread(), object->thread()); - } - - // the thread has been destroyed, thread affinity should - // automatically reset to no thread - QCOMPARE(object->thread(), (QThread *)0); - QCOMPARE(child->thread(), object->thread()); - - delete object; -} - -class MoveToThreadObject : public QObject -{ - Q_OBJECT -public: - QThread *timerEventThread; - QThread *customEventThread; - QThread *slotThread; - - MoveToThreadObject(QObject *parent = 0) - : QObject(parent), timerEventThread(0), customEventThread(0), slotThread(0) - { } - - void customEvent(QEvent *) - { - if (customEventThread) - qFatal("%s: customEventThread should be null", Q_FUNC_INFO); - customEventThread = QThread::currentThread(); - emit theSignal(); - } - - void timerEvent(QTimerEvent *) - { - if (timerEventThread) - qFatal("%s: timerEventThread should be null", Q_FUNC_INFO); - timerEventThread = QThread::currentThread(); - emit theSignal(); - } - -public slots: - void theSlot() - { - if (slotThread) - qFatal("%s: slotThread should be null", Q_FUNC_INFO); - slotThread = QThread::currentThread(); - emit theSignal(); - } - -signals: - void theSignal(); -}; - -class MoveToThreadThread : public QThread -{ -public: - ~MoveToThreadThread() - { - if (isRunning()) { - terminate(); - wait(); - } - } - void start() - { - QEventLoop eventLoop; - connect(this, SIGNAL(started()), &eventLoop, SLOT(quit()), Qt::QueuedConnection); - QThread::start(); - // wait for thread to start - (void) eventLoop.exec(); - } - void run() - { (void) exec(); } -}; - -void tst_QObject::thread0() -{ - QObject *object = new QObject; - object->moveToThread(0); - QObject *child = new QObject(object); - QCOMPARE(child->parent(), object); - QCOMPARE(child->thread(), (QThread *)0); - -#if 0 - // We don't support moving children into a parent that has no thread - // affinity (yet?). - QObject *child2 = new QObject; - child2->moveToThread(0); - child2->setParent(object); - QCOMPARE(child2->parent(), object); - QCOMPARE(child2->thread(), (QThread *)0); -#endif - - delete object; -} - -void tst_QObject::moveToThread() -{ - QThread *currentThread = QThread::currentThread(); - - { - QObject *object = new QObject; - QObject *child = new QObject(object); - QCOMPARE(object->thread(), currentThread); - QCOMPARE(child->thread(), currentThread); - object->moveToThread(0); - QCOMPARE(object->thread(), (QThread *)0); - QCOMPARE(child->thread(), (QThread *)0); - object->moveToThread(currentThread); - QCOMPARE(object->thread(), currentThread); - QCOMPARE(child->thread(), currentThread); - object->moveToThread(0); - QCOMPARE(object->thread(), (QThread *)0); - QCOMPARE(child->thread(), (QThread *)0); - // can delete an object with no thread anywhere - delete object; - } - - { - MoveToThreadThread thread; - thread.start(); - - QObject *object = new QObject; - QObject *child = new QObject(object); - QPointer<QObject> opointer = object; - QPointer<QObject> cpointer = object; - - QCOMPARE(object->thread(), currentThread); - QCOMPARE(child->thread(), currentThread); - object->moveToThread(&thread); - QCOMPARE(object->thread(), (QThread *)&thread); - QCOMPARE(child->thread(), (QThread *)&thread); - - connect(object, SIGNAL(destroyed()), &thread, SLOT(quit()), Qt::DirectConnection); - QMetaObject::invokeMethod(object, "deleteLater", Qt::QueuedConnection); - thread.wait(); - - QVERIFY(opointer == 0); - QVERIFY(cpointer == 0); - } - - { - // make sure posted events are moved with the object - MoveToThreadThread thread; - thread.start(); - - MoveToThreadObject *object = new MoveToThreadObject; - MoveToThreadObject *child = new MoveToThreadObject(object); - - connect(object, SIGNAL(theSignal()), &thread, SLOT(quit()), Qt::DirectConnection); - QCoreApplication::postEvent(child, new QEvent(QEvent::User)); - QCoreApplication::postEvent(object, new QEvent(QEvent::User)); - - QCOMPARE(object->thread(), currentThread); - QCOMPARE(child->thread(), currentThread); - object->moveToThread(&thread); - QCOMPARE(object->thread(), (QThread *)&thread); - QCOMPARE(child->thread(), (QThread *)&thread); - - thread.wait(); - - QCOMPARE(object->customEventThread, (QThread *)&thread); - QCOMPARE(child->customEventThread, (QThread *)&thread); - - thread.start(); - connect(object, SIGNAL(destroyed()), &thread, SLOT(quit()), Qt::DirectConnection); - QMetaObject::invokeMethod(object, "deleteLater", Qt::QueuedConnection); - thread.wait(); - } - - { - // make sure timers are moved with the object - MoveToThreadThread thread; - thread.start(); - - MoveToThreadObject *object = new MoveToThreadObject; - MoveToThreadObject *child = new MoveToThreadObject(object); - - connect(object, SIGNAL(theSignal()), &thread, SLOT(quit()), Qt::DirectConnection); - -#if defined(Q_OS_SYMBIAN) - // Child timer will be registered after parent timer in the new - // thread, and 10ms is less than symbian timer resolution, so - // child->timerEventThread compare after thread.wait() will - // usually fail unless timers are farther apart. - child->startTimer(100); - object->startTimer(150); -#else - child->startTimer(90); - object->startTimer(100); -#endif - - QCOMPARE(object->thread(), currentThread); - QCOMPARE(child->thread(), currentThread); - object->moveToThread(&thread); - QCOMPARE(object->thread(), (QThread *)&thread); - QCOMPARE(child->thread(), (QThread *)&thread); - - thread.wait(); - - QCOMPARE(object->timerEventThread, (QThread *)&thread); - QCOMPARE(child->timerEventThread, (QThread *)&thread); - - thread.start(); - connect(object, SIGNAL(destroyed()), &thread, SLOT(quit()), Qt::DirectConnection); - QMetaObject::invokeMethod(object, "deleteLater", Qt::QueuedConnection); - thread.wait(); - } - - { - // make sure socket notifiers are moved with the object - MoveToThreadThread thread; - thread.start(); - - QTcpServer server; - QVERIFY(server.listen(QHostAddress::LocalHost, 0)); - QTcpSocket *socket = new QTcpSocket; - MoveToThreadObject *child = new MoveToThreadObject(socket); - connect(socket, SIGNAL(disconnected()), child, SLOT(theSlot()), Qt::DirectConnection); - connect(child, SIGNAL(theSignal()), &thread, SLOT(quit()), Qt::DirectConnection); - - socket->connectToHost(server.serverAddress(), server.serverPort()); - - QVERIFY(server.waitForNewConnection(1000)); - QTcpSocket *serverSocket = server.nextPendingConnection(); - QVERIFY(serverSocket); - - socket->waitForConnected(); - - QCOMPARE(socket->thread(), currentThread); - socket->moveToThread(&thread); - QCOMPARE(socket->thread(), (QThread *)&thread); - - serverSocket->close(); - - QVERIFY(thread.wait(10000)); - - QCOMPARE(child->slotThread, (QThread *)&thread); - - thread.start(); - connect(socket, SIGNAL(destroyed()), &thread, SLOT(quit()), Qt::DirectConnection); - QMetaObject::invokeMethod(socket, "deleteLater", Qt::QueuedConnection); - thread.wait(); - } -} - - -void tst_QObject::property() -{ - PropertyObject object; - const QMetaObject *mo = object.metaObject(); - QMetaProperty property; - QVERIFY(mo); - - QVERIFY(mo->indexOfProperty("alpha") != -1); - property = mo->property(mo->indexOfProperty("alpha")); - QVERIFY(property.isEnumType()); - QCOMPARE(property.typeName(), "Alpha"); - QCOMPARE(property.type(), QVariant::Int); - - QVariant var = object.property("alpha"); - QVERIFY(!var.isNull()); - QCOMPARE(var.toInt(), int(PropertyObject::Alpha0)); - object.setAlpha(PropertyObject::Alpha1); - QCOMPARE(object.property("alpha").toInt(), int(PropertyObject::Alpha1)); - QVERIFY(object.setProperty("alpha", PropertyObject::Alpha2)); - QCOMPARE(object.property("alpha").toInt(), int(PropertyObject::Alpha2)); - QVERIFY(object.setProperty("alpha", "Alpha1")); - QCOMPARE(object.property("alpha").toInt(), int(PropertyObject::Alpha1)); - QVERIFY(!object.setProperty("alpha", QVariant())); - - QVERIFY(mo->indexOfProperty("number") != -1); - QCOMPARE(object.property("number").toInt(), 0); - object.setNumber(24); - QCOMPARE(object.property("number"), QVariant(24)); - QVERIFY(object.setProperty("number", 12)); - QCOMPARE(object.property("number"), QVariant(12)); - QVERIFY(object.setProperty("number", "42")); - QCOMPARE(object.property("number"), QVariant(42)); - - QVERIFY(mo->indexOfProperty("string") != -1); - QCOMPARE(object.property("string").toString(), QString()); - object.setString("String1"); - QCOMPARE(object.property("string"), QVariant("String1")); - QVERIFY(object.setProperty("string", "String2")); - QCOMPARE(object.property("string"), QVariant("String2")); - QVERIFY(!object.setProperty("string", QVariant())); - - const int idx = mo->indexOfProperty("variant"); - QVERIFY(idx != -1); - QVERIFY(mo->property(idx).type() == QVariant::LastType); - QCOMPARE(object.property("variant"), QVariant()); - QVariant variant1(42); - QVariant variant2("string"); - object.setVariant(variant1); - QCOMPARE(object.property("variant"), variant1); - QVERIFY(object.setProperty("variant", variant2)); - QCOMPARE(object.variant(), QVariant(variant2)); - QCOMPARE(object.property("variant"), variant2); - QVERIFY(object.setProperty("variant", QVariant())); - QCOMPARE(object.property("variant"), QVariant()); - - QVERIFY(mo->indexOfProperty("custom") != -1); - property = mo->property(mo->indexOfProperty("custom")); - QVERIFY(property.isValid()); - QVERIFY(property.isWritable()); - QVERIFY(!property.isEnumType()); - QCOMPARE(property.typeName(), "CustomType*"); - QCOMPARE(property.type(), QVariant::UserType); - - CustomType *customPointer = 0; - QVariant customVariant = object.property("custom"); - customPointer = qVariantValue<CustomType *>(customVariant); - QCOMPARE(customPointer, object.custom()); - - CustomType custom; - customPointer = &custom; - qVariantSetValue(customVariant, customPointer); - - property = mo->property(mo->indexOfProperty("custom")); - QVERIFY(property.isWritable()); - QCOMPARE(property.typeName(), "CustomType*"); - QCOMPARE(property.type(), QVariant::UserType); - - QVERIFY(object.setProperty("custom", customVariant)); - QCOMPARE(object.custom(), customPointer); - - customVariant = object.property("custom"); - customPointer = qVariantValue<CustomType *>(customVariant); - QCOMPARE(object.custom(), customPointer); - - // this enum property has a meta type, but it's not yet registered, so we know this fails - QVERIFY(mo->indexOfProperty("priority") != -1); - property = mo->property(mo->indexOfProperty("priority")); - QVERIFY(property.isEnumType()); - QCOMPARE(property.typeName(), "Priority"); - QCOMPARE(property.type(), QVariant::Int); - - var = object.property("priority"); - QVERIFY(!var.isNull()); - QCOMPARE(var.toInt(), int(PropertyObject::High)); - object.setPriority(PropertyObject::Low); - QCOMPARE(object.property("priority").toInt(), int(PropertyObject::Low)); - QVERIFY(object.setProperty("priority", PropertyObject::VeryHigh)); - QCOMPARE(object.property("priority").toInt(), int(PropertyObject::VeryHigh)); - QVERIFY(object.setProperty("priority", "High")); - QCOMPARE(object.property("priority").toInt(), int(PropertyObject::High)); - QVERIFY(!object.setProperty("priority", QVariant())); - - // now it's registered, so it works as expected - int priorityMetaTypeId = qRegisterMetaType<PropertyObject::Priority>("PropertyObject::Priority"); - - QVERIFY(mo->indexOfProperty("priority") != -1); - property = mo->property(mo->indexOfProperty("priority")); - QVERIFY(property.isEnumType()); - QCOMPARE(property.typeName(), "Priority"); - QCOMPARE(property.type(), QVariant::UserType); - QCOMPARE(property.userType(), priorityMetaTypeId); - - var = object.property("priority"); - QVERIFY(!var.isNull()); - QVERIFY(qVariantCanConvert<PropertyObject::Priority>(var)); - QCOMPARE(qVariantValue<PropertyObject::Priority>(var), PropertyObject::High); - object.setPriority(PropertyObject::Low); - QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::Low); - QVERIFY(object.setProperty("priority", PropertyObject::VeryHigh)); - QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::VeryHigh); - QVERIFY(object.setProperty("priority", "High")); - QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::High); - QVERIFY(!object.setProperty("priority", QVariant())); - - var = object.property("priority"); - QCOMPARE(qVariantValue<PropertyObject::Priority>(var), PropertyObject::High); - object.setPriority(PropertyObject::Low); - QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::Low); - object.setProperty("priority", var); - QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::High); - - qRegisterMetaType<CustomString>("CustomString"); - QVERIFY(mo->indexOfProperty("customString") != -1); - QCOMPARE(object.property("customString").toString(), QString()); - object.setCustomString("String1"); - QCOMPARE(object.property("customString"), QVariant("String1")); - QVERIFY(object.setProperty("customString", "String2")); - QCOMPARE(object.property("customString"), QVariant("String2")); - QVERIFY(!object.setProperty("customString", QVariant())); -} - -void tst_QObject::metamethod() -{ - SenderObject obj; - const QMetaObject *mobj = obj.metaObject(); - QMetaMethod m; - - m = mobj->method(mobj->indexOfMethod("invoke1()")); - QVERIFY(QByteArray(m.signature()) == "invoke1()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Public); - QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); - QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("sinvoke1()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke1()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Public); - QVERIFY((m.attributes() & QMetaMethod::Scriptable)); - QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("invoke2()")); - QVERIFY(QByteArray(m.signature()) == "invoke2()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Protected); - QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); - QVERIFY((m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("sinvoke2()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke2()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Protected); - QVERIFY((m.attributes() & QMetaMethod::Scriptable)); - QVERIFY((m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("invoke3()")); - QVERIFY(QByteArray(m.signature()) == "invoke3()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Private); - QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); - QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("sinvoke3()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke3()"); - QVERIFY(m.methodType() == QMetaMethod::Method); - QVERIFY(m.access() == QMetaMethod::Private); - QVERIFY((m.attributes() & QMetaMethod::Scriptable)); - QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("signal5()")); - QVERIFY(QByteArray(m.signature()) == "signal5()"); - QVERIFY(m.methodType() == QMetaMethod::Signal); - QVERIFY(m.access() == QMetaMethod::Protected); - QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); - QVERIFY((m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("aPublicSlot()")); - QVERIFY(QByteArray(m.signature()) == "aPublicSlot()"); - QVERIFY(m.methodType() == QMetaMethod::Slot); - QVERIFY(m.access() == QMetaMethod::Public); - QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); - QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); - - m = mobj->method(mobj->indexOfMethod("invoke1()")); - QCOMPARE(m.parameterNames().count(), 0); - QCOMPARE(m.parameterTypes().count(), 0); - - m = mobj->method(mobj->indexOfMethod("invoke2(int)")); - QCOMPARE(m.parameterNames().count(), 1); - QCOMPARE(m.parameterTypes().count(), 1); - QCOMPARE(m.parameterTypes().at(0), QByteArray("int")); - QVERIFY(m.parameterNames().at(0).isEmpty()); - - m = mobj->method(mobj->indexOfMethod("invoke3(int,int)")); - QCOMPARE(m.parameterNames().count(), 2); - QCOMPARE(m.parameterTypes().count(), 2); - QCOMPARE(m.parameterTypes().at(0), QByteArray("int")); - QCOMPARE(m.parameterNames().at(0), QByteArray("hinz")); - QCOMPARE(m.parameterTypes().at(1), QByteArray("int")); - QCOMPARE(m.parameterNames().at(1), QByteArray("kunz")); - -} - -namespace QObjectTest -{ - class TestObject: public QObject - { - Q_OBJECT - public: - TestObject(): QObject(), i(0) {} - void doEmit() { emit aSignal(); } - int i; - public slots: - void aSlot() { ++i; } - signals: - void aSignal(); - }; -} - -void tst_QObject::namespaces() -{ - QObjectTest::TestObject obj; - - QVERIFY(connect(&obj, SIGNAL(aSignal()), &obj, SLOT(aSlot()))); - obj.doEmit(); - QCOMPARE(obj.i, 1); -} - -class SuperObject : public QObject -{ - Q_OBJECT -public: - QObject *theSender; - int theSignalId; - - SuperObject() - { - theSender = 0; - theSignalId = 0; - } - - friend class tst_QObject; - - using QObject::sender; - -public slots: - void rememberSender() - { - theSender = sender(); - theSignalId = senderSignalIndex(); - } - - void deleteAndRememberSender() - { - delete theSender; - rememberSender(); - } -signals: - void anotherSignal(); - void theSignal(); -}; - -void tst_QObject::sender() -{ - { - SuperObject sender; - SuperObject receiver; - connect(&sender, SIGNAL(anotherSignal()), - &receiver, SLOT(rememberSender())); - connect(&sender, SIGNAL(theSignal()), - &receiver, SLOT(rememberSender())); - QCOMPARE(receiver.sender(), (QObject *)0); - QCOMPARE(receiver.senderSignalIndex(), -1); - emit sender.theSignal(); - QCOMPARE(receiver.theSender, (QObject *)&sender); - QCOMPARE(receiver.sender(), (QObject *)0); - QCOMPARE(receiver.theSignalId, - sender.metaObject()->indexOfSignal("theSignal()")); - QCOMPARE(receiver.senderSignalIndex(), -1); - - emit sender.anotherSignal(); - QCOMPARE(receiver.theSignalId, - sender.metaObject()->indexOfSignal("anotherSignal()")); - QCOMPARE(receiver.senderSignalIndex(), -1); - } - - { - SuperObject *sender = new SuperObject; - SuperObject *receiver = new SuperObject; - connect(sender, SIGNAL(theSignal()), - receiver, SLOT(rememberSender()), - Qt::BlockingQueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - connect(sender, SIGNAL(theSignal()), - &thread, SLOT(quit()), - Qt::DirectConnection); - - QCOMPARE(receiver->sender(), (QObject *)0); - QCOMPARE(receiver->senderSignalIndex(), -1); - receiver->theSender = 0; - receiver->theSignalId = -1; - thread.start(); - emit sender->theSignal(); - QCOMPARE(receiver->theSender, (QObject *) sender); - QCOMPARE(receiver->sender(), (QObject *)0); - QCOMPARE(receiver->theSignalId, - sender->metaObject()->indexOfSignal("theSignal()")); - QCOMPARE(receiver->senderSignalIndex(), -1); - - QVERIFY(thread.wait(10000)); - delete receiver; - delete sender; - } - - { - SuperObject *sender = new SuperObject; - SuperObject receiver; - connect(sender, SIGNAL(theSignal()), - &receiver, SLOT(deleteAndRememberSender())); - QCOMPARE(receiver.sender(), (QObject *)0); - receiver.theSender = sender; - emit sender->theSignal(); - QCOMPARE(receiver.theSender, (QObject *)0); - QCOMPARE(receiver.sender(), (QObject *)0); - } - - { - SuperObject *sender = new SuperObject; - SuperObject *receiver = new SuperObject; - connect(sender, SIGNAL(theSignal()), - receiver, SLOT(deleteAndRememberSender()), - Qt::BlockingQueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - connect(sender, SIGNAL(destroyed()), - &thread, SLOT(quit()), - Qt::DirectConnection); - - QCOMPARE(receiver->sender(), (QObject *)0); - receiver->theSender = sender; - thread.start(); - emit sender->theSignal(); - QCOMPARE(receiver->theSender, (QObject *)0); - QCOMPARE(receiver->sender(), (QObject *)0); - - QVERIFY(thread.wait(10000)); - delete receiver; - } -} - -namespace Foo -{ - struct Bar - { - virtual ~Bar() {} - virtual int rtti() const = 0; - }; - - struct Bleh - { - virtual ~Bleh() {} - virtual int rtti() const = 0; - }; -} - -QT_BEGIN_NAMESPACE -Q_DECLARE_INTERFACE(Foo::Bar, "com.qtest.foobar") -QT_END_NAMESPACE - -#define Bleh_iid "com.qtest.bleh" -QT_BEGIN_NAMESPACE -Q_DECLARE_INTERFACE(Foo::Bleh, Bleh_iid) -QT_END_NAMESPACE - -class FooObject: public QObject, public Foo::Bar -{ - Q_OBJECT - Q_INTERFACES(Foo::Bar) -public: - int rtti() const { return 42; } -}; - -class BlehObject : public QObject, public Foo::Bleh -{ - Q_OBJECT - Q_INTERFACES(Foo::Bleh) -public: - int rtti() const { return 43; } -}; - -void tst_QObject::declareInterface() -{ - FooObject obj; - - Foo::Bar *bar = qobject_cast<Foo::Bar *>(&obj); - QVERIFY(bar); - QCOMPARE(bar->rtti(), 42); - QCOMPARE(static_cast<Foo::Bar *>(&obj), bar); - - BlehObject bleh; - - bar = qobject_cast<Foo::Bar *>(&bleh); - QVERIFY(!bar); - Foo::Bleh *b = qobject_cast<Foo::Bleh *>(&bleh); - QCOMPARE(b->rtti(), 43); - QCOMPARE(static_cast<Foo::Bleh *>(&bleh), b); - -} - -class CustomData : public QObjectUserData -{ -public: - int id; -}; - -void tst_QObject::testUserData() -{ - const int USER_DATA_COUNT = 100; - int user_data_ids[USER_DATA_COUNT]; - - // Register a few - for (int i=0; i<USER_DATA_COUNT; ++i) { - user_data_ids[i] = QObject::registerUserData(); - } - - // Randomize the table a bit - for (int i=0; i<100; ++i) { - int p1 = rand() % USER_DATA_COUNT; - int p2 = rand() % USER_DATA_COUNT; - - int tmp = user_data_ids[p1]; - user_data_ids[p1] = user_data_ids[p2]; - user_data_ids[p2] = tmp; - } - - // insert the user data into an object - QObject my_test_object; - for (int i=0; i<USER_DATA_COUNT; ++i) { - CustomData *data = new CustomData; - data->id = user_data_ids[i]; - my_test_object.setUserData(data->id, data); - } - - // verify that all ids and positions are matching - for (int i=0; i<USER_DATA_COUNT; ++i) { - int id = user_data_ids[i]; - CustomData *data = static_cast<CustomData *>(my_test_object.userData(id)); - QVERIFY(data != 0); - QVERIFY(data->id == id); - } -} - -class DestroyedListener : public QObject -{ - Q_OBJECT -public: - inline DestroyedListener() : pointerWasZero(false) {} - - QPointer<QObject> pointer; - bool pointerWasZero; - -private slots: - inline void otherObjectDestroyed() - { pointerWasZero = pointer.isNull(); } -}; - -void tst_QObject::qpointerResetBeforeDestroyedSignal() -{ - QObject *obj = new QObject; - DestroyedListener listener; - listener.pointer = obj; - listener.pointerWasZero = false; - connect(obj, SIGNAL(destroyed()), &listener, SLOT(otherObjectDestroyed())); - delete obj; - QVERIFY(listener.pointerWasZero); - QVERIFY(listener.pointer.isNull()); -} - -class DefaultArguments : public QObject -{ - Q_OBJECT - -public slots: - - void theSlot(const QString &s) { result = s; } - -signals: - void theOriginalSignal(); - void theSecondSignal(const QString &s = QString("secondDefault")); - -public: - - void emitTheOriginalSignal() { emit theOriginalSignal(); } - void emitTheSecondSignal() { emit theSecondSignal(); } - QString result; -}; - -void tst_QObject::connectSignalsToSignalsWithDefaultArguments() -{ - DefaultArguments o; - connect(&o, SIGNAL(theOriginalSignal()), &o, SIGNAL(theSecondSignal())); - connect(&o, SIGNAL(theSecondSignal(QString)), &o, SLOT(theSlot(QString))); - QVERIFY( o.result.isEmpty() ); - o.emitTheSecondSignal(); - QCOMPARE(o.result, QString("secondDefault")); - o.result = "Not called"; - o.emitTheOriginalSignal(); - QCOMPARE(o.result, QString("secondDefault")); - -} - -void tst_QObject::receivers() -{ - class Object : public QObject - { - public: - int receivers(const char* signal) const - { return QObject::receivers(signal); } - }; - - Object object; - QCOMPARE(object.receivers(SIGNAL(destroyed())), 0); - object.connect(&object, SIGNAL(destroyed()), SLOT(deleteLater())); - QCOMPARE(object.receivers(SIGNAL(destroyed())), 1); - object.connect(&object, SIGNAL(destroyed()), SLOT(deleteLater())); - QCOMPARE(object.receivers(SIGNAL(destroyed())), 2); - object.disconnect(SIGNAL(destroyed()), &object, SLOT(deleteLater())); - QCOMPARE(object.receivers(SIGNAL(destroyed())), 0); -} - -enum Enum { }; - -struct Struct { }; -class Class { }; -template <typename T> class Template { }; - -class NormalizeObject : public QObject -{ - Q_OBJECT - -public: - -signals: - void uintPointerSignal(uint *); - void ulongPointerSignal(ulong *); - void constUintPointerSignal(const uint *); - void constUlongPointerSignal(const ulong *); - - void structSignal(Struct s); - void classSignal(Class c); - void enumSignal(Enum e); - - void structPointerSignal(Struct *s); - void classPointerSignal(Class *c); - void enumPointerSignal(Enum *e); - - void constStructPointerSignal(const Struct *s); - void constClassPointerSignal(const Class *c); - void constEnumPointerSignal(const Enum *e); - - void constStructPointerConstPointerSignal(const Struct * const *s); - void constClassPointerConstPointerSignal(const Class * const *c); - void constEnumPointerConstPointerSignal(const Enum * const *e); - - void unsignedintSignal(unsigned int); - void unsignedSignal(unsigned); - void unsignedlongSignal(unsigned long); - void unsignedlonglongSignal(quint64); - void unsignedlongintSignal(unsigned long int); - void unsignedshortSignal(unsigned short); - void unsignedcharSignal(unsigned char); - - void typeRefSignal(Template<Class &> &ref); - void constTypeRefSignal(const Template<Class const &> &ref); - void typeConstRefSignal(Template<Class const &> const &ref); - - void typePointerConstRefSignal(Class * const &); - - void constTemplateSignal1( Template<int > ); - void constTemplateSignal2( Template< const int >); - -public slots: - void uintPointerSlot(uint *) { } - void ulongPointerSlot(ulong *) { } - void constUintPointerSlot(const uint *) { } - void constUlongPointerSlot(const ulong *) { } - - void structSlot(Struct s) { Q_UNUSED(s); } - void classSlot(Class c) { Q_UNUSED(c); } - void enumSlot(Enum e) { Q_UNUSED(e); } - - void structPointerSlot(Struct *s) { Q_UNUSED(s); } - void classPointerSlot(Class *c) { Q_UNUSED(c); } - void enumPointerSlot(Enum *e) { Q_UNUSED(e); } - - void constStructPointerSlot(const Struct *s) { Q_UNUSED(s); } - void constClassPointerSlot(const Class *c) { Q_UNUSED(c); } - void constEnumPointerSlot(const Enum *e) { Q_UNUSED(e); } - - void constStructPointerConstPointerSlot(const Struct * const *s) { Q_UNUSED(s); } - void constClassPointerConstPointerSlot(const Class * const *c) { Q_UNUSED(c); } - void constEnumPointerConstPointerSlot(const Enum * const *e) { Q_UNUSED(e); } - - void uintSlot(uint) {}; - void unsignedintSlot(unsigned int) {}; - void unsignedSlot(unsigned) {}; - void unsignedlongSlot(unsigned long) {}; - void unsignedlonglongSlot(quint64) {}; - void unsignedlongintSlot(unsigned long int) {}; - void unsignedshortSlot(unsigned short) {}; - void unsignedcharSlot(unsigned char) {}; - - void typeRefSlot(Template<Class &> &) {} - void constTypeRefSlot(const Template<const Class &> &) {} - void typeConstRefSlot(Template<Class const &> const &) {} - - void typePointerConstRefSlot(Class * const &) {} - - void constTemplateSlot1(Template<int > const) {} - void constTemplateSlot2(const Template<int > ) {} - void constTemplateSlot3(const Template< const int >) {} -}; - -#include "oldnormalizeobject.h" - -void tst_QObject::normalize() -{ - NormalizeObject object; - - // unsigned int -> uint, unsigned long -> ulong - QVERIFY(object.connect(&object, - SIGNAL(uintPointerSignal(uint *)), - SLOT(uintPointerSlot(uint *)))); - QVERIFY(object.connect(&object, - SIGNAL(uintPointerSignal(unsigned int *)), - SLOT(uintPointerSlot(uint *)))); - QVERIFY(object.connect(&object, - SIGNAL(uintPointerSignal(uint *)), - SLOT(uintPointerSlot(unsigned int *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constUintPointerSignal(const uint *)), - SLOT(constUintPointerSlot(const uint *)))); - QVERIFY(object.connect(&object, - SIGNAL(constUintPointerSignal(const unsigned int *)), - SLOT(constUintPointerSlot(const uint *)))); - QVERIFY(object.connect(&object, - SIGNAL(constUintPointerSignal(const uint *)), - SLOT(constUintPointerSlot(const unsigned int *)))); - - QVERIFY(object.connect(&object, - SIGNAL(ulongPointerSignal(ulong *)), - SLOT(ulongPointerSlot(ulong *)))); - QVERIFY(object.connect(&object, - SIGNAL(ulongPointerSignal(unsigned long *)), - SLOT(ulongPointerSlot(ulong *)))); - QVERIFY(object.connect(&object, - SIGNAL(ulongPointerSignal(ulong *)), - SLOT(ulongPointerSlot(unsigned long *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constUlongPointerSignal(const ulong *)), - SLOT(constUlongPointerSlot(const ulong *)))); - QVERIFY(object.connect(&object, - SIGNAL(constUlongPointerSignal(const unsigned long *)), - SLOT(constUlongPointerSlot(const ulong *)))); - QVERIFY(object.connect(&object, - SIGNAL(constUlongPointerSignal(const ulong *)), - SLOT(constUlongPointerSlot(const unsigned long *)))); - - // struct, class, and enum are optional - QVERIFY(object.connect(&object, - SIGNAL(structSignal(struct Struct)), - SLOT(structSlot(struct Struct)))); - QVERIFY(object.connect(&object, - SIGNAL(structSignal(Struct)), - SLOT(structSlot(struct Struct)))); - QVERIFY(object.connect(&object, - SIGNAL(structSignal(struct Struct)), - SLOT(structSlot(Struct)))); - QVERIFY(object.connect(&object, - SIGNAL(classSignal(class Class)), - SLOT(classSlot(class Class)))); - QVERIFY(object.connect(&object, - SIGNAL(classSignal(Class)), - SLOT(classSlot(class Class)))); - QVERIFY(object.connect(&object, - SIGNAL(classSignal(class Class)), - SLOT(classSlot(Class)))); - QVERIFY(object.connect(&object, - SIGNAL(enumSignal(enum Enum)), - SLOT(enumSlot(enum Enum)))); - QVERIFY(object.connect(&object, - SIGNAL(enumSignal(Enum)), - SLOT(enumSlot(enum Enum)))); - QVERIFY(object.connect(&object, - SIGNAL(enumSignal(enum Enum)), - SLOT(enumSlot(Enum)))); - - QVERIFY(object.connect(&object, - SIGNAL(structPointerSignal(struct Struct *)), - SLOT(structPointerSlot(struct Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(structPointerSignal(Struct *)), - SLOT(structPointerSlot(struct Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(structPointerSignal(struct Struct *)), - SLOT(structPointerSlot(Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(classPointerSignal(class Class *)), - SLOT(classPointerSlot(class Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(classPointerSignal(Class *)), - SLOT(classPointerSlot(class Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(classPointerSignal(class Class *)), - SLOT(classPointerSlot(Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(enumPointerSignal(enum Enum *)), - SLOT(enumPointerSlot(enum Enum *)))); - QVERIFY(object.connect(&object, - SIGNAL(enumPointerSignal(Enum *)), - SLOT(enumPointerSlot(enum Enum *)))); - QVERIFY(object.connect(&object, - SIGNAL(enumPointerSignal(enum Enum *)), - SLOT(enumPointerSlot(Enum *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(const struct Struct *)), - SLOT(constStructPointerSlot(const struct Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(const Struct *)), - SLOT(constStructPointerSlot(const struct Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(const struct Struct *)), - SLOT(constStructPointerSlot(const Struct *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(const class Class *)), - SLOT(constClassPointerSlot(const class Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(const Class *)), - SLOT(constClassPointerSlot(const class Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(const class Class *)), - SLOT(constClassPointerSlot(const Class *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(const enum Enum *)), - SLOT(constEnumPointerSlot(const enum Enum *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(const Enum *)), - SLOT(constEnumPointerSlot(const enum Enum *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(const enum Enum *)), - SLOT(constEnumPointerSlot(const Enum *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(struct Struct const *)), - SLOT(constStructPointerSlot(struct Struct const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(Struct const *)), - SLOT(constStructPointerSlot(struct Struct const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerSignal(struct Struct const *)), - SLOT(constStructPointerSlot(Struct const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(class Class const *)), - SLOT(constClassPointerSlot(class Class const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(Class const *)), - SLOT(constClassPointerSlot(class Class const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerSignal(class Class const *)), - SLOT(constClassPointerSlot(Class const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(enum Enum const *)), - SLOT(constEnumPointerSlot(enum Enum const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(Enum const *)), - SLOT(constEnumPointerSlot(enum Enum const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerSignal(enum Enum const *)), - SLOT(constEnumPointerSlot(Enum const *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(const struct Struct * const *)), - SLOT(constStructPointerConstPointerSlot(const struct Struct * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(const Struct * const *)), - SLOT(constStructPointerConstPointerSlot(const struct Struct * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(const struct Struct * const *)), - SLOT(constStructPointerConstPointerSlot(const Struct * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(const class Class * const *)), - SLOT(constClassPointerConstPointerSlot(const class Class * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(const Class * const *)), - SLOT(constClassPointerConstPointerSlot(const class Class * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(const class Class * const *)), - SLOT(constClassPointerConstPointerSlot(const Class * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(const enum Enum * const *)), - SLOT(constEnumPointerConstPointerSlot(const enum Enum * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(const Enum * const *)), - SLOT(constEnumPointerConstPointerSlot(const enum Enum * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(const enum Enum * const *)), - SLOT(constEnumPointerConstPointerSlot(const Enum * const *)))); - - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(struct Struct const * const *)), - SLOT(constStructPointerConstPointerSlot(struct Struct const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(Struct const * const *)), - SLOT(constStructPointerConstPointerSlot(struct Struct const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constStructPointerConstPointerSignal(struct Struct const * const *)), - SLOT(constStructPointerConstPointerSlot(Struct const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(class Class const * const *)), - SLOT(constClassPointerConstPointerSlot(class Class const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(Class const * const *)), - SLOT(constClassPointerConstPointerSlot(class Class const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constClassPointerConstPointerSignal(class Class const * const *)), - SLOT(constClassPointerConstPointerSlot(Class const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(enum Enum const * const *)), - SLOT(constEnumPointerConstPointerSlot(enum Enum const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(Enum const * const *)), - SLOT(constEnumPointerConstPointerSlot(enum Enum const * const *)))); - QVERIFY(object.connect(&object, - SIGNAL(constEnumPointerConstPointerSignal(enum Enum const * const *)), - SLOT(constEnumPointerConstPointerSlot(Enum const * const *)))); - - QVERIFY(object.connect(&object, - SIGNAL(unsignedintSignal(unsigned int)), - SLOT(unsignedintSlot(unsigned int)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedSignal(unsigned)), - SLOT(unsignedSlot(unsigned)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedSignal(unsigned)), - SLOT(uintSlot(uint)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedlongSignal(unsigned long)), - SLOT(unsignedlongSlot(unsigned long)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedlonglongSignal(quint64)), - SLOT(unsignedlonglongSlot(quint64)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedlongintSignal(unsigned long int)), - SLOT(unsignedlongintSlot(unsigned long int)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedshortSignal(unsigned short)), - SLOT(unsignedshortSlot(unsigned short)))); - QVERIFY(object.connect(&object, - SIGNAL(unsignedcharSignal(unsigned char)), - SLOT(unsignedcharSlot(unsigned char)))); - - // connect when original template signature and mixed usage of 'T<C const &> const &', - // 'const T<const C &> &', and 'T<const C &>' - - QVERIFY(object.connect(&object, - SIGNAL(typeRefSignal(Template<Class &> &)), - SLOT(typeRefSlot(Template<Class &> &)))); - - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - - // same test again, this time with an object compiled with old moc output... we know that - // it is not possible to connect everything, whic is the purpose for this test - OldNormalizeObject oldobject; - - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - // these fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - - // these also fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - - QVERIFY(object.connect(&object, - SIGNAL(typePointerConstRefSignal(Class*const&)), - SLOT(typePointerConstRefSlot(Class*const&)))); - QVERIFY(object.connect(&object, - SIGNAL(typePointerConstRefSignal(Class*const&)), - SLOT(typePointerConstRefSlot(Class*)))); - QVERIFY(object.connect(&object, - SIGNAL(typePointerConstRefSignal(Class*)), - SLOT(typePointerConstRefSlot(Class*const&)))); - QVERIFY(object.connect(&object, - SIGNAL(typePointerConstRefSignal(Class*)), - SLOT(typePointerConstRefSlot(Class*)))); - - QVERIFY( connect(&object, SIGNAL(constTemplateSignal1(Template <int>)), - &object , SLOT(constTemplateSlot1 (Template<int > ) ) )); - QVERIFY( connect(&object, SIGNAL(constTemplateSignal1(Template <int>)), - &object , SLOT(constTemplateSlot2 (Template<int > ) ) )); - QVERIFY( connect(&object, SIGNAL(constTemplateSignal2(Template <const int>)), - &object , SLOT(constTemplateSlot3(Template<int const > ) ) )); - - //type does not match - QTest::ignoreMessage(QtWarningMsg, "QObject::connect: Incompatible sender/receiver arguments\n" - " NormalizeObject::constTemplateSignal1(Template<int>) --> NormalizeObject::constTemplateSlot3(Template<const int>)"); - QVERIFY(!connect(&object, SIGNAL(constTemplateSignal1(Template <int>)), - &object , SLOT(constTemplateSlot3(Template<int const> ) ) )); -} - -class SiblingDeleter : public QObject -{ -public: - inline SiblingDeleter(QObject *sibling, QObject *parent) - : QObject(parent), sibling(sibling) {} - inline virtual ~SiblingDeleter() { delete sibling; } - -private: - QPointer<QObject> sibling; -}; - - -void tst_QObject::childDeletesItsSibling() -{ - QObject *commonParent = new QObject(0); - QPointer<QObject> child = new QObject(0); - QPointer<QObject> siblingDeleter = new SiblingDeleter(child, commonParent); - child->setParent(commonParent); - delete commonParent; // don't crash - QVERIFY(!child); - QVERIFY(!siblingDeleter); -} - -void tst_QObject::floatProperty() -{ - PropertyObject obj; - const int idx = obj.metaObject()->indexOfProperty("myFloat"); - QVERIFY(idx > 0); - QMetaProperty prop = obj.metaObject()->property(idx); - QVERIFY(prop.isValid()); - QVERIFY(prop.type() == uint(QMetaType::type("float"))); - QVERIFY(!prop.write(&obj, QVariant("Hello"))); - QVERIFY(prop.write(&obj, qVariantFromValue(128.0f))); - QVariant v = prop.read(&obj); - QVERIFY(int(v.userType()) == QMetaType::Float); - QVERIFY(qVariantValue<float>(v) == 128.0f); -} - -void tst_QObject::qrealProperty() -{ - PropertyObject obj; - const int idx = obj.metaObject()->indexOfProperty("myQReal"); - QVERIFY(idx > 0); - QMetaProperty prop = obj.metaObject()->property(idx); - QVERIFY(prop.isValid()); - QVERIFY(prop.type() == uint(QMetaType::type("qreal"))); - QVERIFY(!prop.write(&obj, QVariant("Hello"))); - - QVERIFY(prop.write(&obj, qVariantFromValue(128.0f))); - QVariant v = prop.read(&obj); - QCOMPARE(v.userType(), qMetaTypeId<qreal>()); - QVERIFY(qVariantValue<qreal>(v) == 128.0); - - QVERIFY(prop.write(&obj, qVariantFromValue(double(127)))); - v = prop.read(&obj); - QCOMPARE(v.userType(), qMetaTypeId<qreal>()); - QVERIFY(qVariantValue<qreal>(v) == 127.0); -} - -class DynamicPropertyObject : public PropertyObject -{ -public: - inline DynamicPropertyObject() {} - - inline virtual bool event(QEvent *e) { - if (e->type() == QEvent::DynamicPropertyChange) { - changedDynamicProperties.append(static_cast<QDynamicPropertyChangeEvent *>(e)->propertyName()); - } - return QObject::event(e); - } - - QList<QByteArray> changedDynamicProperties; -}; - -void tst_QObject::dynamicProperties() -{ - DynamicPropertyObject obj; - - QVERIFY(obj.dynamicPropertyNames().isEmpty()); - - QVERIFY(obj.setProperty("number", 42)); - QVERIFY(obj.changedDynamicProperties.isEmpty()); - QCOMPARE(obj.property("number").toInt(), 42); - - QVERIFY(!obj.setProperty("number", "invalid string")); - QVERIFY(obj.changedDynamicProperties.isEmpty()); - - QVERIFY(!obj.setProperty("myuserproperty", "Hello")); - QCOMPARE(obj.changedDynamicProperties.count(), 1); - QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty")); - obj.changedDynamicProperties.clear(); - - QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello")); - - QCOMPARE(obj.dynamicPropertyNames().count(), 1); - QCOMPARE(obj.dynamicPropertyNames().first(), QByteArray("myuserproperty")); - - QVERIFY(!obj.setProperty("myuserproperty", QVariant())); - - QCOMPARE(obj.changedDynamicProperties.count(), 1); - QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty")); - obj.changedDynamicProperties.clear(); - - QVERIFY(obj.property("myuserproperty").isNull()); - - QVERIFY(obj.dynamicPropertyNames().isEmpty()); -} - -void tst_QObject::recursiveSignalEmission() -{ -#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) - QSKIP("Emulator builds in Symbian do not support launching processes linking to Qt", SkipAll); -#elif defined(QT_NO_PROCESS) - QSKIP("Test requires QProcess", SkipAll); -#else - QProcess proc; - proc.start("./signalbug"); - QVERIFY(proc.waitForFinished()); - QVERIFY(proc.exitStatus() == QProcess::NormalExit); - QCOMPARE(proc.exitCode(), 0); -#endif -} - -void tst_QObject::blockingQueuedConnection() -{ - { - SenderObject sender; - - MoveToThreadThread thread; - ReceiverObject receiver; - receiver.moveToThread(&thread); - thread.start(); - - receiver.connect(&sender, SIGNAL(signal1()), SLOT(slot1()), Qt::BlockingQueuedConnection); - sender.emitSignal1(); - QVERIFY(receiver.called(1)); - - receiver.reset(); - QVERIFY(QMetaObject::invokeMethod(&receiver, "slot1", Qt::BlockingQueuedConnection)); - QVERIFY(receiver.called(1)); - - thread.quit(); - QVERIFY(thread.wait()); - } -} - -class EventSpy : public QObject -{ - Q_OBJECT - -public: - typedef QList<QPair<QObject *, QEvent::Type> > EventList; - - EventSpy(QObject *parent = 0) - : QObject(parent) - { } - - EventList eventList() - { - return events; - } - - void clear() - { - events.clear(); - } - - bool eventFilter(QObject *object, QEvent *event) - { - events.append(qMakePair(object, event->type())); - return false; - } - -private: - EventList events; -}; - -void tst_QObject::compatibilityChildInsertedEvents() -{ - EventSpy::EventList expected; - - { - // no children created, so we expect no events - QObject object; - EventSpy spy; - object.installEventFilter(&spy); - - QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); - - QCoreApplication::processEvents(); - - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::Type(QEvent::User + 1)); - QCOMPARE(spy.eventList(), expected); - } - - { - // 2 children, so we expect 2 ChildAdded and 2 ChildInserted events - QObject object; - EventSpy spy; - object.installEventFilter(&spy); - - QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); - - QObject child1(&object); - QObject child2; - child2.setParent(&object); - - QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 2))); - - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::ChildAdded) - << qMakePair(&object, QEvent::ChildAdded); - QCOMPARE(spy.eventList(), expected); - spy.clear(); - - QCoreApplication::processEvents(); - - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::Type(QEvent::User + 1)) - << qMakePair(&object, QEvent::Type(QEvent::User + 2)); - QCOMPARE(spy.eventList(), expected); - } - - { - // 2 children, but one is reparented away, so we expect: - // 2 ChildAdded, 1 ChildRemoved, and 1 ChildInserted - QObject object; - EventSpy spy; - object.installEventFilter(&spy); - - QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); - - QObject child1(&object); - QObject child2; - child2.setParent(&object); - child2.setParent(0); - - QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 2))); - - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::ChildAdded) - << qMakePair(&object, QEvent::ChildAdded) - << qMakePair(&object, QEvent::ChildRemoved); - QCOMPARE(spy.eventList(), expected); - spy.clear(); - - QCoreApplication::processEvents(); - - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::Type(QEvent::User + 1)) - << qMakePair(&object, QEvent::Type(QEvent::User + 2)); - QCOMPARE(spy.eventList(), expected); - } -} - -void tst_QObject::installEventFilter() -{ - QEvent event(QEvent::User); - EventSpy::EventList expected; - - QObject object; - EventSpy spy; - object.installEventFilter(&spy); - - // nothing special, should just work - QCoreApplication::sendEvent(&object, &event); - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::User); - QCOMPARE(spy.eventList(), expected); - spy.clear(); - - // moving the filter causes QCoreApplication to skip the filter - spy.moveToThread(0); - QTest::ignoreMessage(QtWarningMsg, "QCoreApplication: Object event filter cannot be in a different thread."); - QCoreApplication::sendEvent(&object, &event); - QVERIFY(spy.eventList().isEmpty()); - - // move it back, and the filter works again - spy.moveToThread(object.thread()); - QCoreApplication::sendEvent(&object, &event); - expected = - EventSpy::EventList() - << qMakePair(&object, QEvent::User); - QCOMPARE(spy.eventList(), expected); - spy.clear(); - - // cannot install an event filter that lives in a different thread - object.removeEventFilter(&spy); - spy.moveToThread(0); - QTest::ignoreMessage(QtWarningMsg, "QObject::installEventFilter(): Cannot filter events for objects in a different thread."); - object.installEventFilter(&spy); - QCoreApplication::sendEvent(&object, &event); - QVERIFY(spy.eventList().isEmpty()); -} - -class EmitThread : public QThread -{ Q_OBJECT -public: - void run(void) { - emit work(); - } -signals: - void work(); -}; - -class DeleteObject : public QObject -{ - Q_OBJECT - -public slots: - void deleteSelf() - { - delete this; - } - - void relaySignalAndProcessEvents() - { - emit relayedSignal(); - QCoreApplication::processEvents(); - } - -signals: - void relayedSignal(); -}; - -void tst_QObject::deleteSelfInSlot() -{ - { - SenderObject sender; - DeleteObject *receiver = new DeleteObject(); - receiver->connect(&sender, - SIGNAL(signal1()), - SLOT(deleteSelf()), - Qt::BlockingQueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - thread.connect(receiver, SIGNAL(destroyed()), SLOT(quit()), Qt::DirectConnection); - thread.start(); - - QPointer<DeleteObject> p = receiver; - sender.emitSignal1(); - QVERIFY(p.isNull()); - - QVERIFY(thread.wait(10000)); - } - - { - SenderObject sender; - DeleteObject *receiver = new DeleteObject(); - receiver->connect(&sender, - SIGNAL(signal1()), - SLOT(relaySignalAndProcessEvents()), - Qt::BlockingQueuedConnection); - receiver->connect(receiver, - SIGNAL(relayedSignal()), - SLOT(deleteSelf()), - Qt::QueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - thread.connect(receiver, SIGNAL(destroyed()), SLOT(quit()), Qt::DirectConnection); - thread.start(); - - QPointer<DeleteObject> p = receiver; - sender.emitSignal1(); - QVERIFY(p.isNull()); - - QVERIFY(thread.wait(10000)); - } - - { - EmitThread sender; - DeleteObject *receiver = new DeleteObject(); - connect(&sender, SIGNAL(work()), receiver, SLOT(deleteSelf()), Qt::DirectConnection); - QPointer<DeleteObject> p = receiver; - sender.start(); - QVERIFY(sender.wait(10000)); - QVERIFY(p.isNull()); - } -} - -class DisconnectObject : public QObject -{ - Q_OBJECT - -public slots: - void disconnectSelf() - { - disconnect(sender(), 0, this, 0); - } - - void relaySignalAndProcessEvents() - { - emit relayedSignal(); - QCoreApplication::processEvents(); - } - -signals: - void relayedSignal(); -}; - -void tst_QObject::disconnectSelfInSlotAndDeleteAfterEmit() -{ - { - SenderObject sender; - DisconnectObject *receiver = new DisconnectObject(); - receiver->connect(&sender, SIGNAL(signal1()), SLOT(disconnectSelf())); - sender.emitSignal1AfterRecursion(); - delete receiver; - } - - { - SenderObject sender; - DisconnectObject *receiver = new DisconnectObject(); - receiver->connect(&sender, - SIGNAL(signal1()), - SLOT(disconnectSelf()), - Qt::BlockingQueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - thread.connect(receiver, SIGNAL(destroyed()), SLOT(quit()), Qt::DirectConnection); - thread.start(); - - QPointer<DisconnectObject> p = receiver; - sender.emitSignal1(); - QVERIFY(!p.isNull()); - - receiver->deleteLater(); - - QVERIFY(thread.wait(10000)); - QVERIFY(p.isNull()); - } - - { - SenderObject sender; - DisconnectObject *receiver = new DisconnectObject(); - receiver->connect(&sender, - SIGNAL(signal1()), - SLOT(relaySignalAndProcessEvents()), - Qt::BlockingQueuedConnection); - receiver->connect(receiver, - SIGNAL(relayedSignal()), - SLOT(disconnectSelf()), - Qt::QueuedConnection); - - QThread thread; - receiver->moveToThread(&thread); - thread.connect(receiver, SIGNAL(destroyed()), SLOT(quit()), Qt::DirectConnection); - thread.start(); - - QPointer<DisconnectObject> p = receiver; - sender.emitSignal1(); - QVERIFY(!p.isNull()); - - receiver->deleteLater(); - - QVERIFY(thread.wait(10000)); - QVERIFY(p.isNull()); - } -} - -void tst_QObject::dumpObjectInfo() -{ - QObject a, b; - QObject::connect(&a, SIGNAL(destroyed(QObject *)), &b, SLOT(deleteLater())); - a.disconnect(&b); - a.dumpObjectInfo(); // should not crash -} - -class ConnectToSender : public QObject -{ Q_OBJECT - public slots: - void uselessSlot() { count++; } - - void harmfullSlot() { - //this used to crash - connect(sender(), SIGNAL(signal4()), this, SLOT(uselessSlot())); - //play a little bit with the memory in order to really get a segfault. - connect(sender(), SIGNAL(signal1()), this, SLOT(uselessSlot())); - QList<double>() << 45 << 78 << 65 << 121 << 45 << 78 << 12; - } - public: - int count; -}; - -void tst_QObject::connectToSender() -{ - SenderObject s; - ConnectToSender r; - r.count = 0; - QObject::connect(&s, SIGNAL(signal1()), &r, SLOT(harmfullSlot())); - QObject::connect(&s, SIGNAL(signal1()), &r, SLOT(uselessSlot())); - - s.emitSignal1(); - - QCOMPARE(r.count, 1); - s.emitSignal4(); - QCOMPARE(r.count, 2); -} - -void tst_QObject::qobjectConstCast() -{ - FooObject obj; - - QObject *ptr = &obj; - const QObject *cptr = &obj; - - QVERIFY(qobject_cast<FooObject *>(ptr)); - QVERIFY(qobject_cast<const FooObject *>(cptr)); -} - -void tst_QObject::uniqConnection() -{ - SenderObject *s = new SenderObject; - ReceiverObject *r1 = new ReceiverObject; - ReceiverObject *r2 = new ReceiverObject; - r1->reset(); - r2->reset(); - ReceiverObject::sequence = 0; - - QVERIFY( connect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) , Qt::UniqueConnection) ); - QVERIFY( connect( s, SIGNAL( signal1() ), r2, SLOT( slot1() ) , Qt::UniqueConnection) ); - QVERIFY( connect( s, SIGNAL( signal1() ), r1, SLOT( slot3() ) , Qt::UniqueConnection) ); - QVERIFY( connect( s, SIGNAL( signal3() ), r1, SLOT( slot3() ) , Qt::UniqueConnection) ); - - s->emitSignal1(); - s->emitSignal2(); - s->emitSignal3(); - s->emitSignal4(); - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 2 ); - QCOMPARE( r1->count_slot4, 0 ); - QCOMPARE( r2->count_slot1, 1 ); - QCOMPARE( r2->count_slot2, 0 ); - QCOMPARE( r2->count_slot3, 0 ); - QCOMPARE( r2->count_slot4, 0 ); - QCOMPARE( r1->sequence_slot1, 1 ); - QCOMPARE( r2->sequence_slot1, 2 ); - QCOMPARE( r1->sequence_slot3, 4 ); - - r1->reset(); - r2->reset(); - ReceiverObject::sequence = 0; - - QVERIFY( connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) , Qt::UniqueConnection) ); - QVERIFY( connect( s, SIGNAL( signal4() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); - QVERIFY(!connect( s, SIGNAL( signal4() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); - QVERIFY( connect( s, SIGNAL( signal1() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); - QVERIFY(!connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) , Qt::UniqueConnection) ); - - s->emitSignal4(); - QCOMPARE( r1->count_slot4, 1 ); - QCOMPARE( r2->count_slot4, 1 ); - QCOMPARE( r1->sequence_slot4, 1 ); - QCOMPARE( r2->sequence_slot4, 2 ); - - r1->reset(); - r2->reset(); - ReceiverObject::sequence = 0; - - connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) ); - - s->emitSignal4(); - QCOMPARE( r1->count_slot4, 2 ); - QCOMPARE( r2->count_slot4, 1 ); - QCOMPARE( r1->sequence_slot4, 3 ); - QCOMPARE( r2->sequence_slot4, 2 ); - - delete s; - delete r1; - delete r2; -} - -void tst_QObject::interfaceIid() -{ - QCOMPARE(QByteArray(qobject_interface_iid<Foo::Bleh *>()), - QByteArray(Bleh_iid)); - QCOMPARE(QByteArray(qobject_interface_iid<Foo::Bar *>()), - QByteArray("com.qtest.foobar")); - QCOMPARE(QByteArray(qobject_interface_iid<FooObject *>()), - QByteArray()); -} - -void tst_QObject::deleteQObjectWhenDeletingEvent() -{ - //this is related to task 259514 - //before the fix this used to dead lock when the QObject from the event was destroyed - - struct MyEvent : public QEvent - { - MyEvent() : QEvent(QEvent::User) { } - QObject obj; - }; - - QObject o; - QApplication::postEvent(&o, new MyEvent); - QCoreApplication::removePostedEvents(&o); // here you would get a deadlock -} - -class OverloadObject : public QObject -{ - friend class tst_QObject; - Q_OBJECT - signals: - void sig(int i, char c, qreal m = 12); - void sig(int i, int j = 12); - void sig(QObject *o, QObject *p, QObject *q = 0, QObject *r = 0) const; - void other(int a = 0); - void sig(QObject *o, OverloadObject *p = 0, QObject *q = 0, QObject *r = 0); - void sig(double r = 0.5); - public slots: - void slo(int i, int j = 43) - { - s_num += 1; - i1_num = i; - i2_num = j; - } - void slo(QObject *o, QObject *p = qApp, QObject *q = qApp, QObject *r = qApp) - { - s_num += 10; - o1_obj = o; - o2_obj = p; - o3_obj = q; - o4_obj = r; - } - void slo() - { - s_num += 100; - } - - public: - int s_num; - int i1_num; - int i2_num; - QObject *o1_obj; - QObject *o2_obj; - QObject *o3_obj; - QObject *o4_obj; -}; - -void tst_QObject::overloads() -{ - OverloadObject obj1; - OverloadObject obj2; - QObject obj3; - obj1.s_num = 0; - obj2.s_num = 0; - - connect (&obj1, SIGNAL(sig(int)) , &obj1, SLOT(slo(int))); - connect (&obj1, SIGNAL(sig(QObject *, QObject *, QObject *)) , &obj1, SLOT(slo(QObject * , QObject *, QObject *))); - - connect (&obj1, SIGNAL(sig(QObject *, QObject *, QObject *, QObject *)) , &obj2, SLOT(slo(QObject * , QObject *, QObject *))); - connect (&obj1, SIGNAL(sig(QObject *)) , &obj2, SLOT(slo())); - connect (&obj1, SIGNAL(sig(int, int)) , &obj2, SLOT(slo(int, int))); - - emit obj1.sig(0.5); //connected to nothing - emit obj1.sig(1, 'a'); //connected to nothing - QCOMPARE(obj1.s_num, 0); - QCOMPARE(obj2.s_num, 0); - - emit obj1.sig(1); //this signal is connected - QCOMPARE(obj1.s_num, 1); - QCOMPARE(obj1.i1_num, 1); - QCOMPARE(obj1.i2_num, 43); //default argument of the slot - - QCOMPARE(obj2.s_num, 1); - QCOMPARE(obj2.i1_num, 1); - QCOMPARE(obj2.i2_num, 12); //default argument of the signal - - - emit obj1.sig(&obj2); //this signal is conencted to obj2 - QCOMPARE(obj1.s_num, 1); - QCOMPARE(obj2.s_num, 101); - emit obj1.sig(&obj2, &obj3); //this signal is connected - QCOMPARE(obj1.s_num, 11); - QCOMPARE(obj1.o1_obj, (QObject *)&obj2); - QCOMPARE(obj1.o2_obj, &obj3); - QCOMPARE(obj1.o3_obj, (QObject *)0); //default arg of the signal - QCOMPARE(obj1.o4_obj, (QObject *)qApp); //default arg of the slot - - QCOMPARE(obj2.s_num, 111); - QCOMPARE(obj2.o1_obj, (QObject *)&obj2); - QCOMPARE(obj2.o2_obj, &obj3); - QCOMPARE(obj2.o3_obj, (QObject *)0); //default arg of the signal - QCOMPARE(obj2.o4_obj, (QObject *)qApp); //default arg of the slot -} - -class ManySignals : public QObject -{ Q_OBJECT - friend class tst_QObject; -signals: - void sig00(); void sig01(); void sig02(); void sig03(); void sig04(); - void sig05(); void sig06(); void sig07(); void sig08(); void sig09(); - void sig10(); void sig11(); void sig12(); void sig13(); void sig14(); - void sig15(); void sig16(); void sig17(); void sig18(); void sig19(); - void sig20(); void sig21(); void sig22(); void sig23(); void sig24(); - void sig25(); void sig26(); void sig27(); void sig28(); void sig29(); - void sig30(); void sig31(); void sig32(); void sig33(); void sig34(); - void sig35(); void sig36(); void sig37(); void sig38(); void sig39(); - void sig40(); void sig41(); void sig42(); void sig43(); void sig44(); - void sig45(); void sig46(); void sig47(); void sig48(); void sig49(); - void sig50(); void sig51(); void sig52(); void sig53(); void sig54(); - void sig55(); void sig56(); void sig57(); void sig58(); void sig59(); - void sig60(); void sig61(); void sig62(); void sig63(); void sig64(); - void sig65(); void sig66(); void sig67(); void sig68(); void sig69(); - -public slots: - void received() { rec++; } -public: - int rec; -}; - - -void tst_QObject::isSignalConnected() -{ - ManySignals o; - o.rec = 0; -#ifdef QT_BUILD_INTERNAL - QObjectPrivate *priv = QObjectPrivate::get(&o); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("destroyed()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig00()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig05()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig15()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); -#endif - - QObject::connect(&o, SIGNAL(sig00()), &o, SIGNAL(sig69())); - QObject::connect(&o, SIGNAL(sig34()), &o, SIGNAL(sig03())); - QObject::connect(&o, SIGNAL(sig69()), &o, SIGNAL(sig34())); - QObject::connect(&o, SIGNAL(sig03()), &o, SIGNAL(sig18())); - -#ifdef QT_BUILD_INTERNAL - QVERIFY(!priv->isSignalConnected(priv->signalIndex("destroyed()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig05()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig15()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()"))); - - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig00()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig03()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig34()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig18()"))); -#endif - - QObject::connect(&o, SIGNAL(sig18()), &o, SIGNAL(sig29())); - QObject::connect(&o, SIGNAL(sig29()), &o, SIGNAL(sig62())); - QObject::connect(&o, SIGNAL(sig62()), &o, SIGNAL(sig28())); - QObject::connect(&o, SIGNAL(sig28()), &o, SIGNAL(sig27())); - -#ifdef QT_BUILD_INTERNAL - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig18()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig62()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig28()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig27()"))); -#endif - - QCOMPARE(o.rec, 0); - emit o.sig01(); - emit o.sig34(); - QCOMPARE(o.rec, 0); - - QObject::connect(&o, SIGNAL(sig27()), &o, SLOT(received())); - -#ifdef QT_BUILD_INTERNAL - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig00()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig03()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig34()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig18()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig62()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig28()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); - QVERIFY(priv->isSignalConnected(priv->signalIndex("sig27()"))); - - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig04()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig21()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig25()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig55()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); -#endif - - emit o.sig00(); - QCOMPARE(o.rec, 1); - emit o.sig69(); - QCOMPARE(o.rec, 2); - emit o.sig36(); - QCOMPARE(o.rec, 2); -} - -void tst_QObject::qMetaObjectConnect() -{ - SenderObject *s = new SenderObject; - ReceiverObject *r1 = new ReceiverObject; - ReceiverObject *r2 = new ReceiverObject; - r1->reset(); - r2->reset(); - ReceiverObject::sequence = 0; - - int signal1Index = s->metaObject()->indexOfSignal("signal1()"); - int signal3Index = s->metaObject()->indexOfSignal("signal3()"); - int slot1Index = r1->metaObject()->indexOfSlot("slot1()"); - int slot2Index = r1->metaObject()->indexOfSlot("slot2()"); - int slot3Index = r1->metaObject()->indexOfSlot("slot3()"); - - QVERIFY(slot1Index > 0); - QVERIFY(slot2Index > 0); - QVERIFY(slot3Index > 0); - - QVERIFY( QMetaObject::connect( s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::connect( s, signal3Index, r2, slot3Index) ); - QVERIFY( QMetaObject::connect( s, -1, r2, slot2Index) ); - - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 0 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 0 ); - QCOMPARE( r2->count_slot3, 0 ); - - s->emitSignal1(); - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 0 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 1 ); - QCOMPARE( r2->count_slot3, 0 ); - - s->emitSignal2(); - s->emitSignal3(); - s->emitSignal4(); - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 0 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 4 ); - QCOMPARE( r2->count_slot3, 1 ); - - QVERIFY( QMetaObject::disconnect( s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::disconnect( s, signal3Index, r2, slot3Index) ); - QVERIFY( QMetaObject::disconnect( s, -1, r2, slot2Index) ); - - s->emitSignal1(); - s->emitSignal2(); - s->emitSignal3(); - s->emitSignal4(); - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 0 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 4 ); - QCOMPARE( r2->count_slot3, 1 ); - - //some "dynamic" signal - QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 20, r1, slot3Index) ); - QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 35, r2, slot1Index) ); - QVERIFY( QMetaObject::connect( s, -1, r1, slot2Index) ); - - r1->reset(); - r2->reset(); - - void *args[] = { 0 , 0 }; - QMetaObject::activate(s, s->metaObject()->methodOffset() + 20, args); - QMetaObject::activate(s, s->metaObject()->methodOffset() + 48, args); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 2 ); - QCOMPARE( r1->count_slot3, 1 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 0 ); - QCOMPARE( r2->count_slot3, 0 ); - - QMetaObject::activate(s, s->metaObject()->methodOffset() + 35, args); - s->emitSignal1(); - s->emitSignal2(); - - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 5 ); - QCOMPARE( r1->count_slot3, 1 ); - QCOMPARE( r2->count_slot1, 1 ); - QCOMPARE( r2->count_slot2, 0 ); - QCOMPARE( r2->count_slot3, 0 ); - - delete s; - r1->reset(); - r2->reset(); - -#define SIGNAL_INDEX(S) obj1.metaObject()->indexOfSignal(QMetaObject::normalizedSignature(#S)) - OverloadObject obj1; - QObject obj2, obj3; - - QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , r1, slot1Index); - QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) , r2, slot1Index); - - QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) , r1, slot2Index); - QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , r2, slot2Index); - QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , r1, slot3Index); - - emit obj1.sig(0.5); //connected to nothing - emit obj1.sig(1, 'a'); //connected to nothing - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 0 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 0 ); - QCOMPARE( r2->count_slot3, 0 ); - - emit obj1.sig(1); //this signal is connected - emit obj1.sig(&obj2); - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - QCOMPARE( r1->count_slot3, 1 ); - QCOMPARE( r2->count_slot1, 0 ); - QCOMPARE( r2->count_slot2, 1 ); - QCOMPARE( r2->count_slot3, 0 ); - - emit obj1.sig(&obj2, &obj3); //this signal is connected - - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 1 ); - QCOMPARE( r1->count_slot3, 1 ); - QCOMPARE( r2->count_slot1, 1 ); - QCOMPARE( r2->count_slot2, 1 ); - QCOMPARE( r2->count_slot3, 0 ); - - delete r1; - delete r2; - -} - -void tst_QObject::qMetaObjectDisconnectOne() -{ - SenderObject *s = new SenderObject; - ReceiverObject *r1 = new ReceiverObject; - - int signal1Index = s->metaObject()->indexOfSignal("signal1()"); - int signal3Index = s->metaObject()->indexOfSignal("signal3()"); - int slot1Index = r1->metaObject()->indexOfSlot("slot1()"); - int slot2Index = r1->metaObject()->indexOfSlot("slot2()"); - - QVERIFY(signal1Index > 0); - QVERIFY(signal3Index > 0); - QVERIFY(slot1Index > 0); - QVERIFY(slot2Index > 0); - - QVERIFY( QMetaObject::connect(s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) ); - QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) ); - QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) ); - - r1->reset(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - - s->emitSignal1(); - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 0 ); - - s->emitSignal3(); - QCOMPARE( r1->count_slot1, 1 ); - QCOMPARE( r1->count_slot2, 3 ); - - r1->reset(); - QVERIFY( QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) ); - - s->emitSignal1(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - - s->emitSignal3(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 2 ); - - r1->reset(); - QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) ); - - s->emitSignal1(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - - s->emitSignal3(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 1 ); - - r1->reset(); - QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) ); - QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) ); - - s->emitSignal1(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - - s->emitSignal3(); - QCOMPARE( r1->count_slot1, 0 ); - QCOMPARE( r1->count_slot2, 0 ); - - delete s; - delete r1; -} - -class ConfusingObject : public SenderObject -{ Q_OBJECT -public slots: - void signal1() { s++; } -signals: - void aPublicSlot(); -public: - int s; - ConfusingObject() : s(0) {} - friend class tst_QObject; -}; - -void tst_QObject::sameName() -{ - ConfusingObject c1, c2; - QVERIFY(connect(&c1, SIGNAL(signal1()), &c1, SLOT(signal1()))); - c1.emitSignal1(); - QCOMPARE(c1.s, 1); - - QVERIFY(connect(&c2, SIGNAL(signal1()), &c1, SIGNAL(signal1()))); - c2.emitSignal1(); - QCOMPARE(c1.s, 2); - - QVERIFY(connect(&c2, SIGNAL(aPublicSlot()), &c1, SLOT(signal1()))); - c2.aPublicSlot(); - QCOMPARE(c2.aPublicSlotCalled, 0); - QCOMPARE(c1.aPublicSlotCalled, 0); - QCOMPARE(c1.s, 3); - - QVERIFY(connect(&c2, SIGNAL(aPublicSlot()), &c1, SLOT(aPublicSlot()))); - c2.aPublicSlot(); - QCOMPARE(c2.aPublicSlotCalled, 0); - QCOMPARE(c1.aPublicSlotCalled, 1); - QCOMPARE(c1.s, 4); -} - -void tst_QObject::connectByMetaMethods() -{ - SenderObject s; - ReceiverObject r; - const QMetaObject *smeta = s.metaObject(); - const QMetaObject *rmeta = r.metaObject(); - int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); - int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); - QVERIFY( sigIndx != -1 ); - QVERIFY( slotIndx != -1 ); - QMetaMethod signal = smeta->method(sigIndx); - QMetaMethod slot = rmeta->method(slotIndx); - - QVERIFY(connect(&s,signal, &r,slot)); - - QVERIFY(!r.called(1)); - s.emitSignal1(); - QVERIFY(r.called(1)); -} - -void tst_QObject::connectByMetaMethodSlotInsteadOfSignal() -{ - SenderObject s; - ReceiverObject r; - const QMetaObject *smeta = s.metaObject(); - const QMetaObject *rmeta = r.metaObject(); - int badIndx = smeta->indexOfSlot(QMetaObject::normalizedSignature("aPublicSlot()")); - int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); - QVERIFY( badIndx != -1 ); - QVERIFY( slotIndx != -1 ); - QMetaMethod badMethod = smeta->method(badIndx); - QMetaMethod slot = rmeta->method(slotIndx); - - QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::aPublicSlot() to ReceiverObject::slot1()"); - QVERIFY(!connect(&s,badMethod, &r,slot)); -} - -class Constructable: public QObject -{ - Q_OBJECT - -public: - Q_INVOKABLE Constructable(){} - -}; - -void tst_QObject::connectConstructorByMetaMethod() -{ - Constructable sc; - Constructable rc; - SenderObject s; - ReceiverObject r; - - const QMetaObject cmeta = Constructable::staticMetaObject; - const QMetaObject *smeta = s.metaObject(); - const QMetaObject *rmeta = r.metaObject(); - int constructorIndx = cmeta.indexOfConstructor(QMetaObject::normalizedSignature("Constructable()")); - int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); - int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); - QVERIFY( constructorIndx != -1 ); - QVERIFY( sigIndx != -1 ); - QVERIFY( slotIndx != -1 ); - - QMetaMethod constructor = cmeta.constructor(constructorIndx); - QMetaMethod signal = smeta->method(sigIndx); - QMetaMethod slot = rmeta->method(slotIndx); - - QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to ReceiverObject::slot1()"); - QVERIFY(!connect(&sc,constructor, &r,slot)); - QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::signal1() to Constructable::Constructable()"); - QVERIFY(!connect(&s,signal, &rc,constructor)); - QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to Constructable::Constructable()"); - QVERIFY(!connect(&sc,constructor, &rc,constructor)); -} - -void tst_QObject::disconnectByMetaMethod() -{ - SenderObject *s = new SenderObject; - ReceiverObject *r1 = new ReceiverObject; - ReceiverObject *r2 = new ReceiverObject; - - QMetaMethod signal1 = s->metaObject()->method( - s->metaObject()->indexOfMethod("signal1()")); - QMetaMethod signal2 = s->metaObject()->method( - s->metaObject()->indexOfMethod("signal2()")); - QMetaMethod signal3 = s->metaObject()->method( - s->metaObject()->indexOfMethod("signal3()")); - QMetaMethod signal4 = s->metaObject()->method( - s->metaObject()->indexOfMethod("signal4()")); - - QMetaMethod slot1 = r1->metaObject()->method( - r1->metaObject()->indexOfMethod("slot1()")); - QMetaMethod slot2 = r1->metaObject()->method( - r1->metaObject()->indexOfMethod("slot2()")); - QMetaMethod slot3 = r1->metaObject()->method( - r1->metaObject()->indexOfMethod("slot3()")); - QMetaMethod slot4 = r1->metaObject()->method( - r1->metaObject()->indexOfMethod("slot4()")); - - connect(s, signal1, r1, slot1); - - s->emitSignal1(); - - QVERIFY(r1->called(1)); - r1->reset(); - - // usual disconnect with all parameters given - bool ret = QObject::disconnect(s, signal1, r1, slot1); - - s->emitSignal1(); - - QVERIFY(!r1->called(1)); - r1->reset(); - - QVERIFY(ret); - ret = QObject::disconnect(s, signal1, r1, slot1); - QVERIFY(!ret); - - r1->reset(); - - connect( s, signal1, r1, slot1 ); - connect( s, signal1, r1, slot2 ); - connect( s, signal1, r1, slot3 ); - connect( s, signal2, r1, slot4 ); - - // disconnect s's signal1() from all slots of r1 - QObject::disconnect(s, signal1, r1, QMetaMethod()); - - s->emitSignal1(); - s->emitSignal2(); - - QVERIFY(!r1->called(1)); - QVERIFY(!r1->called(2)); - QVERIFY(!r1->called(3)); - QVERIFY(r1->called(4)); - r1->reset(); - // make sure all is disconnected again - QObject::disconnect(s, 0, r1, 0); - - connect(s, signal1, r1, slot1); - connect(s, signal1, r2, slot1); - connect(s, signal2, r1, slot2); - connect(s, signal2, r2, slot2); - connect(s, signal3, r1, slot3); - connect(s, signal3, r2, slot3); - - // disconnect signal1() from all receivers - QObject::disconnect(s, signal1, 0, QMetaMethod()); - s->emitSignal1(); - s->emitSignal2(); - s->emitSignal3(); - - QVERIFY(!r1->called(1)); - QVERIFY(!r2->called(1)); - QVERIFY(r1->called(2)); - QVERIFY(r2->called(2)); - QVERIFY(r1->called(2)); - QVERIFY(r2->called(2)); - - r1->reset(); - r2->reset(); - - // disconnect all signals of s from all receivers - QObject::disconnect( s, 0, 0, 0 ); - - connect( s, signal1, r1, slot1 ); - connect( s, signal1, r2, slot1 ); - - // disconnect all signals from slot1 of r1 - QObject::disconnect(s, QMetaMethod(), r1, slot1); - - s->emitSignal1(); - - QVERIFY(!r1->called(1)); - QVERIFY(r2->called(1)); - - delete r2; - delete r1; - delete s; -} - -void tst_QObject::disconnectNotSignalMetaMethod() -{ - SenderObject s; - ReceiverObject r; - - connect(&s, SIGNAL(signal1()), &r, SLOT(slot1())); - - QMetaMethod slot = s.metaObject()->method( - s.metaObject()->indexOfMethod("aPublicSlot()")); - - QTest::ignoreMessage(QtWarningMsg,"Object::disconnect: Attempt to unbind non-signal SenderObject::aPublicSlot()"); - QVERIFY(!QObject::disconnect(&s, slot, &r, QMetaMethod())); -} - -class ThreadAffinityThread : public QThread -{ -public: - SenderObject *sender; - - ThreadAffinityThread(SenderObject *sender) - : sender(sender) - { } - void run() - { - sender->emitSignal1(); - } -}; - -void tst_QObject::autoConnectionBehavior() -{ - SenderObject *sender = new SenderObject; - ReceiverObject *receiver = new ReceiverObject; - connect(sender, SIGNAL(signal1()), receiver, SLOT(slot1())); - - // at emit, currentThread == sender->thread(), currentThread == receiver->thread(), sender->thread() == receiver->thread() - QVERIFY(!receiver->called(1)); - sender->emitSignal1(); - QVERIFY(receiver->called(1)); - receiver->reset(); - - // at emit, currentThread != sender->thread(), currentThread != receiver->thread(), sender->thread() == receiver->thread() - ThreadAffinityThread emitThread1(sender); - QVERIFY(!receiver->called(1)); - emitThread1.start(); - QVERIFY(emitThread1.wait(30000)); - QVERIFY(!receiver->called(1)); - QCoreApplication::sendPostedEvents(receiver, QEvent::MetaCall); - QVERIFY(receiver->called(1)); - receiver->reset(); - - // at emit, currentThread == sender->thread(), currentThread != receiver->thread(), sender->thread() != receiver->thread() - sender->moveToThread(&emitThread1); - QVERIFY(!receiver->called(1)); - emitThread1.start(); - QVERIFY(emitThread1.wait(30000)); - QVERIFY(!receiver->called(1)); - QCoreApplication::sendPostedEvents(receiver, QEvent::MetaCall); - QVERIFY(receiver->called(1)); - receiver->reset(); - - // at emit, currentThread != sender->thread(), currentThread == receiver->thread(), sender->thread() != receiver->thread() - QVERIFY(!receiver->called(1)); - sender->emitSignal1(); - QVERIFY(receiver->called(1)); - receiver->reset(); - - // at emit, currentThread != sender->thread(), currentThread != receiver->thread(), sender->thread() != receiver->thread() - ThreadAffinityThread emitThread2(sender); - QThread receiverThread; - QTimer *timer = new QTimer; - timer->setSingleShot(true); - timer->setInterval(100); - connect(&receiverThread, SIGNAL(started()), timer, SLOT(start())); - connect(timer, SIGNAL(timeout()), &receiverThread, SLOT(quit()), Qt::DirectConnection); - connect(&receiverThread, SIGNAL(finished()), timer, SLOT(deleteLater())); - timer->moveToThread(&receiverThread); - - receiver->moveToThread(&receiverThread); - QVERIFY(!receiver->called(1)); - emitThread2.start(); - QVERIFY(emitThread2.wait(30000)); - QVERIFY(!receiver->called(1)); - receiverThread.start(); - QVERIFY(receiverThread.wait(30000)); - QVERIFY(receiver->called(1)); - receiver->reset(); - - delete sender; - delete receiver; -} - -class BaseDestroyed : public QObject -{ Q_OBJECT - QList<QString> fooList; - bool destroyed; -public: - BaseDestroyed() : destroyed(false) - { fooList << "a" << "b"; } - ~BaseDestroyed() - { - QVERIFY(!destroyed); - destroyed = true; - } - -public slots: - void slotUseList() - { - QVERIFY(!destroyed); - fooList << "c" << "d"; - } -}; - -void tst_QObject::baseDestroyed() -{ - BaseDestroyed d; - connect(&d, SIGNAL(destroyed()), &d, SLOT(slotUseList())); - //When d goes out of scope, slotUseList should not be called as the BaseDestroyed has - // already been destroyed while ~QObject emit destroyed -} - -QTEST_MAIN(tst_QObject) -#include "tst_qobject.moc" |