diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-02-03 14:45:34 +0100 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2024-02-04 18:33:37 +0100 |
commit | 0d0810e2dcc8a9ee28935af5daadc2ef36ed25a2 (patch) | |
tree | 49e94b35709aee9b8c46f1443a89da1f03be1457 /tests/auto/corelib/kernel/qobject | |
parent | d887e34b495c52a1168c7e7212172d879963c420 (diff) |
QObject: fix installEventFilterOrder() test flakiness
Don't rely on timer precision and use int counter instead.
Amends 1fe88bf4cd919d4b5cadb4be2cf0193525c54673
Pick-to: 6.7 6.6 6.5 6.2 5.15
Change-Id: I057b4dd51014784ec9b244301b43583f3de6ddd1
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'tests/auto/corelib/kernel/qobject')
-rw-r--r-- | tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 85 |
1 files changed, 40 insertions, 45 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 3f4a1b037e..6c387fde96 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -3142,6 +3142,8 @@ void tst_QObject::blockingQueuedConnection() } } +static int s_eventSpyCounter = -1; + class EventSpy : public QObject { Q_OBJECT @@ -3161,16 +3163,17 @@ public: void clear() { events.clear(); + thisCounter = -1; } bool eventFilter(QObject *object, QEvent *event) override { events.append(qMakePair(object, event->type())); - timeStamp = std::chrono::steady_clock::now(); + thisCounter = ++s_eventSpyCounter; return false; } - std::chrono::steady_clock::time_point timeStamp; + int thisCounter = -1; private: EventList events; }; @@ -3372,76 +3375,68 @@ void tst_QObject::installEventFilter() QVERIFY(spy.eventList().isEmpty()); } +#define CHECK_FAIL(message) \ +do {\ + if (QTest::currentTestFailed())\ + QFAIL("failed one line above on " message);\ +} while (false) + void tst_QObject::installEventFilterOrder() { // installEventFilter() adds new objects to d_func()->extraData->eventFilters, which // affects the order of calling each object's eventFilter() when processing the events. QObject object; - EventSpy spy1; - object.installEventFilter(&spy1); - EventSpy spy2; - object.installEventFilter(&spy2); - EventSpy spy3; - object.installEventFilter(&spy3); - - const EventSpy::EventList expected = { {&object, QEvent::Type(QEvent::User + 1)} }; - auto checkExpected = [&] { - QCOMPARE(spy1.eventList(), expected); - QCOMPARE(spy2.eventList(), expected); - QCOMPARE(spy3.eventList(), expected); - }; + EventSpy spy1, spy2, spy3; auto clearSignalSpies = [&] { for (auto *s : {&spy1, &spy2, &spy3}) s->clear(); + s_eventSpyCounter = -1; }; - auto checkCallOrder = [](EventSpy &a, EventSpy &b, EventSpy &c) { - QVERIFY(a.timeStamp > b.timeStamp); - QVERIFY(b.timeStamp > c.timeStamp); + const EventSpy::EventList expected = { { &object, QEvent::Type(QEvent::User + 1) } }; + + // Call Order: from first to last + auto checkCallOrder = [&expected](const QList<EventSpy *> &spies) { + for (int i = 0; i < spies.size(); ++i) { + EventSpy *spy = spies.at(i); + QVERIFY2(spy->eventList() == expected, + QString("The spy %1 wasn't triggered exactly once.").arg(i).toLatin1()); + QCOMPARE(spy->thisCounter, i); + } }; + // Install event filters and check the order of invocations: + // The last installed = the first called. + object.installEventFilter(&spy1); + object.installEventFilter(&spy2); + object.installEventFilter(&spy3); + clearSignalSpies(); QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); QCoreApplication::processEvents(); - - checkExpected(); - if (QTest::currentTestFailed()) - return; - - checkCallOrder(spy1, spy2, spy3); - if (QTest::currentTestFailed()) - return; - - clearSignalSpies(); + checkCallOrder({ &spy3, &spy2, &spy1 }); + CHECK_FAIL("checkCallOrder() - 1st round"); // Install event filter for `spy1` again, which reorders spy1 in `eventFilters` // (the list doesn't have duplicates). object.installEventFilter(&spy1); - + clearSignalSpies(); QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); QCoreApplication::processEvents(); + checkCallOrder({ &spy1, &spy3, &spy2 }); + CHECK_FAIL("checkCallOrder() - 2nd round"); - checkExpected(); - if (QTest::currentTestFailed()) - return; - - checkCallOrder(spy2, spy3, spy1); - if (QTest::currentTestFailed()) - return; - - clearSignalSpies(); - + // Remove event filter for `spy3`, ensure it's not called anymore and the + // existing filters order is preserved. object.removeEventFilter(&spy3); - + clearSignalSpies(); QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); QCoreApplication::processEvents(); - + checkCallOrder({ &spy1, &spy2 }); + CHECK_FAIL("checkCallOrder() - 3rd round"); QVERIFY(spy3.eventList().isEmpty()); - QCOMPARE(spy1.eventList(), expected); - QCOMPARE(spy2.eventList(), expected); - - QVERIFY(spy2.timeStamp > spy1.timeStamp); + QCOMPARE(spy3.thisCounter, -1); } class EmitThread : public QThread |