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

View File

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