From d01d08971a1ba4d66927a48577041abc5b7df8a2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2015 18:15:53 -0700 Subject: Fix the remainingTime() result after the first activation of a QTimer On Windows, t->timeout was updated only once, at creation time, so the timer would always show as "overdue" after the first activation. The timer is updated to indicate the full remaining time during the slot activation, which is the behavior of the Unix and Glib dispatchers. Task-number: QTBUG-46940 Change-Id: I255870833a024a36adf6ffff13ecadb021c4358c Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp | 59 ++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp') diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index c7011dbc04..1d1432f600 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -54,6 +54,8 @@ private slots: void singleShotTimeout(); void timeout(); void remainingTime(); + void remainingTimeDuringActivation_data(); + void remainingTimeDuringActivation(); void livelock_data(); void livelock(); void timerInfiniteRecursion_data(); @@ -79,14 +81,16 @@ class TimerHelper : public QObject { Q_OBJECT public: - TimerHelper() : QObject(), count(0) + TimerHelper() : QObject(), count(0), remainingTime(-1) { } int count; + int remainingTime; public slots: void timeout(); + void fetchRemainingTime(); }; void TimerHelper::timeout() @@ -94,6 +98,12 @@ void TimerHelper::timeout() ++count; } +void TimerHelper::fetchRemainingTime() +{ + QTimer *timer = static_cast(sender()); + remainingTime = timer->remainingTime(); +} + void tst_QTimer::zeroTimer() { TimerHelper helper; @@ -158,6 +168,53 @@ void tst_QTimer::remainingTime() int remainingTime = timer.remainingTime(); QVERIFY2(qAbs(remainingTime - 150) < 50, qPrintable(QString::number(remainingTime))); + + // wait for the timer to actually fire now + connect(&timer, SIGNAL(timeout()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(helper.count, 1); + + // the timer is still active, so it should have a non-zero remaining time + remainingTime = timer.remainingTime(); + QVERIFY2(remainingTime > 150, qPrintable(QString::number(remainingTime))); +} + +void tst_QTimer::remainingTimeDuringActivation_data() +{ + QTest::addColumn("singleShot"); + QTest::newRow("repeating") << true; + QTest::newRow("single-shot") << true; +} + +void tst_QTimer::remainingTimeDuringActivation() +{ + QFETCH(bool, singleShot); + + TimerHelper helper; + QTimer timer; + + const int timeout = 20; // 20 ms is short enough and should not round down to 0 in any timer mode + + connect(&timer, SIGNAL(timeout()), &helper, SLOT(fetchRemainingTime())); + connect(&timer, SIGNAL(timeout()), &QTestEventLoop::instance(), SLOT(exitLoop())); + timer.start(timeout); + timer.setSingleShot(singleShot); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + if (singleShot) + QCOMPARE(helper.remainingTime, -1); // timer not running + else + QCOMPARE(helper.remainingTime, timeout); + + if (!singleShot) { + // do it again - see QTBUG-46940 + helper.remainingTime = -1; + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(helper.remainingTime, timeout); + } } void tst_QTimer::livelock_data() -- cgit v1.2.3