Revert "testlib: Add qWaitFor to wait for predicate"

This reverts commit 3b38392844.

The change caused test compile failures with MSVC2015 in qqmlsettings;
a variable was not captured in the lambda expression. This appears
to be a compiler bug of MSVC.

Task-number: QTBUG-59096
Change-Id: I3bf5288eb005b2e1661819bb33bc54fb944d0150
Reviewed-by: Liang Qi <liang.qi@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
bb10
Friedemann Kleint 2017-02-23 10:32:31 +01:00 committed by Liang Qi
parent 21298aad45
commit 35fa30e65d
4 changed files with 31 additions and 66 deletions

View File

@ -306,13 +306,5 @@ QTest::keyClick(myWindow, Qt::Key_Escape);
QTest::keyClick(myWindow, Qt::Key_Escape, Qt::ShiftModifier, 200);
//! [29]
//! [30]
MyObject obj;
obj.startup();
QTest::qWaitFor([&]() {
return obj.isReady();
}, 3000);
//! [30]
}

View File

@ -150,8 +150,7 @@ do {\
#define QTRY_IMPL(expr, timeout)\
const int qt_test_step = 50; \
const int qt_test_timeoutValue = timeout; \
bool timedOut = !QTest::qWaitFor([&]() { return (expr); }, qt_test_timeoutValue); \
Q_UNUSED(timedOut); \
QTRY_LOOP_IMPL((expr), qt_test_timeoutValue, qt_test_step); \
QTRY_TIMEOUT_DEBUG_IMPL((expr), qt_test_timeoutValue, qt_test_step)\
// Will try to wait for the expression to become true while allowing event processing

View File

@ -1062,21 +1062,6 @@
\sa QTest::qSleep(), QSignalSpy::wait()
*/
/*! \fn void QTest::qWaitFor(Predicate predicate, int timeout)
Waits for \a timeout milliseconds or until the \a predicate returns true.
Returns \c true if the \a preciate returned true within \a timeout milliseconds, otherwise returns \c false.
Example:
\snippet code/src_qtestlib_qtestcase.cpp 30
The code above will wait for the object to become ready, for a
maximum of three seconds.
\since 5.9
*/
/*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
\since 5.0

View File

@ -54,60 +54,41 @@ QT_BEGIN_NAMESPACE
namespace QTest
{
template <typename Predicate>
static Q_REQUIRED_RESULT bool qWaitFor(Predicate predicate, int timeout = 5000)
{
// We should not spint the event loop in case the predicate is already true,
// otherwise we might send new events that invalidate the predicate.
if (predicate())
return true;
// qWait() is expected to spin the event loop, even when called with a small
// timeout like 1ms, so we we can't use a simple while-loop here based on
// the deadline timer not having timed out. Use do-while instead.
int remaining = timeout;
QDeadlineTimer deadline(remaining, Qt::PreciseTimer);
do {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
remaining = deadline.remainingTime();
if (remaining > 0) {
QTest::qSleep(qMin(10, remaining));
remaining = deadline.remainingTime();
}
if (predicate())
return true;
remaining = deadline.remainingTime();
} while (remaining > 0);
return predicate(); // Last chance
}
Q_DECL_UNUSED inline static void qWait(int ms)
{
Q_ASSERT(QCoreApplication::instance());
auto unconditionalWait = []() { return false; };
bool timedOut = !qWaitFor(unconditionalWait, ms);
Q_UNUSED(timedOut);
QDeadlineTimer timer(ms, Qt::PreciseTimer);
int remaining = ms;
do {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete);
remaining = timer.remainingTime();
if (remaining <= 0)
break;
QTest::qSleep(qMin(10, remaining));
remaining = timer.remainingTime();
} while (remaining > 0);
}
#ifdef QT_GUI_LIB
inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000)
{
bool becameActive = qWaitFor([&]() { return window->isActive(); }, timeout);
QDeadlineTimer timer(timeout, Qt::PreciseTimer);
int remaining = timeout;
while (!window->isActive() && remaining > 0) {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete);
QTest::qSleep(10);
remaining = timer.remainingTime();
}
// Try ensuring the platform window receives the real position.
// (i.e. that window->pos() reflects reality)
// isActive() ( == FocusIn in case of X) does not guarantee this. It seems some WMs randomly
// send the final ConfigureNotify (the one with the non-bogus 0,0 position) after the FocusIn.
// If we just let things go, every mapTo/FromGlobal call the tests perform directly after
// qWaitForWindowShown() will generate bogus results.
if (becameActive) {
if (window->isActive()) {
int waitNo = 0; // 0, 0 might be a valid position after all, so do not wait for ever
while (window->position().isNull()) {
if (waitNo++ > timeout / 10)
@ -120,7 +101,15 @@ namespace QTest
inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000)
{
return qWaitFor([&]() { return window->isExposed(); }, timeout);
QDeadlineTimer timer(timeout, Qt::PreciseTimer);
int remaining = timeout;
while (!window->isExposed() && remaining > 0) {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete);
QTest::qSleep(10);
remaining = timer.remainingTime();
}
return window->isExposed();
}
#endif