QTest: don't wait before sending mouse event: increment the timestamp

Tests can run faster now, but we still expect calculations based on
the timestamp (such as QEventPoint::velocity()) to be correct.

Change-Id: Ie962604c9ebd139384dcd89a157de66b4b773cc9
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Shawn Rutledge 2020-11-10 15:30:22 +01:00
parent 1d8dd9a02c
commit f5010c49a3
2 changed files with 22 additions and 27 deletions

View File

@ -84,13 +84,16 @@ namespace QTest
// to depend on platform themes. // to depend on platform themes.
static const int mouseDoubleClickInterval = 500; static const int mouseDoubleClickInterval = 500;
/*! \internal /*! \internal
This function creates a QPA mouse event of type specified by \a action
This function mocks all mouse events by bypassing the windowing system. The and calls QWindowSystemInterface::handleMouseEvent(), simulating the
result is that the mouse events do not come from the system via Qt platform windowing system and bypassing the platform plugin. \a delay is the
plugins, but are created on the spot and immediately available for processing amount of time to be added to the simulated clock so that
by Qt. QInputEvent::timestamp() will be greater than that of the previous
*/ event. We expect all event-handling code to rely on the event
timestamps, not the system clock; therefore tests can be run faster
than real-time.
*/
static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button, static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button,
Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1) Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
{ {
@ -106,10 +109,7 @@ namespace QTest
if (delay == -1 || delay < defaultMouseDelay()) if (delay == -1 || delay < defaultMouseDelay())
delay = defaultMouseDelay(); delay = defaultMouseDelay();
if (delay > 0) { lastMouseTimestamp += qMax(1, delay);
QTest::qWait(delay);
lastMouseTimestamp += delay;
}
if (pos.isNull()) if (pos.isNull())
pos = QPoint(window->width() / 2, window->height() / 2); pos = QPoint(window->width() / 2, window->height() / 2);
@ -127,28 +127,28 @@ namespace QTest
case MouseDClick: case MouseDClick:
qtestMouseButtons.setFlag(button, true); qtestMouseButtons.setFlag(button, true);
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress, qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress,
stateKey, ++lastMouseTimestamp); stateKey, lastMouseTimestamp);
qtestMouseButtons.setFlag(button, false); qtestMouseButtons.setFlag(button, false);
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease, qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease,
stateKey, ++lastMouseTimestamp); stateKey, lastMouseTimestamp);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case MousePress: case MousePress:
case MouseClick: case MouseClick:
qtestMouseButtons.setFlag(button, true); qtestMouseButtons.setFlag(button, true);
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress, qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress,
stateKey, ++lastMouseTimestamp); stateKey, lastMouseTimestamp);
if (action == MousePress) if (action == MousePress)
break; break;
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case MouseRelease: case MouseRelease:
qtestMouseButtons.setFlag(button, false); qtestMouseButtons.setFlag(button, false);
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease, qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease,
stateKey, ++lastMouseTimestamp); stateKey, lastMouseTimestamp);
lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated
break; break;
case MouseMove: case MouseMove:
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, Qt::NoButton, QEvent::MouseMove, qt_handleMouseEvent(w, pos, global, qtestMouseButtons, Qt::NoButton, QEvent::MouseMove,
stateKey, ++lastMouseTimestamp); stateKey, lastMouseTimestamp);
break; break;
default: default:
QTEST_ASSERT(false); QTEST_ASSERT(false);
@ -193,10 +193,7 @@ namespace QTest
if (delay == -1 || delay < defaultMouseDelay()) if (delay == -1 || delay < defaultMouseDelay())
delay = defaultMouseDelay(); delay = defaultMouseDelay();
if (delay > 0) { lastMouseTimestamp += qMax(1, delay);
QTest::qWait(delay);
lastMouseTimestamp += delay;
}
if (action == MouseClick) { if (action == MouseClick) {
mouseEvent(MousePress, widget, button, stateKey, pos); mouseEvent(MousePress, widget, button, stateKey, pos);
@ -226,17 +223,13 @@ namespace QTest
break; break;
case MouseMove: case MouseMove:
QCursor::setPos(widget->mapToGlobal(pos)); QCursor::setPos(widget->mapToGlobal(pos));
#ifdef Q_OS_MAC
QTest::qWait(20);
#else
qApp->processEvents(); qApp->processEvents();
#endif
return; return;
default: default:
QTEST_ASSERT(false); QTEST_ASSERT(false);
} }
QMouseEvent me(meType, pos, widget->mapToGlobal(pos), button, meButton, stateKey, QPointingDevice::primaryPointingDevice()); QMouseEvent me(meType, pos, widget->mapToGlobal(pos), button, meButton, stateKey, QPointingDevice::primaryPointingDevice());
me.setTimestamp(++lastMouseTimestamp); me.setTimestamp(lastMouseTimestamp);
if (action == MouseRelease) // avoid double clicks being generated if (action == MouseRelease) // avoid double clicks being generated
lastMouseTimestamp += mouseDoubleClickInterval; lastMouseTimestamp += mouseDoubleClickInterval;

View File

@ -206,14 +206,16 @@ void tst_QToolButton::task176137_autoRepeatOfAction()
QSignalSpy spy(&action,SIGNAL(triggered())); QSignalSpy spy(&action,SIGNAL(triggered()));
QTest::mousePress (toolButton, Qt::LeftButton); QTest::mousePress (toolButton, Qt::LeftButton);
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, QPoint (), 2000); QTest::qWait(2000);
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, {});
QCOMPARE(spy.count(),1); QCOMPARE(spy.count(),1);
// try again with auto repeat // try again with auto repeat
toolButton->setAutoRepeat (true); toolButton->setAutoRepeat (true);
QSignalSpy repeatSpy(&action,SIGNAL(triggered())); // new spy QSignalSpy repeatSpy(&action,SIGNAL(triggered())); // new spy
QTest::mousePress (toolButton, Qt::LeftButton); QTest::mousePress (toolButton, Qt::LeftButton);
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, QPoint (), 3000); QTest::qWait(3000);
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, {});
const qreal expected = (3000 - toolButton->autoRepeatDelay()) / toolButton->autoRepeatInterval() + 1; const qreal expected = (3000 - toolButton->autoRepeatDelay()) / toolButton->autoRepeatInterval() + 1;
//we check that the difference is small (on some systems timers are not super accurate) //we check that the difference is small (on some systems timers are not super accurate)
qreal diff = (expected - repeatSpy.count()) / expected; qreal diff = (expected - repeatSpy.count()) / expected;