summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-03-20 08:44:28 +0100
committerLiang Qi <liang.qi@qt.io>2017-03-20 09:00:44 +0100
commitae2695535a2f1abbd4c6596a22dd33319b9388dd (patch)
tree91df41df365a13ea71b1361d909535e5b7a7360a /tests/auto/corelib/kernel/qobject/tst_qobject.cpp
parent8066ae49433ed7604e710eef7b15d15de171608e (diff)
parentc1a2f97a3b3a8c058b1760b57e5c83bf7815b84a (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/corelib/io/qfilesystemengine_win.cpp src/gui/text/qdistancefield.cpp src/plugins/platforms/xcb/qxcbconnection.h Change-Id: I1be4a6f440ccb7599991159e3cb9de60990e4b1e
Diffstat (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp')
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp149
1 files changed, 145 insertions, 4 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index f44c40c27f..db6bdf0809 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -41,8 +41,9 @@
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
-#include <QProcess>
-
+#if QT_CONFIG(process)
+# include <QProcess>
+#endif
#include "qobject.h"
#ifdef QT_BUILD_INTERNAL
#include <private/qobject_p.h>
@@ -281,7 +282,7 @@ static void playWithObjects()
void tst_QObject::initTestCase()
{
-#ifndef QT_NO_PROCESS
+#if QT_CONFIG(process)
const QString testDataDir = QFileInfo(QFINDTESTDATA("signalbug")).absolutePath();
QVERIFY2(QDir::setCurrent(testDataDir), qPrintable("Could not chdir to " + testDataDir));
#endif
@@ -3006,7 +3007,7 @@ void tst_QObject::dynamicProperties()
void tst_QObject::recursiveSignalEmission()
{
-#ifdef QT_NO_PROCESS
+#if !QT_CONFIG(process)
QSKIP("No qprocess support", SkipAll);
#else
QProcess proc;
@@ -5306,6 +5307,15 @@ void tst_QObject::connectNoDefaultConstructorArg()
QVERIFY(connect(&ob, &NoDefaultContructorArguments::mySignal, &ob, &NoDefaultContructorArguments::mySlot, Qt::QueuedConnection));
}
+struct MoveOnly
+{
+ int value;
+ explicit MoveOnly(int v = 1) : value(v) {}
+ MoveOnly(MoveOnly &&o) : value(o.value) { o.value = -1; }
+ MoveOnly &operator=(MoveOnly &&o) { value = o.value; o.value = -1; return *this; }
+ Q_DISABLE_COPY(MoveOnly);
+};
+
class ReturnValue : public QObject {
friend class tst_QObject;
Q_OBJECT
@@ -5315,6 +5325,7 @@ signals:
int returnInt(int);
void returnVoid(int);
CustomType returnCustomType(int);
+ MoveOnly returnMoveOnly(int);
QObject *returnPointer();
public slots:
@@ -5327,6 +5338,7 @@ public slots:
QString returnHello() { return QStringLiteral("hello"); }
QObject *returnThisSlot1() { return this; }
ReturnValue *returnThisSlot2() { return this; }
+ MoveOnly returnMoveOnlySlot(int i) { return MoveOnly(i); }
public:
struct VariantFunctor {
QVariant operator()(int i) { return i; }
@@ -5343,6 +5355,9 @@ public:
struct VoidFunctor {
void operator()(int) {}
};
+ struct MoveOnlyFunctor {
+ MoveOnly operator()(int i) { return MoveOnly(i); }
+ };
};
QString someFunctionReturningString(int i) {
@@ -5380,6 +5395,7 @@ void tst_QObject::returnValue()
emit r.returnVoid(45);
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
QCOMPARE((emit r.returnPointer()), static_cast<QObject *>(0));
+ QCOMPARE((emit r.returnMoveOnly(666)).value, MoveOnly().value);
}
{ // connected to a slot returning the same type
CheckInstanceCount checker;
@@ -5394,6 +5410,8 @@ void tst_QObject::returnValue()
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType(45).value());
QVERIFY(connect(&r, &ReturnValue::returnPointer, &receiver, &ReturnValue::returnThisSlot1, type));
QCOMPARE((emit r.returnPointer()), static_cast<QObject *>(&receiver));
+ QVERIFY(connect(&r, &ReturnValue::returnMoveOnly, &receiver, &ReturnValue::returnMoveOnlySlot, type));
+ QCOMPARE((emit r.returnMoveOnly(666)).value, 666);
}
if (!isBlockingQueued) { // connected to simple functions or functor
CheckInstanceCount checker;
@@ -5412,6 +5430,10 @@ void tst_QObject::returnValue()
ReturnValue::IntFunctor intFunctor;
QVERIFY(connect(&r, &ReturnValue::returnInt, intFunctor));
QCOMPARE(emit r.returnInt(45), int(45));
+
+ ReturnValue::MoveOnlyFunctor moveOnlyFunctor;
+ QVERIFY(connect(&r, &ReturnValue::returnMoveOnly, moveOnlyFunctor));
+ QCOMPARE((emit r.returnMoveOnly(666)).value, 666);
}
{ // connected to a slot with different type
CheckInstanceCount checker;
@@ -5450,6 +5472,8 @@ void tst_QObject::returnValue()
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
QVERIFY(connect(&r, &ReturnValue::returnPointer, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE((emit r.returnPointer()), static_cast<QObject *>(0));
+ QVERIFY(connect(&r, &ReturnValue::returnMoveOnly, &receiver, &ReturnValue::returnVoidSlot, type));
+ QCOMPARE((emit r.returnMoveOnly(666)).value, MoveOnly().value);
}
if (!isBlockingQueued) {
// queued connection should not forward the return value
@@ -5465,6 +5489,8 @@ void tst_QObject::returnValue()
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
QVERIFY(connect(&r, &ReturnValue::returnPointer, &receiver, &ReturnValue::returnThisSlot1, Qt::QueuedConnection));
QCOMPARE((emit r.returnPointer()), static_cast<QObject *>(0));
+ QVERIFY(connect(&r, &ReturnValue::returnMoveOnly, &receiver, &ReturnValue::returnMoveOnlySlot, Qt::QueuedConnection));
+ QCOMPARE((emit r.returnMoveOnly(666)).value, MoveOnly().value);
QCoreApplication::processEvents();
@@ -5548,6 +5574,8 @@ void tst_QObject::returnValue2()
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnCustomTypeSlot(int)), type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType(45).value());
+ QVERIFY(connect(&r, SIGNAL(returnMoveOnly(int)), &receiver, SLOT(returnMoveOnlySlot(int)), type));
+ QCOMPARE((emit r.returnMoveOnly(45)).value, 45);
}
{ // connected to a slot returning void
CheckInstanceCount checker;
@@ -5560,6 +5588,8 @@ void tst_QObject::returnValue2()
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
+ QVERIFY(connect(&r, SIGNAL(returnMoveOnly(int)), &receiver, SLOT(returnVoidSlot()), type));
+ QCOMPARE((emit r.returnMoveOnly(45)).value, MoveOnly().value);
}
if (!isBlockingQueued) {
// queued connection should not forward the return value
@@ -5573,6 +5603,9 @@ void tst_QObject::returnValue2()
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnCustomTypeSlot(int)), Qt::QueuedConnection));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
+ QVERIFY(connect(&r, SIGNAL(returnMoveOnly(int)), &receiver, SLOT(returnMoveOnlySlot(int)), Qt::QueuedConnection));
+ QCOMPARE((emit r.returnMoveOnly(45)).value, MoveOnly().value);
+
QCoreApplication::processEvents();
//Queued conneciton with different return type should be safe
@@ -5679,6 +5712,27 @@ public slots:
virtual void slot2() { ++virtual_base_count; }
};
+struct NormalBase
+{
+ QByteArray lastCalled;
+ virtual ~NormalBase() {}
+ virtual void virtualBaseSlot() { lastCalled = "virtualBaseSlot"; }
+ void normalBaseSlot() { lastCalled = "normalBaseSlot"; }
+};
+
+class ObjectWithMultiInheritance : public VirtualSlotsObject, public NormalBase
+{
+ Q_OBJECT
+};
+
+// Normally, the class that inherit QObject always must go first, because of the way qobject_cast
+// work, and moc checks for that. But if we don't use Q_OBJECT, this should work
+class ObjectWithMultiInheritance2 : public NormalBase, public VirtualSlotsObject
+{
+ // no QObject as QObject always must go first
+ // Q_OBJECT
+};
+
// VMI = Virtual or Multiple Inheritance
// (in this case, both)
void tst_QObject::connectSlotsVMIClass()
@@ -5761,6 +5815,93 @@ void tst_QObject::connectSlotsVMIClass()
QCOMPARE(obj.virtual_base_count, 1);
QCOMPARE(obj.regular_call_count, 0);
}
+
+ // test connecting a slot that is virtual within the second base
+ {
+ ObjectWithMultiInheritance obj;
+ void (ObjectWithMultiInheritance::*slot)() = &ObjectWithMultiInheritance::virtualBaseSlot;
+ QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+ QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray("virtualBaseSlot"));
+ obj.lastCalled.clear();
+
+ QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+ QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray());
+ }
+
+ // test connecting a slot that is not virtual within the second base
+ {
+ ObjectWithMultiInheritance obj;
+ void (ObjectWithMultiInheritance::*slot)() = &ObjectWithMultiInheritance::normalBaseSlot;
+ QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+ QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray("normalBaseSlot"));
+ obj.lastCalled.clear();
+
+ QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+ QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray());
+ }
+
+ // test connecting a slot within the first non-QObject base
+ {
+ ObjectWithMultiInheritance2 obj;
+ void (ObjectWithMultiInheritance2::*slot)() = &ObjectWithMultiInheritance2::normalBaseSlot;
+ QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+ QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray("normalBaseSlot"));
+ obj.lastCalled.clear();
+
+ QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+ QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 0);
+ QCOMPARE(obj.lastCalled, QByteArray());
+ }
+
+ // test connecting a slot within the second QObject base
+ {
+ ObjectWithMultiInheritance2 obj;
+ void (ObjectWithMultiInheritance2::*slot)() = &ObjectWithMultiInheritance2::slot1;
+ QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+ QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot, Qt::UniqueConnection));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 1);
+ QCOMPARE(obj.lastCalled, QByteArray());
+
+ QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+ QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, slot));
+
+ emit obj.signal1();
+ QCOMPARE(obj.base_counter1, 0);
+ QCOMPARE(obj.derived_counter1, 1);
+ QCOMPARE(obj.lastCalled, QByteArray());
+ }
}
#ifndef QT_BUILD_INTERNAL