QObject: fix installEventFilterOrder() test flakiness
Don't rely on timer precision and use int counter instead. Amends 1fe88bf4cd919d4b5cadb4be2cf0193525c54673 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: I057b4dd51014784ec9b244301b43583f3de6ddd1 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> (cherry picked from commit 0d0810e2dcc8a9ee28935af5daadc2ef36ed25a2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
f48faee770
commit
c160f3340e
@ -3142,6 +3142,8 @@ void tst_QObject::blockingQueuedConnection()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int s_eventSpyCounter = -1;
|
||||||
|
|
||||||
class EventSpy : public QObject
|
class EventSpy : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -3161,16 +3163,17 @@ public:
|
|||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
events.clear();
|
events.clear();
|
||||||
|
thisCounter = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eventFilter(QObject *object, QEvent *event) override
|
bool eventFilter(QObject *object, QEvent *event) override
|
||||||
{
|
{
|
||||||
events.append(qMakePair(object, event->type()));
|
events.append(qMakePair(object, event->type()));
|
||||||
timeStamp = std::chrono::steady_clock::now();
|
thisCounter = ++s_eventSpyCounter;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point timeStamp;
|
int thisCounter = -1;
|
||||||
private:
|
private:
|
||||||
EventList events;
|
EventList events;
|
||||||
};
|
};
|
||||||
@ -3372,76 +3375,68 @@ void tst_QObject::installEventFilter()
|
|||||||
QVERIFY(spy.eventList().isEmpty());
|
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()
|
void tst_QObject::installEventFilterOrder()
|
||||||
{
|
{
|
||||||
// installEventFilter() adds new objects to d_func()->extraData->eventFilters, which
|
// installEventFilter() adds new objects to d_func()->extraData->eventFilters, which
|
||||||
// affects the order of calling each object's eventFilter() when processing the events.
|
// affects the order of calling each object's eventFilter() when processing the events.
|
||||||
|
|
||||||
QObject object;
|
QObject object;
|
||||||
EventSpy spy1;
|
EventSpy spy1, spy2, spy3;
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto clearSignalSpies = [&] {
|
auto clearSignalSpies = [&] {
|
||||||
for (auto *s : {&spy1, &spy2, &spy3})
|
for (auto *s : {&spy1, &spy2, &spy3})
|
||||||
s->clear();
|
s->clear();
|
||||||
|
s_eventSpyCounter = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto checkCallOrder = [](EventSpy &a, EventSpy &b, EventSpy &c) {
|
const EventSpy::EventList expected = { { &object, QEvent::Type(QEvent::User + 1) } };
|
||||||
QVERIFY(a.timeStamp > b.timeStamp);
|
|
||||||
QVERIFY(b.timeStamp > c.timeStamp);
|
// 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::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
checkCallOrder({ &spy3, &spy2, &spy1 });
|
||||||
checkExpected();
|
CHECK_FAIL("checkCallOrder() - 1st round");
|
||||||
if (QTest::currentTestFailed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
checkCallOrder(spy1, spy2, spy3);
|
|
||||||
if (QTest::currentTestFailed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
clearSignalSpies();
|
|
||||||
|
|
||||||
// Install event filter for `spy1` again, which reorders spy1 in `eventFilters`
|
// Install event filter for `spy1` again, which reorders spy1 in `eventFilters`
|
||||||
// (the list doesn't have duplicates).
|
// (the list doesn't have duplicates).
|
||||||
object.installEventFilter(&spy1);
|
object.installEventFilter(&spy1);
|
||||||
|
|
||||||
QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
checkExpected();
|
|
||||||
if (QTest::currentTestFailed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
checkCallOrder(spy2, spy3, spy1);
|
|
||||||
if (QTest::currentTestFailed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
clearSignalSpies();
|
clearSignalSpies();
|
||||||
|
|
||||||
object.removeEventFilter(&spy3);
|
|
||||||
|
|
||||||
QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
|
QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
checkCallOrder({ &spy1, &spy3, &spy2 });
|
||||||
|
CHECK_FAIL("checkCallOrder() - 2nd round");
|
||||||
|
|
||||||
|
// 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());
|
QVERIFY(spy3.eventList().isEmpty());
|
||||||
QCOMPARE(spy1.eventList(), expected);
|
QCOMPARE(spy3.thisCounter, -1);
|
||||||
QCOMPARE(spy2.eventList(), expected);
|
|
||||||
|
|
||||||
QVERIFY(spy2.timeStamp > spy1.timeStamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmitThread : public QThread
|
class EmitThread : public QThread
|
||||||
|
Loading…
x
Reference in New Issue
Block a user