summaryrefslogtreecommitdiffstats
path: root/old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp')
-rw-r--r--old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp756
1 files changed, 756 insertions, 0 deletions
diff --git a/old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp b/old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp
new file mode 100644
index 0000000..2c7d484
--- /dev/null
+++ b/old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp
@@ -0,0 +1,756 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QAbstractEventDispatcher>
+#include <QDebug>
+#include <QObject>
+#include <QTest>
+#include <qinputgenerator_p.h>
+
+#include "nativeevent.h"
+
+//TESTED_COMPONENT=QA: Testing Framework (18707)
+
+struct TestKeyEvent {
+ enum Type { KeyPress, KeyRelease, KeyClick };
+
+ TestKeyEvent(TestKeyEvent::Type _type, Qt::Key _key, Qt::KeyboardModifiers _modifiers,
+ bool _autorepeat)
+ : type(_type)
+ , key(_key)
+ , modifiers(_modifiers)
+ , autorepeat(_autorepeat)
+ {}
+
+ TestKeyEvent::Type type;
+ Qt::Key key;
+ Qt::KeyboardModifiers modifiers;
+ bool autorepeat;
+};
+
+typedef QList<TestKeyEvent> TestKeyEventList;
+Q_DECLARE_METATYPE(TestKeyEventList);
+
+typedef QList<QKeyEvent> QKeyEventList;
+Q_DECLARE_METATYPE(QKeyEventList);
+
+struct TestMouseEvent {
+ enum Type {
+ MouseButtonPress,
+ MouseButtonRelease,
+ MouseButtonClick
+ };
+
+ TestMouseEvent(TestMouseEvent::Type _type, const QPoint& _pos, Qt::MouseButtons _buttons)
+ : type(_type)
+ , pos(_pos)
+ , buttons(_buttons)
+ {}
+
+ TestMouseEvent::Type type;
+ QPoint pos;
+ Qt::MouseButtons buttons;
+};
+
+typedef QList<TestMouseEvent> TestMouseEventList;
+Q_DECLARE_METATYPE(TestMouseEventList);
+
+typedef QList<QMouseEvent> QMouseEventList;
+Q_DECLARE_METATYPE(QMouseEventList);
+
+QString toString(QKeyEvent const& e)
+{
+ QString out;
+ out += (e.type() == QEvent::KeyPress) ? "press" : "release";
+ out += ", " + QString("key:0x%1").arg(e.key(),8,16,QLatin1Char('0'));
+ out += "," + QString("modifiers:0x%1").arg(e.modifiers(),8,16,QLatin1Char('0'));
+ out += "," + QString("isAutoRepeat:%1").arg(e.isAutoRepeat());
+ out += "," + QString("nativeModifiers:0x%1").arg(e.nativeModifiers(),8,16,QLatin1Char('0'));
+ out += "," + QString("nativeScanCode:0x%1").arg(e.nativeScanCode(),8,16,QLatin1Char('0'));
+ out += "," + QString("nativeVirtualKey:0x%1").arg(e.nativeVirtualKey(),8,16,QLatin1Char('0'));
+ out += ",text:" + e.text();
+ /*
+ Only check count if it has some text.
+ When doing a 'Shift' key or similar, whether or not there's a count depends on
+ the platform, so we'll treat it as undefined.
+ */
+ if (!e.text().isEmpty())
+ out += "," + QString("count:%1").arg(e.count());
+ return out;
+}
+
+QString toString(QKeyEventList const& l)
+{
+ QString out;
+ QString sep = " ";
+ for (int i = 0; i < l.count(); ++i) {
+ out += sep + toString(l.at(i));
+ sep = "\n ";
+ }
+ return out;
+}
+
+QString toString(QPoint const& p)
+{
+ return QString("(%1,%2)").arg(p.x()).arg(p.y());
+}
+
+QString toString(Qt::MouseButton b)
+{
+ switch (b) {
+ case Qt::NoButton:
+ return "0";
+ case Qt::LeftButton:
+ return "left";
+ case Qt::RightButton:
+ return "right";
+ case Qt::MidButton:
+ return "mid";
+ case Qt::XButton1:
+ return "xbutton1";
+ case Qt::XButton2:
+ return "xbutton2";
+ default:
+ return QString("0x%1").arg(b, 8, 16, QLatin1Char('0'));
+ }
+}
+
+QString toString(Qt::MouseButtons b)
+{
+ QString out;
+ if (!b || (b & (~Qt::MouseButtonMask))) {
+ out = QString("0x%1").arg(b,8,16,QLatin1Char('0'));
+ }
+ else {
+ static const Qt::MouseButton AllButtons[] = {
+ Qt::LeftButton,
+ Qt::RightButton,
+ Qt::MidButton,
+ Qt::XButton1,
+ Qt::XButton2
+ };
+ QString sep;
+ for (unsigned int i = 0; i < sizeof(AllButtons)/sizeof(AllButtons[0]); ++i) {
+ if (b & AllButtons[i]) {
+ out += sep + toString(Qt::MouseButton((int)(b & AllButtons[i])));
+ sep = "|";
+ }
+ }
+ }
+ return out;
+}
+
+QString toString(QMouseEvent const& e)
+{
+ QString out;
+ switch (e.type()) {
+ case QEvent::MouseButtonPress:
+ out += "press";
+ break;
+ case QEvent::MouseButtonRelease:
+ out += "release";
+ break;
+ case QEvent::MouseButtonDblClick:
+ out += "doubleclick";
+ break;
+ case QEvent::MouseMove:
+ out += "move";
+ break;
+ default:
+ out += "unknown_type";
+ }
+ out += ", "+ QString("pos:%1").arg(toString(e.pos()));
+ out += "," + QString("globalPos:%1").arg(toString(e.globalPos()));
+ out += "," + QString("button:%1").arg(toString(e.button()));
+ out += "," + QString("buttons:%1").arg(toString(e.buttons()));
+ out += "," + QString("modifiers:0x%1").arg(e.modifiers(),8,16,QLatin1Char('0'));
+ return out;
+}
+
+QString toString(QMouseEventList const& l)
+{
+ QString out;
+ QString sep = " ";
+ for (int i = 0; i < l.count(); ++i) {
+ out += sep + toString(l.at(i));
+ sep = "\n ";
+ }
+ return out;
+}
+
+QString toString(NativeEvent const& e)
+{
+ QString out;
+ out += e.type;
+
+ QString sep = " ";
+ typedef QPair<QString,QString> StringPair;
+ foreach (StringPair const& p, e.things) {
+ out += sep + p.first + ":" + p.second;
+ sep = ",";
+ }
+
+ return out;
+}
+
+namespace QTest {
+template<>
+inline bool qCompare(QKeyEvent const &e1, QKeyEvent const &e2,
+ const char* actual, const char* expected, const char* file, int line)
+{
+ return qCompare(toString(e1), toString(e2), actual, expected, file, line);
+}
+template<>
+inline bool qCompare(QMouseEvent const &e1, QMouseEvent const &e2,
+ const char* actual, const char* expected, const char* file, int line)
+{
+ return qCompare(toString(e1), toString(e2), actual, expected, file, line);
+}
+}
+
+
+class tst_QInputGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QInputGenerator();
+ void eventTest();
+
+private slots:
+ void keyEvent();
+ void keyEvent_data();
+ void mouseEvent();
+ void mouseEvent_data();
+ void initTestCase();
+ void init();
+
+private:
+ template <typename T>
+ bool waitForCount(QList<T> const* list, int howmany, int timeout = 5000);
+ bool eventFilter(QObject*, QEvent*);
+ template <typename T1, typename T2>
+ static void dumpEvents(QList<T1> const& actual, QList<T2> const& expected);
+ static bool nativeEventFilter(void* event);
+
+private:
+ QList<QKeyEvent> m_keyEvents;
+ QList<QMouseEvent> m_mouseEvents;
+ QEventLoop* m_eventTestLoop;
+ QTime m_eventTestTime;
+ static tst_QInputGenerator* s_eventTestInstance;
+};
+tst_QInputGenerator* tst_QInputGenerator::s_eventTestInstance = 0;
+
+tst_QInputGenerator::tst_QInputGenerator()
+ : QObject()
+ , m_keyEvents()
+ , m_mouseEvents()
+ , m_eventTestLoop(0)
+ , m_eventTestTime()
+{
+}
+
+void tst_QInputGenerator::initTestCase()
+{
+ qApp->installEventFilter(this);
+}
+
+void tst_QInputGenerator::init()
+{
+ m_keyEvents.clear();
+ m_mouseEvents.clear();
+}
+
+void tst_QInputGenerator::keyEvent()
+{
+ QFETCH(TestKeyEventList, testEvents);
+ QFETCH(QKeyEventList, qtEvents);
+
+ QWidget w;
+ w.setFocus();
+ w.setFixedSize(1024, 768);
+ w.show();
+
+ QInputGenerator input;
+
+ /* Simulate all test events. */
+ while (testEvents.count()) {
+ TestKeyEvent next = testEvents.takeFirst();
+
+ if (next.type == TestKeyEvent::KeyPress) {
+ input.keyPress(next.key, next.modifiers, next.autorepeat);
+ }
+ else if (next.type == TestKeyEvent::KeyRelease) {
+ input.keyRelease(next.key, next.modifiers);
+ }
+ else if (next.type == TestKeyEvent::KeyClick) {
+ input.keyClick(next.key, next.modifiers);
+ }
+ }
+
+ /* Wait until we get the expected amount of qt events. */
+ if (m_keyEvents.count() < qtEvents.count()) {
+ bool waited = waitForCount(&m_keyEvents, qtEvents.count());
+ if (!waited) {
+ dumpEvents(m_keyEvents, qtEvents);
+ }
+ QVERIFY2(waited, qPrintable(QString("Expected %1 QKeyEvent(s) but got %2").arg(qtEvents.count()).arg(m_keyEvents.count())));
+ }
+
+ /* Compare actual qt events with expected. */
+ for (int i = 0; i < qtEvents.count(); ++i) {
+ const QKeyEvent& actual = m_keyEvents[i];
+ const QKeyEvent& expected = qtEvents[i];
+ if (!QTest::qCompare(actual, expected, "actual", "expected", __FILE__, __LINE__)) {
+ dumpEvents(m_keyEvents, qtEvents);
+ return;
+ }
+ }
+}
+
+void tst_QInputGenerator::keyEvent_data()
+{
+ QTest::addColumn<TestKeyEventList>("testEvents");
+ QTest::addColumn<QKeyEventList> ("qtEvents");
+
+ /* Make event definition a little less verbose... */
+#define TE(Type,K,Mod,Repeat) TestKeyEvent(TestKeyEvent::Key##Type, Qt::Key_##K, Mod, Repeat)
+#define QE(Type,K,Mod,Text,Repeat,Count) QKeyEvent(QEvent::Key##Type, Qt::Key_##K, Mod, QLatin1String(Text), Repeat, Count)
+ QTest::newRow("a (press only)")
+ << (TestKeyEventList() << TE(Press, A, 0, false))
+ << (QKeyEventList() << QE(Press, A, 0, "a", false, 1))
+ ;
+ QTest::newRow("a (release only)")
+ << (TestKeyEventList() << TE(Release, A, 0, false))
+ << (QKeyEventList() << QE(Release, A, 0, "a", false, 1))
+ ;
+ QTest::newRow("autorepeat b")
+ << (TestKeyEventList()
+ << TE(Press, B, 0, false)
+ /*
+ << TE(Press, B, 0, true)
+ << TE(Press, B, 0, true)
+ << TE(Press, B, 0, true)
+ << TE(Press, B, 0, true)
+ << TE(Press, B, 0, true)
+ */
+ << TE(Release, B, 0, false)
+
+ )
+ << (QKeyEventList()
+ << QE(Press, B, 0, "b", false, 1)
+ /*
+ << QE(Press, B, 0, "b", true, 1)
+ << QE(Press, B, 0, "b", true, 1)
+ << QE(Press, B, 0, "b", true, 1)
+ << QE(Press, B, 0, "b", true, 1)
+ << QE(Press, B, 0, "b", true, 1)
+ */
+ << QE(Release, B, 0, "b", false, 1)
+ )
+ ;
+ QTest::newRow("dog")
+ << (TestKeyEventList()
+ << TE(Click, D, 0, false)
+ << TE(Click, O, 0, false)
+ << TE(Click, G, 0, false)
+ )
+ << (QKeyEventList()
+ << QE(Press, D, 0, "d", false, 1) << QE(Release, D, 0, "d", false, 1)
+ << QE(Press, O, 0, "o", false, 1) << QE(Release, O, 0, "o", false, 1)
+ << QE(Press, G, 0, "g", false, 1) << QE(Release, G, 0, "g", false, 1)
+ )
+ ;
+ QTest::newRow("mIXEd caSE")
+ << (TestKeyEventList()
+ << TE(Click, M, 0, false)
+ << TE(Click, I, Qt::ShiftModifier, false)
+ << TE(Click, X, Qt::ShiftModifier, false)
+ << TE(Click, E, Qt::ShiftModifier, false)
+ << TE(Click, D, 0, false)
+ << TE(Click, Space, 0, false)
+ << TE(Click, C, 0, false)
+ << TE(Click, A, 0, false)
+ << TE(Click, S, Qt::ShiftModifier, false)
+ << TE(Click, E, Qt::ShiftModifier, false)
+ )
+ << (QKeyEventList()
+ << QE(Press, M, 0, "m", false, 1) << QE(Release, M, 0, "m", false, 1)
+ << QE(Press, Shift, 0, "", false, 0)
+ << QE(Press, I, Qt::ShiftModifier, "I", false, 1) << QE(Release, I, Qt::ShiftModifier, "I", false, 1)
+ << QE(Press, X, Qt::ShiftModifier, "X", false, 1) << QE(Release, X, Qt::ShiftModifier, "X", false, 1)
+ << QE(Press, E, Qt::ShiftModifier, "E", false, 1) << QE(Release, E, Qt::ShiftModifier, "E", false, 1)
+ << QE(Release, Shift, Qt::ShiftModifier, "", false, 0)
+ << QE(Press, D, 0, "d", false, 1) << QE(Release, D, 0, "d", false, 1)
+ << QE(Press, Space, 0, " ", false, 1) << QE(Release, Space, 0, " ", false, 1)
+ << QE(Press, C, 0, "c", false, 1) << QE(Release, C, 0, "c", false, 1)
+ << QE(Press, A, 0, "a", false, 1) << QE(Release, A, 0, "a", false, 1)
+ << QE(Press, Shift, 0, "", false, 0)
+ << QE(Press, S, Qt::ShiftModifier, "S", false, 1) << QE(Release, S, Qt::ShiftModifier, "S", false, 1)
+ << QE(Press, E, Qt::ShiftModifier, "E", false, 1) << QE(Release, E, Qt::ShiftModifier, "E", false, 1)
+ )
+ ;
+#undef TE
+#undef QE
+}
+
+void tst_QInputGenerator::mouseEvent()
+{
+ QFETCH(TestMouseEventList, testEvents);
+ QFETCH(QMouseEventList, qtEvents);
+
+ QWidget w1(0, Qt::FramelessWindowHint);
+ w1.setFocus();
+ w1.setGeometry(0, 0, 100, 100);
+ w1.setMouseTracking(false);
+ w1.show();
+
+ QWidget w2(0, Qt::FramelessWindowHint);
+ w2.setFocus();
+ w2.setGeometry(100, 0, 100, 100);
+ w2.setMouseTracking(false);
+ w2.show();
+
+ QWidget w3(0, Qt::FramelessWindowHint);
+ w3.setFocus();
+ w3.setGeometry(0, 100, 100, 100);
+ w3.setMouseTracking(false);
+ w3.show();
+
+ QWidget w4(0, Qt::FramelessWindowHint);
+ w4.setFocus();
+ w4.setGeometry(100, 100, 100, 100);
+ w4.setMouseTracking(false);
+ w4.show();
+
+ /* Make sure we go slow enough to avoid accidental double clicks */
+ int dblclick = qApp->doubleClickInterval();
+ QTest::qWait(dblclick);
+
+ QInputGenerator input;
+
+ /* Simulate all test events. */
+ while (testEvents.count()) {
+ TestMouseEvent next = testEvents.takeFirst();
+
+ if (next.type == TestMouseEvent::MouseButtonPress) {
+ input.mousePress(next.pos, next.buttons);
+ }
+ else if (next.type == TestMouseEvent::MouseButtonRelease) {
+ input.mouseRelease(next.pos, next.buttons);
+ }
+ else if (next.type == TestMouseEvent::MouseButtonClick) {
+ input.mouseClick(next.pos, next.buttons);
+ }
+ }
+
+ /* Wait until we get the expected amount of qt events. */
+ if (m_mouseEvents.count() < qtEvents.count()) {
+ bool waited = waitForCount(&m_mouseEvents, qtEvents.count());
+ if (!waited) {
+ dumpEvents(m_mouseEvents, qtEvents);
+ }
+ QVERIFY2(waited, qPrintable(QString("Expected %1 QMouseEvent(s) but got %2").arg(qtEvents.count()).arg(m_mouseEvents.count())));
+ }
+
+ /* Compare actual qt events with expected. */
+ for (int i = 0; i < qtEvents.count(); ++i) {
+ const QMouseEvent& actual = m_mouseEvents[i];
+ const QMouseEvent& expected = qtEvents[i];
+ if (!QTest::qCompare(actual, expected, "actual", "expected", __FILE__, __LINE__)) {
+ dumpEvents(m_mouseEvents, qtEvents);
+ return;
+ }
+ }
+}
+
+void tst_QInputGenerator::mouseEvent_data()
+{
+ QTest::addColumn<TestMouseEventList>("testEvents");
+ QTest::addColumn<QMouseEventList> ("qtEvents");
+
+ /*
+ To test mapping of global to local positions, 4 widgets are laid out in a 2x2 grid.
+ Each widget is 100x100 in size. The widgets are arranged so they sit exactly in the
+ top left 200x200 of the screen. The widgets are asked to be frameless.
+ */
+
+ /* Make event definition a little less verbose... */
+#define TE(Type,Pos,Buttons) TestMouseEvent(TestMouseEvent::Mouse##Type, Pos, Buttons)
+#define QE(Type,Pos,GlobalPos,Button,Buttons,Mod) QMouseEvent(QEvent::Mouse##Type, Pos, GlobalPos,Qt::MouseButton(Button),Buttons,Mod)
+ QTest::newRow("single left press, tl")
+ << (TestMouseEventList() << TE(ButtonPress, QPoint(50,50), Qt::LeftButton))
+ << (QMouseEventList() << QE(ButtonPress, QPoint(50,50), QPoint(50,50), Qt::LeftButton, Qt::LeftButton, 0))
+ ;
+ QTest::newRow("single left press, tr")
+ << (TestMouseEventList() << TE(ButtonPress, QPoint(150,50), Qt::LeftButton))
+ << (QMouseEventList() << QE(ButtonPress, QPoint(50,50), QPoint(150,50), Qt::LeftButton, Qt::LeftButton, 0))
+ ;
+ QTest::newRow("single left press, bl")
+ << (TestMouseEventList() << TE(ButtonPress, QPoint(25,150), Qt::LeftButton))
+ << (QMouseEventList() << QE(ButtonPress, QPoint(25,50), QPoint(25,150), Qt::LeftButton, Qt::LeftButton, 0))
+ ;
+ QTest::newRow("single left press, br")
+ << (TestMouseEventList() << TE(ButtonPress, QPoint(150,125),Qt::LeftButton))
+ << (QMouseEventList() << QE(ButtonPress, QPoint(50,25), QPoint(150,125),Qt::LeftButton, Qt::LeftButton, 0))
+ ;
+
+ QTest::newRow("single right click, tl")
+ << (TestMouseEventList() << TE(ButtonClick, QPoint(50,50), Qt::RightButton))
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(50,50), QPoint(50,50), Qt::RightButton, Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(50,50), QPoint(50,50), Qt::RightButton, 0, 0)
+ )
+ ;
+ QTest::newRow("single right click, tr")
+ << (TestMouseEventList() << TE(ButtonClick, QPoint(150,50), Qt::RightButton))
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(50,50), QPoint(150,50), Qt::RightButton, Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(50,50), QPoint(150,50), Qt::RightButton, 0, 0)
+ )
+ ;
+ QTest::newRow("single right click, bl")
+ << (TestMouseEventList() << TE(ButtonClick, QPoint(25,150), Qt::RightButton))
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(25,50), QPoint(25,150), Qt::RightButton, Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(25,50), QPoint(25,150), Qt::RightButton, 0, 0)
+ )
+ ;
+ QTest::newRow("single right click, br")
+ << (TestMouseEventList() << TE(ButtonClick, QPoint(150,125),Qt::RightButton))
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(50,25), QPoint(150,125), Qt::RightButton, Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(50,25), QPoint(150,125), Qt::RightButton, 0, 0)
+ )
+ ;
+
+ QTest::newRow("double middle click")
+ << (TestMouseEventList()
+ << TE(ButtonClick, QPoint(20,30),Qt::MidButton)
+ << TE(ButtonClick, QPoint(20,30),Qt::MidButton)
+ )
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(20,30), QPoint(20,30), Qt::MidButton, Qt::MidButton, 0)
+ << QE(ButtonRelease, QPoint(20,30), QPoint(20,30), Qt::MidButton, 0, 0)
+ << QE(ButtonDblClick, QPoint(20,30), QPoint(20,30), Qt::MidButton, Qt::MidButton, 0)
+ << QE(ButtonRelease, QPoint(20,30), QPoint(20,30), Qt::MidButton, 0, 0)
+ )
+ ;
+
+ QTest::newRow("middle drag")
+ << (TestMouseEventList()
+ << TE(ButtonPress, QPoint(20,30),Qt::MidButton)
+ << TE(ButtonPress, QPoint(20,31),Qt::MidButton)
+ << TE(ButtonPress, QPoint(21,32),Qt::MidButton)
+ << TE(ButtonPress, QPoint(21,33),Qt::MidButton)
+ << TE(ButtonPress, QPoint(22,34),Qt::MidButton)
+ << TE(ButtonPress, QPoint(22,35),Qt::MidButton)
+ << TE(ButtonPress, QPoint(23,36),Qt::MidButton)
+ << TE(ButtonPress, QPoint(23,37),Qt::MidButton)
+ << TE(ButtonPress, QPoint(24,38),Qt::MidButton)
+ << TE(ButtonPress, QPoint(24,39),Qt::MidButton)
+ << TE(ButtonRelease, QPoint(25,40),Qt::MidButton)
+ )
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(20,30), QPoint(20,30), Qt::MidButton, Qt::MidButton, 0)
+ /* Note, exactly how many move events we expect depends on platform... */
+ << QE(Move, QPoint(25,40), QPoint(25,40), 0, Qt::MidButton, 0)
+ << QE(ButtonRelease, QPoint(25,40), QPoint(25,40), Qt::MidButton, 0, 0)
+ )
+ ;
+
+ QTest::newRow("multiple buttons with shaky hands")
+ << (TestMouseEventList()
+ << TE(ButtonPress, QPoint(110,120),Qt::MidButton)
+ << TE(ButtonPress, QPoint(110,125),Qt::RightButton)
+ << TE(ButtonPress, QPoint(105,105),Qt::LeftButton)
+ << TE(ButtonRelease, QPoint(105,107),Qt::RightButton)
+ << TE(ButtonRelease, QPoint(110,119),Qt::MidButton)
+ << TE(ButtonPress, QPoint(110,112),Qt::RightButton)
+ << TE(ButtonRelease, QPoint(103,102),Qt::LeftButton)
+ << TE(ButtonRelease, QPoint(111,103),Qt::RightButton)
+ )
+ << (QMouseEventList()
+ << QE(ButtonPress, QPoint(10,20),QPoint(110,120), Qt::MidButton, Qt::MidButton, 0)
+
+ << QE(Move, QPoint(10,25),QPoint(110,125), 0, Qt::MidButton, 0)
+ << QE(ButtonPress, QPoint(10,25),QPoint(110,125), Qt::RightButton, Qt::MidButton|Qt::RightButton, 0)
+
+ << QE(Move, QPoint(5,5), QPoint(105,105), 0, Qt::MidButton|Qt::RightButton, 0)
+ << QE(ButtonPress, QPoint(5,5), QPoint(105,105), Qt::LeftButton, Qt::MidButton|Qt::RightButton|Qt::LeftButton, 0)
+
+ << QE(Move, QPoint(5,7), QPoint(105,107), 0, Qt::MidButton|Qt::RightButton|Qt::LeftButton, 0)
+ << QE(ButtonRelease, QPoint(5,7), QPoint(105,107), Qt::RightButton, Qt::MidButton|Qt::LeftButton, 0)
+
+ << QE(Move, QPoint(10,19),QPoint(110,119), 0, Qt::MidButton|Qt::LeftButton, 0)
+ << QE(ButtonRelease, QPoint(10,19),QPoint(110,119), Qt::MidButton, Qt::LeftButton, 0)
+
+ << QE(Move, QPoint(10,12),QPoint(110,112), 0, Qt::LeftButton, 0)
+ << QE(ButtonPress, QPoint(10,12),QPoint(110,112), Qt::RightButton, Qt::LeftButton|Qt::RightButton, 0)
+
+ << QE(Move, QPoint(3,2), QPoint(103,102), 0, Qt::LeftButton|Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(3,2), QPoint(103,102), Qt::LeftButton, Qt::RightButton, 0)
+
+ << QE(Move, QPoint(11,3), QPoint(111,103), 0, Qt::RightButton, 0)
+ << QE(ButtonRelease, QPoint(11,3), QPoint(111,103), Qt::RightButton, 0, 0)
+ )
+ ;
+#undef TE
+#undef QE
+}
+
+bool tst_QInputGenerator::nativeEventFilter(void* event)
+{
+ tst_QInputGenerator* that = tst_QInputGenerator::s_eventTestInstance;
+ if (!that || !that->m_eventTestLoop) return false;
+
+ if (NativeEvent::isInteresting(event)) {
+ qDebug() << that->m_eventTestTime.elapsed() << qPrintable(toString(NativeEvent(event)));
+ that->m_eventTestLoop->quit();
+ }
+
+ return false;
+}
+
+void tst_QInputGenerator::eventTest()
+{
+ qApp->installEventFilter(this);
+ QAbstractEventDispatcher* dispatch = QAbstractEventDispatcher::instance();
+ dispatch->setEventFilter(tst_QInputGenerator::nativeEventFilter);
+ tst_QInputGenerator::s_eventTestInstance = this;
+
+ m_eventTestTime.start();
+
+ QWidget w;
+ w.setFixedSize(800,600);
+ w.show();
+
+ QEventLoop loop;
+ m_eventTestLoop = &loop;
+
+ qDebug() << "Running event test; use keyboard/mouse to interact with displayed widget.";
+ while (w.isVisible()) {
+ loop.exec();
+ }
+ m_eventTestLoop = 0;
+}
+
+bool tst_QInputGenerator::eventFilter(QObject* o, QEvent* e)
+{
+ QEvent::Type type = e->type();
+ if (type == QEvent::KeyPress || type == QEvent::KeyRelease) {
+ if (m_eventTestLoop) {
+ qDebug() << m_eventTestTime.elapsed() << "key" << qPrintable(toString(*static_cast<QKeyEvent*>(e)));
+ m_eventTestLoop->quit();
+ goto end;
+ }
+ m_keyEvents << *static_cast<QKeyEvent*>(e);
+ }
+ else if (type >= QEvent::MouseButtonPress && type <= QEvent::MouseMove) {
+ /*
+ Even when mouse tracking is turned off, Qt still generates events for mouse
+ moves on some platforms. Discard them, since it's unpredictable how many
+ there might be.
+ */
+ QMouseEvent* me = static_cast<QMouseEvent*>(e);
+ if (type == QEvent::MouseMove && o->isWidgetType()
+ && !static_cast<QWidget*>(o)->hasMouseTracking() && !me->buttons()) {
+ }
+ else {
+ if (m_eventTestLoop) {
+ qDebug() << m_eventTestTime.elapsed() << "mouse" << qPrintable(toString(*me));
+ m_eventTestLoop->quit();
+ goto end;
+ }
+ m_mouseEvents << *me;
+ }
+ }
+
+end:
+ return QObject::eventFilter(o,e);
+}
+
+template <typename T>
+bool tst_QInputGenerator::waitForCount(QList<T> const* list, int howmany, int timeout)
+{
+ while (list->count() < howmany && timeout > 0) {
+ QTest::qWait(10);
+ timeout -= 10;
+ }
+ return (list->count() >= howmany);
+}
+
+template <typename T1, typename T2>
+void tst_QInputGenerator::dumpEvents(QList<T1> const& actual, QList<T2> const& expected)
+{
+ qWarning("Events leading up to failure:");
+ qWarning("Actual:");
+ for (int i = 0; i < actual.count(); ++i) {
+ qWarning(qPrintable(QString(" %1").arg(toString(actual.at(i)))));
+ }
+ qWarning("Expected:");
+ for (int i = 0; i < expected.count(); ++i) {
+ qWarning(qPrintable(QString(" %1").arg(toString(expected.at(i)))));
+ }
+}
+
+#include "tst_qinputgenerator.moc"
+
+int main(int argc, char** argv)
+{
+ QApplication app(argc, argv);
+
+ bool eventTest = false;
+ for (int i = 0; i < argc; ++i) {
+ if (QByteArray(argv[i]) == "eventTest") {
+ eventTest = true;
+ }
+ }
+
+ tst_QInputGenerator test;
+ if (eventTest) {
+ test.eventTest();
+ return 0;
+ }
+ return QTest::qExec(&test, argc, argv);
+}
+