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

View File

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

View File

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