tst_QObject: Test if the new connect style works with virtual bases

Change-Id: I87e17314d8b24ae983b1fffd1453abe1e395bbd1
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>
This commit is contained in:
Thiago Macieira 2016-05-31 11:01:30 -03:00
parent 7b8a553a13
commit 3b3ca5dead

View File

@ -129,6 +129,7 @@ private slots:
void returnValue2_data();
void returnValue2();
void connectVirtualSlots();
void connectSlotsVMIClass(); // VMI = Virtual or Multiple Inheritance
void connectPrivateSlots();
void connectFunctorArgDifference();
void connectFunctorOverloads();
@ -5606,6 +5607,112 @@ void tst_QObject::connectVirtualSlots()
*/
}
struct VirtualBase
{
int virtual_base_count;
VirtualBase() : virtual_base_count(0) {}
virtual ~VirtualBase() {}
virtual void slot2() = 0;
};
class ObjectWithVirtualBase : public VirtualSlotsObject, public virtual VirtualBase
{
Q_OBJECT
public:
ObjectWithVirtualBase() : regular_call_count(0), derived_counter2(0) {}
int regular_call_count;
int derived_counter2;
public slots:
void regularSlot() { ++regular_call_count; }
virtual void slot1() { ++derived_counter2; }
virtual void slot2() { ++virtual_base_count; }
};
// VMI = Virtual or Multiple Inheritance
// (in this case, both)
void tst_QObject::connectSlotsVMIClass()
{
// test connecting by the base
{
ObjectWithVirtualBase obj;
QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &VirtualSlotsObjectBase::slot1, Qt::UniqueConnection));
QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &VirtualSlotsObjectBase::slot1, Qt::UniqueConnection));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 1);
QCOMPARE(obj.virtual_base_count, 0);
QVERIFY(QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &VirtualSlotsObjectBase::slot1));
QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &VirtualSlotsObjectBase::slot1));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 1);
QCOMPARE(obj.virtual_base_count, 0);
}
// test connecting with the actual class
{
ObjectWithVirtualBase obj;
QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::regularSlot, Qt::UniqueConnection));
QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::regularSlot, Qt::UniqueConnection));
QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot1, Qt::UniqueConnection));
QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot1, Qt::UniqueConnection));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 1);
QCOMPARE(obj.regular_call_count, 1);
QCOMPARE(obj.virtual_base_count, 0);
QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::regularSlot));
QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::regularSlot));
QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot1));
QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot1));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 1);
QCOMPARE(obj.regular_call_count, 1);
QCOMPARE(obj.virtual_base_count, 0);
/* the C++ standard say the comparison between pointer to virtual member function is unspecified
QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &VirtualSlotsObjectBase::slot1, Qt::UniqueConnection));
QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot1, Qt::UniqueConnection));
*/
}
// test connecting a slot that is virtual from the virtual base
{
ObjectWithVirtualBase obj;
QVERIFY( QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot2, Qt::UniqueConnection));
QVERIFY(!QObject::connect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot2, Qt::UniqueConnection));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 0);
QCOMPARE(obj.virtual_base_count, 1);
QCOMPARE(obj.regular_call_count, 0);
QVERIFY( QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot2));
QVERIFY(!QObject::disconnect(&obj, &VirtualSlotsObjectBase::signal1, &obj, &ObjectWithVirtualBase::slot2));
emit obj.signal1();
QCOMPARE(obj.base_counter1, 0);
QCOMPARE(obj.derived_counter1, 0);
QCOMPARE(obj.derived_counter2, 0);
QCOMPARE(obj.virtual_base_count, 1);
QCOMPARE(obj.regular_call_count, 0);
}
}
#ifndef QT_BUILD_INTERNAL
void tst_QObject::connectPrivateSlots()
{QSKIP("Needs QT_BUILD_INTERNAL");}