diff options
Diffstat (limited to 'old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp')
-rw-r--r-- | old/tests/qtuitest/tst_qinputgenerator/tst_qinputgenerator.cpp | 756 |
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); +} + |