diff options
Diffstat (limited to 'src/imports/testlib')
-rw-r--r-- | src/imports/testlib/TestCase.qml | 17 | ||||
-rw-r--r-- | src/imports/testlib/dependencies.json | 1 | ||||
-rw-r--r-- | src/imports/testlib/main.cpp | 116 | ||||
-rw-r--r-- | src/imports/testlib/plugins.qmltypes | 368 | ||||
-rw-r--r-- | src/imports/testlib/quicktestevent.cpp | 471 | ||||
-rw-r--r-- | src/imports/testlib/quicktestevent_p.h | 132 | ||||
-rw-r--r-- | src/imports/testlib/quicktestresultforeign_p.h | 68 | ||||
-rw-r--r-- | src/imports/testlib/quicktestutil.cpp | 111 | ||||
-rw-r--r-- | src/imports/testlib/quicktestutil_p.h | 88 | ||||
-rw-r--r-- | src/imports/testlib/testlib.pro | 13 |
10 files changed, 904 insertions, 481 deletions
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 20c5ce6418..380b7e38d7 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -198,7 +198,7 @@ import Qt.test.qtestroot 1.0 } \endcode - The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence() + The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence() and mouseMove() methods can be used to simulate mouse events in a similar fashion. @@ -1331,7 +1331,7 @@ Item { If \a item is obscured by another item, or a child of \a item occupies that position, then the event will be delivered to the other item instead. - \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() + \sa mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() */ function mousePress(item, x, y, button, modifiers, delay) { if (!qtest_verifyItem(item, "mousePress")) @@ -1365,7 +1365,7 @@ Item { If \a item is obscured by another item, or a child of \a item occupies that position, then the event will be delivered to the other item instead. - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() + \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() */ function mouseRelease(item, x, y, button, modifiers, delay) { if (!qtest_verifyItem(item, "mouseRelease")) @@ -1398,7 +1398,7 @@ Item { If \a item is obscured by another item, or a child of \a item occupies that position, then the event will be delivered to the other item instead. - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel() + \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel() */ function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) { if (!qtest_verifyItem(item, "mouseDrag")) @@ -1453,7 +1453,7 @@ Item { If \a item is obscured by another item, or a child of \a item occupies that position, then the event will be delivered to the other item instead. - \sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() + \sa mousePress(), mouseRelease(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel() */ function mouseClick(item, x, y, button, modifiers, delay) { if (!qtest_verifyItem(item, "mouseClick")) @@ -1475,6 +1475,7 @@ Item { /*! \qmlmethod TestCase::mouseDoubleClick(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + \deprecated Simulates double-clicking a mouse \a button with optional \a modifiers on an \a item. The position of the click is defined by \a x and \a y. @@ -1528,7 +1529,7 @@ Item { This QML method was introduced in Qt 5.5. - \sa mouseDoubleClick(), mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel() + \sa mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel() */ function mouseDoubleClickSequence(item, x, y, button, modifiers, delay) { if (!qtest_verifyItem(item, "mouseDoubleClickSequence")) @@ -1560,7 +1561,7 @@ Item { If \a item is obscured by another item, or a child of \a item occupies that position, then the event will be delivered to the other item instead. - \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel() + \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel() */ function mouseMove(item, x, y, delay, buttons) { if (!qtest_verifyItem(item, "mouseMove")) @@ -1588,7 +1589,7 @@ Item { The \a xDelta and \a yDelta contain the wheel rotation distance in eighths of a degree. see \l QWheelEvent::angleDelta() for more details. - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta() + \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta() */ function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) { if (!qtest_verifyItem(item, "mouseWheel")) diff --git a/src/imports/testlib/dependencies.json b/src/imports/testlib/dependencies.json new file mode 100644 index 0000000000..b2c4125178 --- /dev/null +++ b/src/imports/testlib/dependencies.json @@ -0,0 +1 @@ +["QtQuick 2.0", "QtQuick.Window 2.0"] diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp index c52cf417a6..83fc150e6c 100644 --- a/src/imports/testlib/main.cpp +++ b/src/imports/testlib/main.cpp @@ -37,123 +37,33 @@ ** ****************************************************************************/ -#include <private/qv4scopedvalue_p.h> +#include "quicktestevent_p.h" +#include "quicktestutil_p.h" + #include <QtQml/qqmlextensionplugin.h> #include <QtQml/qqml.h> -#include <QtQml/qjsvalue.h> -#include <QtQml/qjsengine.h> -#include "QtQuickTest/private/quicktestresult_p.h" -#include "QtQuickTest/private/quicktestevent_p.h" -#include "private/qtestoptions_p.h" -#include "QtQuick/qquickitem.h" -#include <QtQml/private/qqmlengine_p.h> -#include <QtGui/QGuiApplication> -#include <QtGui/qstylehints.h> +#include <QtQuickTest/quicktest.h> +#include <QtQuickTest/private/quicktestresult_p.h> +#include <QtQuickTest/private/qtestoptions_p.h> QML_DECLARE_TYPE(QuickTestResult) QML_DECLARE_TYPE(QuickTestEvent) - -#include <QtDebug> - -QT_BEGIN_NAMESPACE - -class QuickTestUtil : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged) - Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged) -public: - QuickTestUtil(QObject *parent = nullptr) - :QObject(parent) - {} - - ~QuickTestUtil() override - {} - bool printAvailableFunctions() const - { - return QTest::printAvailableFunctions; - } - int dragThreshold() const { return QGuiApplication::styleHints()->startDragDistance(); } - -Q_SIGNALS: - void printAvailableFunctionsChanged(); - void dragThresholdChanged(); - -public Q_SLOTS: - - QJSValue typeName(const QVariant& v) const - { - QString name(v.typeName()); - if (v.canConvert<QObject*>()) { - QQmlType type; - const QMetaObject *mo = v.value<QObject*>()->metaObject(); - while (!type.isValid() && mo) { - type = QQmlMetaType::qmlType(mo); - mo = mo->superClass(); - } - if (type.isValid()) { - name = type.qmlTypeName(); - } - } - - QQmlEngine *engine = qmlEngine(this); - QV4::ExecutionEngine *v4 = engine->handle(); - return QJSValue(v4, v4->newString(name)->asReturnedValue()); - } - - bool compare(const QVariant& act, const QVariant& exp) const { - return act == exp; - } - - QJSValue callerFile(int frameIndex = 0) const - { - QQmlEngine *engine = qmlEngine(this); - QV4::ExecutionEngine *v4 = engine->handle(); - QV4::Scope scope(v4); - - QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2); - return (stack.size() > frameIndex + 1) - ? QJSValue(v4, v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue()) - : QJSValue(); - } - int callerLine(int frameIndex = 0) const - { - QQmlEngine *engine = qmlEngine(this); - QV4::ExecutionEngine *v4 = engine->handle(); - - QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2); - if (stack.size() > frameIndex + 1) - return stack.at(frameIndex + 1).line; - return -1; - } -}; - -QT_END_NAMESPACE - QML_DECLARE_TYPE(QuickTestUtil) +extern void qml_register_types_QtTest(); + QT_BEGIN_NAMESPACE -class QTestQmlModule : public QQmlExtensionPlugin +class QTestQmlModule : public QQmlEngineExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) public: - QTestQmlModule(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { } - void registerTypes(const char *uri) override + QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest")); - qmlRegisterType<QuickTestResult, 0>(uri,1,0,"TestResult"); - qmlRegisterType<QuickTestResult, 1>(uri,1,1,"TestResult"); - qmlRegisterType<QuickTestResult, 13>(uri,1,13,"TestResult"); - qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent"); - qmlRegisterType<QuickTestEvent>(uri,1,2,"TestEvent"); - qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil"); - qmlRegisterAnonymousType<QQuickTouchEventSequence>(uri, 1); - - // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward - qmlRegisterModule(uri, 1, QT_VERSION_MINOR); + volatile auto registration = &qml_register_types_QtTest; + Q_UNUSED(registration); } }; diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes deleted file mode 100644 index 6a1371e5f1..0000000000 --- a/src/imports/testlib/plugins.qmltypes +++ /dev/null @@ -1,368 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtTest 1.14' - -Module { - dependencies: ["QtQuick 2.0", "QtQuick.Window 2.0"] - Component { - name: "QQuickTouchEventSequence" - prototype: "QObject" - Method { - name: "press" - type: "QObject*" - Parameter { name: "touchId"; type: "int" } - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - } - Method { - name: "move" - type: "QObject*" - Parameter { name: "touchId"; type: "int" } - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - } - Method { - name: "release" - type: "QObject*" - Parameter { name: "touchId"; type: "int" } - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - } - Method { - name: "stationary" - type: "QObject*" - Parameter { name: "touchId"; type: "int" } - } - Method { name: "commit"; type: "QObject*" } - } - Component { - name: "QuickTestEvent" - prototype: "QObject" - exports: ["QtTest/TestEvent 1.0", "QtTest/TestEvent 1.2"] - exportMetaObjectRevisions: [0, 0] - Property { name: "defaultMouseDelay"; type: "int"; isReadonly: true } - Method { - name: "keyPress" - type: "bool" - Parameter { name: "key"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keyRelease" - type: "bool" - Parameter { name: "key"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keyClick" - type: "bool" - Parameter { name: "key"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keyPressChar" - type: "bool" - Parameter { name: "character"; type: "string" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keyReleaseChar" - type: "bool" - Parameter { name: "character"; type: "string" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keyClickChar" - type: "bool" - Parameter { name: "character"; type: "string" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "keySequence" - revision: 2 - type: "bool" - Parameter { name: "keySequence"; type: "QVariant" } - } - Method { - name: "mousePress" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "button"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "mouseRelease" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "button"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "mouseClick" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "button"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "mouseDoubleClick" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "button"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "mouseDoubleClickSequence" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "button"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "mouseMove" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "delay"; type: "int" } - Parameter { name: "buttons"; type: "int" } - } - Method { - name: "mouseWheel" - type: "bool" - Parameter { name: "item"; type: "QObject"; isPointer: true } - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - Parameter { name: "buttons"; type: "int" } - Parameter { name: "modifiers"; type: "int" } - Parameter { name: "xDelta"; type: "int" } - Parameter { name: "yDelta"; type: "int" } - Parameter { name: "delay"; type: "int" } - } - Method { - name: "touchEvent" - type: "QQuickTouchEventSequence*" - Parameter { name: "item"; type: "QObject"; isPointer: true } - } - Method { name: "touchEvent"; type: "QQuickTouchEventSequence*" } - } - Component { - name: "QuickTestResult" - prototype: "QObject" - exports: [ - "QtTest/TestResult 1.0", - "QtTest/TestResult 1.1", - "QtTest/TestResult 1.13" - ] - exportMetaObjectRevisions: [0, 1, 13] - Enum { - name: "RunMode" - values: { - "RepeatUntilValidMeasurement": 0, - "RunOnce": 1 - } - } - Property { name: "testCaseName"; type: "string" } - Property { name: "functionName"; type: "string" } - Property { name: "dataTag"; type: "string" } - Property { name: "failed"; type: "bool"; isReadonly: true } - Property { name: "skipped"; type: "bool" } - Property { name: "passCount"; type: "int"; isReadonly: true } - Property { name: "failCount"; type: "int"; isReadonly: true } - Property { name: "skipCount"; type: "int"; isReadonly: true } - Property { name: "functionsToRun"; type: "QStringList"; isReadonly: true } - Property { name: "tagsToRun"; type: "QStringList"; isReadonly: true } - Signal { name: "programNameChanged" } - Method { name: "reset" } - Method { name: "startLogging" } - Method { name: "stopLogging" } - Method { name: "initTestTable" } - Method { name: "clearTestTable" } - Method { name: "finishTestData" } - Method { name: "finishTestDataCleanup" } - Method { name: "finishTestFunction" } - Method { - name: "stringify" - Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "fail" - Parameter { name: "message"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "verify" - type: "bool" - Parameter { name: "success"; type: "bool" } - Parameter { name: "message"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "compare" - type: "bool" - Parameter { name: "success"; type: "bool" } - Parameter { name: "message"; type: "string" } - Parameter { name: "val1"; type: "QVariant" } - Parameter { name: "val2"; type: "QVariant" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "fuzzyCompare" - type: "bool" - Parameter { name: "actual"; type: "QVariant" } - Parameter { name: "expected"; type: "QVariant" } - Parameter { name: "delta"; type: "double" } - } - Method { - name: "skip" - Parameter { name: "message"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "expectFail" - type: "bool" - Parameter { name: "tag"; type: "string" } - Parameter { name: "comment"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "expectFailContinue" - type: "bool" - Parameter { name: "tag"; type: "string" } - Parameter { name: "comment"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "warn" - Parameter { name: "message"; type: "string" } - Parameter { name: "location"; type: "QUrl" } - Parameter { name: "line"; type: "int" } - } - Method { - name: "ignoreWarning" - Parameter { name: "message"; type: "QJSValue" } - } - Method { - name: "wait" - Parameter { name: "ms"; type: "int" } - } - Method { - name: "sleep" - Parameter { name: "ms"; type: "int" } - } - Method { - name: "waitForRendering" - type: "bool" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - Parameter { name: "timeout"; type: "int" } - } - Method { - name: "waitForRendering" - type: "bool" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { name: "startMeasurement" } - Method { name: "beginDataRun" } - Method { name: "endDataRun" } - Method { name: "measurementAccepted"; type: "bool" } - Method { name: "needsMoreMeasurements"; type: "bool" } - Method { - name: "startBenchmark" - Parameter { name: "runMode"; type: "RunMode" } - Parameter { name: "tag"; type: "string" } - } - Method { name: "isBenchmarkDone"; type: "bool" } - Method { name: "nextBenchmark" } - Method { name: "stopBenchmark" } - Method { - name: "grabImage" - type: "QObject*" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "findChild" - revision: 1 - type: "QObject*" - Parameter { name: "parent"; type: "QObject"; isPointer: true } - Parameter { name: "objectName"; type: "string" } - } - Method { - name: "isPolishScheduled" - revision: 13 - type: "bool" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "waitForItemPolished" - revision: 13 - type: "bool" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - Parameter { name: "timeout"; type: "int" } - } - } - Component { - name: "QuickTestUtil" - prototype: "QObject" - exports: ["QtTest/TestUtil 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "printAvailableFunctions"; type: "bool"; isReadonly: true } - Property { name: "dragThreshold"; type: "int"; isReadonly: true } - Method { - name: "typeName" - type: "QJSValue" - Parameter { name: "v"; type: "QVariant" } - } - Method { - name: "compare" - type: "bool" - Parameter { name: "act"; type: "QVariant" } - Parameter { name: "exp"; type: "QVariant" } - } - Method { - name: "callerFile" - type: "QJSValue" - Parameter { name: "frameIndex"; type: "int" } - } - Method { name: "callerFile"; type: "QJSValue" } - Method { - name: "callerLine" - type: "int" - Parameter { name: "frameIndex"; type: "int" } - } - Method { name: "callerLine"; type: "int" } - } -} diff --git a/src/imports/testlib/quicktestevent.cpp b/src/imports/testlib/quicktestevent.cpp new file mode 100644 index 0000000000..f2d7f93d26 --- /dev/null +++ b/src/imports/testlib/quicktestevent.cpp @@ -0,0 +1,471 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quicktestevent_p.h" +#include <QtTest/qtestkeyboard.h> +#include <QtQml/qqml.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> +#include <qpa/qwindowsysteminterface.h> + +QT_BEGIN_NAMESPACE + +namespace QTest { + extern int Q_TESTLIB_EXPORT defaultMouseDelay(); +} + +QuickTestEvent::QuickTestEvent(QObject *parent) + : QObject(parent) +{ +} + +QuickTestEvent::~QuickTestEvent() +{ +} + +int QuickTestEvent::defaultMouseDelay() const +{ + return QTest::defaultMouseDelay(); +} + +bool QuickTestEvent::keyPress(int key, int modifiers, int delay) +{ + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyPress(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +bool QuickTestEvent::keyRelease(int key, int modifiers, int delay) +{ + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyRelease(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +bool QuickTestEvent::keyClick(int key, int modifiers, int delay) +{ + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyClick(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +bool QuickTestEvent::keyPressChar(const QString &character, int modifiers, int delay) +{ + QTEST_ASSERT(character.length() == 1); + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyPress(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +bool QuickTestEvent::keyReleaseChar(const QString &character, int modifiers, int delay) +{ + QTEST_ASSERT(character.length() == 1); + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyRelease(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int delay) +{ + QTEST_ASSERT(character.length() == 1); + QWindow *window = activeWindow(); + if (!window) + return false; + QTest::keyClick(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay); + return true; +} + +#if QT_CONFIG(shortcut) +// valueToKeySequence() is copied from qquickshortcut.cpp +static QKeySequence valueToKeySequence(const QVariant &value) +{ + if (value.userType() == QMetaType::Int) + return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt())); + return QKeySequence::fromString(value.toString()); +} +#endif + +bool QuickTestEvent::keySequence(const QVariant &keySequence) +{ + QWindow *window = activeWindow(); + if (!window) + return false; +#if QT_CONFIG(shortcut) + QTest::keySequence(window, valueToKeySequence(keySequence)); +#else + Q_UNUSED(keySequence); +#endif + return true; +} + +namespace QtQuickTest +{ + enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove, MouseDoubleClickSequence }; + + int lastMouseTimestamp = 0; + + // TODO should be Qt::MouseButtons buttons in case multiple buttons are pressed + static void mouseEvent(MouseAction action, QWindow *window, + QObject *item, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey, const QPointF &_pos, int delay=-1) + { + QTEST_ASSERT(window); + QTEST_ASSERT(item); + + if (delay == -1 || delay < QTest::defaultMouseDelay()) + delay = QTest::defaultMouseDelay(); + if (delay > 0) { + QTest::qWait(delay); + lastMouseTimestamp += delay; + } + + if (action == MouseClick) { + mouseEvent(MousePress, window, item, button, stateKey, _pos); + mouseEvent(MouseRelease, window, item, button, stateKey, _pos); + return; + } + + if (action == MouseDoubleClickSequence) { + mouseEvent(MousePress, window, item, button, stateKey, _pos); + mouseEvent(MouseRelease, window, item, button, stateKey, _pos); + mouseEvent(MousePress, window, item, button, stateKey, _pos); + mouseEvent(MouseDoubleClick, window, item, button, stateKey, _pos); + mouseEvent(MouseRelease, window, item, button, stateKey, _pos); + return; + } + + QPoint pos = _pos.toPoint(); + QQuickItem *sgitem = qobject_cast<QQuickItem *>(item); + if (sgitem) + pos = sgitem->mapToScene(_pos).toPoint(); + QTEST_ASSERT(button == Qt::NoButton || button & Qt::MouseButtonMask); + QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask); + + stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask); + + QMouseEvent me(QEvent::User, QPoint(), Qt::LeftButton, button, stateKey); + switch (action) + { + case MousePress: + me = QMouseEvent(QEvent::MouseButtonPress, pos, window->mapToGlobal(pos), button, button, stateKey); + me.setTimestamp(++lastMouseTimestamp); + break; + case MouseRelease: + me = QMouseEvent(QEvent::MouseButtonRelease, pos, window->mapToGlobal(pos), button, {}, stateKey); + me.setTimestamp(++lastMouseTimestamp); + lastMouseTimestamp += 500; // avoid double clicks being generated + break; + case MouseDoubleClick: + me = QMouseEvent(QEvent::MouseButtonDblClick, pos, window->mapToGlobal(pos), button, button, stateKey); + me.setTimestamp(++lastMouseTimestamp); + break; + case MouseMove: + // with move event the button is NoButton, but 'buttons' holds the currently pressed buttons + me = QMouseEvent(QEvent::MouseMove, pos, window->mapToGlobal(pos), Qt::NoButton, button, stateKey); + me.setTimestamp(++lastMouseTimestamp); + break; + default: + QTEST_ASSERT(false); + } + QSpontaneKeyEvent::setSpontaneous(&me); + if (!qApp->notify(window, &me)) { + static const char *mouseActionNames[] = + { "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove", "MouseDoubleClickSequence" }; + QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving window"); + QWARN(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toLatin1().data()); + } + } + +#if QT_CONFIG(wheelevent) + static void mouseWheel(QWindow* window, QObject* item, Qt::MouseButtons buttons, + Qt::KeyboardModifiers stateKey, + QPointF _pos, int xDelta, int yDelta, int delay = -1) + { + QTEST_ASSERT(window); + QTEST_ASSERT(item); + if (delay == -1 || delay < QTest::defaultMouseDelay()) + delay = QTest::defaultMouseDelay(); + if (delay > 0) + QTest::qWait(delay); + + QPoint pos; + QQuickItem *sgitem = qobject_cast<QQuickItem *>(item); + if (sgitem) + pos = sgitem->mapToScene(_pos).toPoint(); + + QTEST_ASSERT(buttons == Qt::NoButton || buttons & Qt::MouseButtonMask); + QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask); + + stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask); + QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons, + stateKey, Qt::NoScrollPhase, false); + + QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm + if (!qApp->notify(window, &we)) + QTest::qWarn("Wheel event not accepted by receiving window"); + } +#endif +}; + +bool QuickTestEvent::mousePress + (QObject *item, qreal x, qreal y, int button, + int modifiers, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + m_pressedButtons.setFlag(Qt::MouseButton(button), true); + QtQuickTest::mouseEvent(QtQuickTest::MousePress, view, item, + Qt::MouseButton(button), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), delay); + return true; +} + +#if QT_CONFIG(wheelevent) +bool QuickTestEvent::mouseWheel( + QObject *item, qreal x, qreal y, int buttons, + int modifiers, int xDelta, int yDelta, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + QtQuickTest::mouseWheel(view, item, Qt::MouseButtons(buttons), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), xDelta, yDelta, delay); + return true; +} +#endif + +bool QuickTestEvent::mouseRelease + (QObject *item, qreal x, qreal y, int button, + int modifiers, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + m_pressedButtons.setFlag(Qt::MouseButton(button), false); + QtQuickTest::mouseEvent(QtQuickTest::MouseRelease, view, item, + Qt::MouseButton(button), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), delay); + return true; +} + +bool QuickTestEvent::mouseClick + (QObject *item, qreal x, qreal y, int button, + int modifiers, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + QtQuickTest::mouseEvent(QtQuickTest::MouseClick, view, item, + Qt::MouseButton(button), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), delay); + return true; +} + +bool QuickTestEvent::mouseDoubleClick + (QObject *item, qreal x, qreal y, int button, + int modifiers, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + QtQuickTest::mouseEvent(QtQuickTest::MouseDoubleClick, view, item, + Qt::MouseButton(button), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), delay); + return true; +} + +bool QuickTestEvent::mouseDoubleClickSequence + (QObject *item, qreal x, qreal y, int button, + int modifiers, int delay) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + QtQuickTest::mouseEvent(QtQuickTest::MouseDoubleClickSequence, view, item, + Qt::MouseButton(button), + Qt::KeyboardModifiers(modifiers), + QPointF(x, y), delay); + return true; +} + +bool QuickTestEvent::mouseMove + (QObject *item, qreal x, qreal y, int delay, int buttons) +{ + QWindow *view = eventWindow(item); + if (!view) + return false; + const Qt::MouseButtons effectiveButtons = buttons ? Qt::MouseButtons(buttons) : m_pressedButtons; + QtQuickTest::mouseEvent(QtQuickTest::MouseMove, view, item, + Qt::MouseButton(int(effectiveButtons)), Qt::NoModifier, + QPointF(x, y), delay); + return true; +} + +QWindow *QuickTestEvent::eventWindow(QObject *item) +{ + QWindow * window = qobject_cast<QWindow *>(item); + if (window) + return window; + + QQuickItem *quickItem = qobject_cast<QQuickItem *>(item); + if (quickItem) + return quickItem->window(); + + QQuickItem *testParentitem = qobject_cast<QQuickItem *>(parent()); + if (testParentitem) + return testParentitem->window(); + return nullptr; +} + +QWindow *QuickTestEvent::activeWindow() +{ + if (QWindow *window = QGuiApplication::focusWindow()) + return window; + return eventWindow(); +} + +QQuickTouchEventSequence::QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item) + : QObject(testEvent) + , m_sequence(QTest::touchEvent(testEvent->eventWindow(item), testEvent->touchDevice())) + , m_testEvent(testEvent) +{ +} + +QObject *QQuickTouchEventSequence::press(int touchId, QObject *item, qreal x, qreal y) +{ + QWindow *view = m_testEvent->eventWindow(item); + if (view) { + QPointF pos(x, y); + QQuickItem *quickItem = qobject_cast<QQuickItem *>(item); + if (quickItem) { + pos = quickItem->mapToScene(pos); + } + m_sequence.press(touchId, pos.toPoint(), view); + } + return this; +} + +QObject *QQuickTouchEventSequence::move(int touchId, QObject *item, qreal x, qreal y) +{ + QWindow *view = m_testEvent->eventWindow(item); + if (view) { + QPointF pos(x, y); + QQuickItem *quickItem = qobject_cast<QQuickItem *>(item); + if (quickItem) { + pos = quickItem->mapToScene(pos); + } + m_sequence.move(touchId, pos.toPoint(), view); + } + return this; +} + +QObject *QQuickTouchEventSequence::release(int touchId, QObject *item, qreal x, qreal y) +{ + QWindow *view = m_testEvent->eventWindow(item); + if (view) { + QPointF pos(x, y); + QQuickItem *quickItem = qobject_cast<QQuickItem *>(item); + if (quickItem) { + pos = quickItem->mapToScene(pos); + } + m_sequence.release(touchId, pos.toPoint(), view); + } + return this; +} + +QObject *QQuickTouchEventSequence::stationary(int touchId) +{ + m_sequence.stationary(touchId); + return this; +} + +QObject *QQuickTouchEventSequence::commit() +{ + m_sequence.commit(); + return this; +} + +/*! + Return a simulated touchscreen, creating one if necessary + + \internal +*/ + +QTouchDevice *QuickTestEvent::touchDevice() +{ + static QTouchDevice *device(nullptr); + + if (!device) { + device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + } + return device; +} + +/*! + Creates a new QQuickTouchEventSequence. + + If valid, \a item determines the QWindow that touch events are sent to. + Test code should use touchEvent() from the QML TestCase type. + + \internal +*/ +QQuickTouchEventSequence *QuickTestEvent::touchEvent(QObject *item) +{ + return new QQuickTouchEventSequence(this, item); +} + +QT_END_NAMESPACE diff --git a/src/imports/testlib/quicktestevent_p.h b/src/imports/testlib/quicktestevent_p.h new file mode 100644 index 0000000000..f452e4ff82 --- /dev/null +++ b/src/imports/testlib/quicktestevent_p.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUICKTESTEVENT_P_H +#define QUICKTESTEVENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/QWindow> +#include <QtQml/qqml.h> +#include <QtTest/qtesttouch.h> + +QT_BEGIN_NAMESPACE + +class QuickTestEvent; +class QQuickTouchEventSequence : public QObject +{ + Q_OBJECT + QML_ANONYMOUS + +public: + explicit QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item = nullptr); +public slots: + QObject* press(int touchId, QObject *item, qreal x, qreal y); + QObject* move(int touchId, QObject *item, qreal x, qreal y); + QObject* release(int touchId, QObject *item, qreal x, qreal y); + QObject* stationary(int touchId); + QObject* commit(); + +private: + QTest::QTouchEventSequence m_sequence; + QuickTestEvent * const m_testEvent; +}; + +class QuickTestEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL) + QML_NAMED_ELEMENT(TestEvent) +public: + QuickTestEvent(QObject *parent = nullptr); + ~QuickTestEvent() override; + int defaultMouseDelay() const; + +public Q_SLOTS: + bool keyPress(int key, int modifiers, int delay); + bool keyRelease(int key, int modifiers, int delay); + bool keyClick(int key, int modifiers, int delay); + + bool keyPressChar(const QString &character, int modifiers, int delay); + bool keyReleaseChar(const QString &character, int modifiers, int delay); + bool keyClickChar(const QString &character, int modifiers, int delay); + + Q_REVISION(2) bool keySequence(const QVariant &keySequence); + + bool mousePress(QObject *item, qreal x, qreal y, int button, + int modifiers, int delay); + bool mouseRelease(QObject *item, qreal x, qreal y, int button, + int modifiers, int delay); + bool mouseClick(QObject *item, qreal x, qreal y, int button, + int modifiers, int delay); + bool mouseDoubleClick(QObject *item, qreal x, qreal y, int button, + int modifiers, int delay); + bool mouseDoubleClickSequence(QObject *item, qreal x, qreal y, int button, + int modifiers, int delay); + bool mouseMove(QObject *item, qreal x, qreal y, int delay, int buttons); + +#if QT_CONFIG(wheelevent) + bool mouseWheel(QObject *item, qreal x, qreal y, int buttons, + int modifiers, int xDelta, int yDelta, int delay); +#endif + + QQuickTouchEventSequence *touchEvent(QObject *item = nullptr); +private: + QWindow *eventWindow(QObject *item = nullptr); + QWindow *activeWindow(); + QTouchDevice *touchDevice(); + + Qt::MouseButtons m_pressedButtons; + + friend class QQuickTouchEventSequence; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/imports/testlib/quicktestresultforeign_p.h b/src/imports/testlib/quicktestresultforeign_p.h new file mode 100644 index 0000000000..92ff8e8a5a --- /dev/null +++ b/src/imports/testlib/quicktestresultforeign_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUICKTESTRESULTFOREIGN_P_H +#define QUICKTESTRESULTFOREIGN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTest/private/quicktestresult_p.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +struct QuickTestResultForeign +{ + Q_GADGET + QML_FOREIGN(QuickTestResult) + QML_NAMED_ELEMENT(TestResult) +}; + +QT_END_NAMESPACE + +#endif // QUICKTESTRESULTFOREIGN_P_H diff --git a/src/imports/testlib/quicktestutil.cpp b/src/imports/testlib/quicktestutil.cpp new file mode 100644 index 0000000000..d9e6a2fba5 --- /dev/null +++ b/src/imports/testlib/quicktestutil.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quicktestutil_p.h" + +#include <QtQuickTest/private/qtestoptions_p.h> +#include <QtQml/private/qqmltype_p.h> +#include <QtQml/private/qqmlmetatype_p.h> +#include <QtQml/private/qv4engine_p.h> +#include <QtQml/private/qv4scopedvalue_p.h> + +#include <QtGui/qguiapplication.h> +#include <QtGui/qstylehints.h> +#include <QtQml/qqmlengine.h> + +QT_BEGIN_NAMESPACE + +bool QuickTestUtil::printAvailableFunctions() const +{ + return QTest::printAvailableFunctions; +} + +int QuickTestUtil::dragThreshold() const +{ + return QGuiApplication::styleHints()->startDragDistance(); +} + +QJSValue QuickTestUtil::typeName(const QVariant &v) const +{ + QString name = QString::fromUtf8(v.typeName()); + if (v.canConvert<QObject*>()) { + QQmlType type; + const QMetaObject *mo = v.value<QObject*>()->metaObject(); + while (!type.isValid() && mo) { + type = QQmlMetaType::qmlType(mo); + mo = mo->superClass(); + } + if (type.isValid()) { + name = type.qmlTypeName(); + } + } + + QQmlEngine *engine = qmlEngine(this); + QV4::ExecutionEngine *v4 = engine->handle(); + return QJSValue(v4, v4->newString(name)->asReturnedValue()); +} + +bool QuickTestUtil::compare(const QVariant &act, const QVariant &exp) const { + return act == exp; +} + +QJSValue QuickTestUtil::callerFile(int frameIndex) const +{ + QQmlEngine *engine = qmlEngine(this); + QV4::ExecutionEngine *v4 = engine->handle(); + QV4::Scope scope(v4); + + QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2); + return (stack.size() > frameIndex + 1) + ? QJSValue(v4, v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue()) + : QJSValue(); +} + +int QuickTestUtil::callerLine(int frameIndex) const +{ + QQmlEngine *engine = qmlEngine(this); + QV4::ExecutionEngine *v4 = engine->handle(); + + QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2); + if (stack.size() > frameIndex + 1) + return stack.at(frameIndex + 1).line; + return -1; +} + +QT_END_NAMESPACE diff --git a/src/imports/testlib/quicktestutil_p.h b/src/imports/testlib/quicktestutil_p.h new file mode 100644 index 0000000000..2456bf88a7 --- /dev/null +++ b/src/imports/testlib/quicktestutil_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUICKTESTUTIL_P_H +#define QUICKTESTUTIL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> +#include <QtQml/qjsvalue.h> + +QT_BEGIN_NAMESPACE + +class QuickTestUtil : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged) + Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged) + QML_NAMED_ELEMENT(TestUtil) +public: + QuickTestUtil(QObject *parent = nullptr) :QObject(parent) {} + ~QuickTestUtil() override {} + + bool printAvailableFunctions() const; + int dragThreshold() const; + +Q_SIGNALS: + void printAvailableFunctionsChanged(); + void dragThresholdChanged(); + +public Q_SLOTS: + + QJSValue typeName(const QVariant& v) const; + bool compare(const QVariant& act, const QVariant& exp) const; + + QJSValue callerFile(int frameIndex = 0) const; + int callerLine(int frameIndex = 0) const; +}; + +QT_END_NAMESPACE + +#endif // QUICKTESTUTIL_P_H diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro index acbe82e5e6..d5e315d7da 100644 --- a/src/imports/testlib/testlib.pro +++ b/src/imports/testlib/testlib.pro @@ -3,9 +3,17 @@ TARGET = qmltestplugin TARGETPATH = QtTest IMPORT_VERSION = 1.$$QT_MINOR_VERSION -QT += qml quick qmltest qmltest-private qml-private core-private testlib +QT += quick qmltest-private qml-private core-private testlib gui-private -SOURCES += main.cpp +SOURCES += \ + main.cpp \ + quicktestevent.cpp \ + quicktestutil.cpp + +HEADERS += \ + quicktestevent_p.h \ + quicktestresultforeign_p.h \ + quicktestutil_p.h QML_FILES = \ TestCase.qml \ @@ -15,3 +23,4 @@ QML_FILES = \ load(qml_plugin) OTHER_FILES += testlib.json +CONFIG += qmltypes install_qmltypes |