diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index 44bde894d2..2ac44bb13d 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -54,18 +54,31 @@ void QTest::qSleep(std::chrono::milliseconds msecs) /*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout) + \since 5.10 + \overload + Waits for \a timeout milliseconds or until the \a predicate returns true. - Returns \c true if the \a predicate returned true at any point, otherwise returns \c false. + This is equivalent to calling: + \code + qWaitFor(predicate, QDeadlineTimer(timeout)); + \endcode +*/ + +/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, QDeadlineTimer deadline) + \since 6.7 + + Waits until \a deadline has expired, or until \a predicate returns true, whichever + happens first. + + Returns \c true if \a predicate returned true at any point, otherwise returns \c false. Example: - \snippet code/src_corelib_kernel_qtestsupport_core_snippet.cpp 0 + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 2 The code above will wait for the object to become ready, for a maximum of three seconds. - - \since 5.10 */ /*! diff --git a/src/corelib/kernel/qtestsupport_core.h b/src/corelib/kernel/qtestsupport_core.h index fdacd116e9..efe46ff503 100644 --- a/src/corelib/kernel/qtestsupport_core.h +++ b/src/corelib/kernel/qtestsupport_core.h @@ -16,7 +16,8 @@ Q_CORE_EXPORT void qSleep(int ms); Q_CORE_EXPORT void qSleep(std::chrono::milliseconds msecs); template <typename Functor> -[[nodiscard]] static bool qWaitFor(Functor predicate, int timeout = 5000) +[[nodiscard]] static bool +qWaitFor(Functor predicate, QDeadlineTimer deadline = QDeadlineTimer(std::chrono::seconds{5})) { // We should not spin the event loop in case the predicate is already true, // otherwise we might send new events that invalidate the predicate. @@ -27,9 +28,9 @@ template <typename Functor> // 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); + using namespace std::chrono; + auto remaining = 0ms; do { // We explicitly do not pass the remaining time to processEvents, as // that would keep spinning processEvents for the whole duration if @@ -43,15 +44,27 @@ template <typename Functor> if (predicate()) return true; - remaining = int(deadline.remainingTime()); - if (remaining > 0) - qSleep(qMin(10, remaining)); - remaining = int(deadline.remainingTime()); - } while (remaining > 0); + if (deadline.isForever()) { // No point checking remaining time + qSleep(10ms); + continue; + } + + remaining = ceil<milliseconds>(deadline.remainingTimeAsDuration()); + if (remaining == 0ms) + break; + + qSleep(std::min(10ms, remaining)); + } while (!deadline.hasExpired()); return predicate(); // Last chance } +template <typename Functor> +[[nodiscard]] static bool qWaitFor(Functor predicate, int timeout) +{ + return qWaitFor(predicate, QDeadlineTimer(timeout)); +} + Q_CORE_EXPORT void qWait(int ms); Q_CORE_EXPORT void qWait(std::chrono::milliseconds msecs); diff --git a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp index 1bd6d3c068..30c6dfec9f 100644 --- a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp +++ b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp @@ -7,6 +7,7 @@ class MyObject { public: int isReady(); + bool startup(); }; // dummy function @@ -25,3 +26,15 @@ int MyObject::isReady() //! [1] return 1; } + +static bool startup() +{ +//! [2] + MyObject obj; + obj.startup(); + using namespace std::chrono_literals; + const bool result = QTest::qWaitFor([&obj]() { return obj.isReady(); }, + QDeadlineTimer(3s)); +//! [2] + return result; +} diff --git a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp deleted file mode 100644 index f2ba321a67..0000000000 --- a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -//! [0] - MyObject obj; - obj.startup(); - QTest::qWaitFor([&]() { - return obj.isReady(); - }, 3000); -//! [0]