QTest: add qWait(chrono::milliseconds) overload

The code bailed out of the while loop when "remainingTime <= 0",
for a QDeadlineTimer::isForever() timer remainingTime() returns -1,
whereas remainingTimeAsDuration() returns nanoseconds::max().

I.e. the original code stopped the while loop when the timer isForever()
or "expired" (i.e. remaining time is 0). I am not sure the isForever()
part was intended that way or not, but it makes sense, if
QCoreApplication::processEvents() has already run "forever", there is no
point looping again.

[ChangeLog][QtCore][QTest] Added qWait(chrono::milliseconds) overload.

Change-Id: I871c28b053c6ba4f81a7e2d434aa4fbe03c8c5e7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2023-03-05 00:13:32 +02:00
parent c580a7b0fa
commit 57712e1160
3 changed files with 35 additions and 12 deletions

View File

@ -68,10 +68,23 @@ void QTest::qSleep(std::chrono::milliseconds msecs)
\since 5.10
*/
/*!
\overload
/*! \fn void QTest::qWait(int ms)
Waits for \a msecs. Equivalent to calling:
\code
QTest::qWait(std::chrono::milliseconds{msecs});
\endcode
*/
Q_CORE_EXPORT void QTest::qWait(int msecs)
{
qWait(std::chrono::milliseconds{msecs});
}
Waits for \a ms milliseconds. While waiting, events will be processed and
/*!
\since 6.7
Waits for \a msecs. While waiting, events will be processed and
your test will stay responsive to user interface events or network communication.
Example:
@ -83,7 +96,7 @@ void QTest::qSleep(std::chrono::milliseconds msecs)
\sa QTest::qSleep(), QSignalSpy::wait()
*/
Q_CORE_EXPORT void QTest::qWait(int ms)
Q_CORE_EXPORT void QTest::qWait(std::chrono::milliseconds msecs)
{
// Ideally this method would be implemented in terms of qWaitFor(), with a
// predicate that always returns false, but qWaitFor() uses the 1-arg overload
@ -93,17 +106,24 @@ Q_CORE_EXPORT void QTest::qWait(int ms)
Q_ASSERT(QCoreApplication::instance());
QDeadlineTimer timer(ms, Qt::PreciseTimer);
int remaining = ms;
using namespace std::chrono;
QDeadlineTimer deadline(msecs, Qt::PreciseTimer);
do {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::processEvents(QEventLoop::AllEvents, deadline);
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
remaining = timer.remainingTime();
if (remaining <= 0)
// If dealine is Forever, processEvents() has already looped forever
if (deadline.isForever())
break;
QTest::qSleep(qMin(10, remaining));
remaining = timer.remainingTime();
} while (remaining > 0);
msecs = ceil<milliseconds>(deadline.remainingTimeAsDuration());
if (msecs == 0ms)
break;
QTest::qSleep(std::min(10ms, msecs));
} while (!deadline.hasExpired());
}
QT_END_NAMESPACE

View File

@ -54,6 +54,8 @@ template <typename Functor>
Q_CORE_EXPORT void qWait(int ms);
Q_CORE_EXPORT void qWait(std::chrono::milliseconds msecs);
} // namespace QTest
QT_END_NAMESPACE

View File

@ -18,9 +18,10 @@ int myNetworkServerNotResponding()
int MyObject::isReady()
{
//! [1]
using namespace std::chrono_literals;
int i = 0;
while (myNetworkServerNotResponding() && i++ < 50)
QTest::qWait(250);
QTest::qWait(250ms);
//! [1]
return 1;
}