From 3b3ca5deadcc5f414b5ca158f599eb321683aee1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 31 May 2016 11:01:30 -0300 Subject: tst_QObject: Test if the new connect style works with virtual bases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I87e17314d8b24ae983b1fffd1453abe1e395bbd1 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 107 ++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 1902687eef..e38dbad7d7 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -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");} -- cgit v1.2.3