From 4c9e36ffcdedd81213eb7a5e6482fe0fdd1ad42a Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 25 Aug 2023 18:05:36 +0200 Subject: [PATCH] QTimer: extend property tests and fix binding loop The bindable property tests were not using the QTestPrivate helpers, so add a new test which uses them. The new tests revealed a binding loop for the interval property. Fix it in a usual way by explicitly removing the binding and using {set}ValueBypassingBindings() in the setter. Task-number: QTBUG-116346 Change-Id: If94f57938da449a68e3527aead5ebd55ba410adb Reviewed-by: Fabian Kosmale Reviewed-by: Alexey Edelev (cherry picked from commit 7d70edd31cb4c55471ad96e3a1d7114e2c081cf6) --- src/corelib/kernel/qtimer.cpp | 5 ++- .../auto/corelib/kernel/qtimer/CMakeLists.txt | 1 + .../auto/corelib/kernel/qtimer/tst_qtimer.cpp | 38 +++++++++++++++++++ .../auto/gui/kernel/qguitimer/CMakeLists.txt | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 785cf677818..282de8f838c 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -622,8 +622,9 @@ QBindable QTimer::bindableSingleShot() void QTimer::setInterval(int msec) { Q_D(QTimer); - const bool intervalChanged = msec != d->inter; - d->inter.setValue(msec); + d->inter.removeBindingUnlessInWrapper(); + const bool intervalChanged = msec != d->inter.valueBypassingBindings(); + d->inter.setValueBypassingBindings(msec); if (d->id != QTimerPrivate::INV_TIMER) { // create new timer QObject::killTimer(d->id); // restart timer d->id = QObject::startTimer(std::chrono::milliseconds{msec}, d->type); diff --git a/tests/auto/corelib/kernel/qtimer/CMakeLists.txt b/tests/auto/corelib/kernel/qtimer/CMakeLists.txt index a4bcaca8774..a65ccbe0e26 100644 --- a/tests/auto/corelib/kernel/qtimer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qtimer/CMakeLists.txt @@ -14,6 +14,7 @@ qt_internal_add_test(tst_qtimer tst_qtimer.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index 3e6954355a8..910916f77c7 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ private slots: void bindToTimer(); void bindTimer(); + void automatedBindingTests(); }; void tst_QTimer::zeroTimer() @@ -1312,6 +1314,42 @@ void tst_QTimer::bindTimer() QCOMPARE(timer.timerType(), Qt::VeryCoarseTimer); } +void tst_QTimer::automatedBindingTests() +{ + QTimer timer; + + QVERIFY(!timer.isSingleShot()); + QTestPrivate::testReadWritePropertyBasics(timer, true, false, "singleShot"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QTimer::singleShot"); + return; + } + + QCOMPARE_NE(timer.interval(), 10); + QTestPrivate::testReadWritePropertyBasics(timer, 10, 20, "interval"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QTimer::interval"); + return; + } + + QCOMPARE_NE(timer.timerType(), Qt::PreciseTimer); + QTestPrivate::testReadWritePropertyBasics(timer, Qt::PreciseTimer, Qt::CoarseTimer, + "timerType"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QTimer::timerType"); + return; + } + + timer.start(1000); + QVERIFY(timer.isActive()); + QTestPrivate::testReadOnlyPropertyBasics(timer, true, false, "active", + [&timer]() { timer.stop(); }); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QTimer::active"); + return; + } +} + class OrderHelper : public QObject { Q_OBJECT diff --git a/tests/auto/gui/kernel/qguitimer/CMakeLists.txt b/tests/auto/gui/kernel/qguitimer/CMakeLists.txt index cf63294faed..c54f4a6bfc8 100644 --- a/tests/auto/gui/kernel/qguitimer/CMakeLists.txt +++ b/tests/auto/gui/kernel/qguitimer/CMakeLists.txt @@ -11,4 +11,5 @@ qt_internal_add_test(tst_qguitimer LIBRARIES Qt::CorePrivate Qt::Gui + Qt::TestPrivate )