summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qobject
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2024-02-03 14:45:34 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2024-02-04 18:33:37 +0100
commit0d0810e2dcc8a9ee28935af5daadc2ef36ed25a2 (patch)
tree49e94b35709aee9b8c46f1443a89da1f03be1457 /tests/auto/corelib/kernel/qobject
parentd887e34b495c52a1168c7e7212172d879963c420 (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.cpp85
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