aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDaniel d'Andrada <daniel.dandrada@luxoft.com>2017-10-19 14:15:17 +0200
committerDaniel d'Andrada <daniel.dandrada@luxoft.com>2018-02-28 15:57:56 +0100
commit266467aa8474530f9e5682c221a0625cf252a84e (patch)
tree9b16cef183d252155646a19020a1ebaeaed36cb7 /tests
parent54a77753da3765b4e1cc6508b900560ee6093c2b (diff)
Testing infrastructure
Diffstat (limited to 'tests')
-rw-r--r--tests/README11
-rw-r--r--tests/dummyimports/QtApplicationManager/ApplicationIPCInterface.qml46
-rw-r--r--tests/dummyimports/QtApplicationManager/ApplicationInstaller.js45
-rw-r--r--tests/dummyimports/QtApplicationManager/ApplicationManager.qml127
-rw-r--r--tests/dummyimports/QtApplicationManager/ApplicationManagerWindow.qml60
-rw-r--r--tests/dummyimports/QtApplicationManager/Notification.qml49
-rw-r--r--tests/dummyimports/QtApplicationManager/SystemMonitor.qml53
-rw-r--r--tests/dummyimports/QtApplicationManager/WindowManager.qml84
-rw-r--r--tests/dummyimports/QtApplicationManager/qmldir7
-rw-r--r--tests/dummyimports/dummyimports.pro6
-rw-r--r--tests/qmltests/qmltests.pro20
-rw-r--r--tests/qmltests/testrunner.cpp2
-rw-r--r--tests/qmltests/tst_ApplicationWidget.qml28
-rw-r--r--tests/qmltests/tst_WidgetDrawer.qml27
-rw-r--r--tests/tests.pro1
-rw-r--r--tests/triton-qmlscene/README6
-rw-r--r--tests/triton-qmlscene/triton-qmlscene.cpp743
-rw-r--r--tests/triton-qmlscene/triton-qmlscene.pro16
18 files changed, 1331 insertions, 0 deletions
diff --git a/tests/README b/tests/README
new file mode 100644
index 00000000..9ebc7f85
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,11 @@
+There are two ways to run qml tests:
+
+1-Execute the automated tests defined inside TestCase{} throughout tst_*.qml files
+ (using a qmltestrunner):
+ build_dir$ make check
+
+2-Try out a test in a window for manual interaction (manual testing).
+ Say you have a component called WidgetDrawer. If it has a test it will
+ be called tst_WidgetDrawer.qml. To show it using triton-qmlscene you run:
+
+ build_dir/tests/qmltests$ make tryWidgetDrawer
diff --git a/tests/dummyimports/QtApplicationManager/ApplicationIPCInterface.qml b/tests/dummyimports/QtApplicationManager/ApplicationIPCInterface.qml
new file mode 100644
index 00000000..c5aa25d6
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/ApplicationIPCInterface.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+import QtQml 2.0
+
+QtObject {
+}
diff --git a/tests/dummyimports/QtApplicationManager/ApplicationInstaller.js b/tests/dummyimports/QtApplicationManager/ApplicationInstaller.js
new file mode 100644
index 00000000..4494e49a
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/ApplicationInstaller.js
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+function removePackage(id) {
+ print("Dummy implementation of removePackage was called for ", id)
+ return ""
+}
diff --git a/tests/dummyimports/QtApplicationManager/ApplicationManager.qml b/tests/dummyimports/QtApplicationManager/ApplicationManager.qml
new file mode 100644
index 00000000..c16db806
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/ApplicationManager.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.2
+
+ListModel {
+ id: root
+
+ property int count: 3
+ property bool dummy: true
+
+ property var applibrary : [
+ ["com.pelagicore.browser","icon.png", "Browser", "browser", "Browser.qml"],
+ ["com.pelagicore.movies","icon.png", "Movies", "media", "Movies.qml"],
+ ["com.pelagicore.music","icon.png", "Music", "media", "Music.qml"],
+ ]
+
+ signal emitSurface(int index, Item item)
+
+
+
+ function setApplicationAudioFocus(appId, appFocus)
+ {
+ print("setApplicationAudioFocus(" + appId + ", " + appFocus + ")")
+ }
+
+ function qmltypeof(obj, className) { // QtObject, string -> bool
+ // className plus "(" is the class instance without modification
+ // className plus "_QML" is the class instance with user-defined properties
+ var str = obj.toString();
+ return str.indexOf(className + "(") == 0 || str.indexOf(className + "_QML") == 0;
+ }
+
+ function startApplication(id) {
+ print("Starting the application. ")
+ var component
+ var item
+ for (var i = 0; i < root.count; i++) {
+ var entry
+ print("ApplicationManager: " + createAppEntry(i).applicationId + " given app id to open: " + id)
+ if (root.get(i).applicationId === id) {
+ component = Qt.createComponent("../../../../apps/" + createAppEntry(i).applicationId + "/" + createAppEntry(i).qml);
+ if (component.status === Component.Ready) {
+ item = component.createObject()
+ if (!item)
+ console.log("Failed to create an Object.")
+ else {
+ print("Starting the application. Sending a signal", i, item, item.children.length)
+ root.setProperty(i, "surfaceItem", item)
+ root.emitSurface(i, item)
+ }
+ }
+ else
+ console.log("Component creation failed " + createAppEntry(i).qml + " Error: " + component.errorString())
+ }
+ }
+ }
+
+
+
+ function createAppEntry(i) {
+
+ var entry = {
+ applicationId: applibrary[i][0],
+ icon: "../../apps/" + applibrary[i][0] + "/" + applibrary[i][1],
+ name: applibrary[i][2],
+ isRunning: false,
+ isStarting: false,
+ isActive: false,
+ isBlocked: false,
+ isUpdating: false,
+ isRemovable: false,
+ updateProgress: 0,
+ codeFilePath: "",
+ categories: applibrary[i][3],
+ qml: applibrary[i][4],
+ surfaceItem: null
+ }
+ return entry
+ }
+ Component.onCompleted: {
+ clear()
+ for (var i = 0; i < root.count; i++) {
+ append(createAppEntry(i))
+ }
+ }
+
+}
diff --git a/tests/dummyimports/QtApplicationManager/ApplicationManagerWindow.qml b/tests/dummyimports/QtApplicationManager/ApplicationManagerWindow.qml
new file mode 100644
index 00000000..15a39a9d
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/ApplicationManagerWindow.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtApplicationManager 1.0
+
+Item {
+ id: root
+ width: 768
+ height: 860
+ property color color
+
+ signal windowPropertyChanged(string name, var value)
+ signal close()
+ //function showFullScreen() {}
+ function showMaximized() {}
+ function showNormal() {}
+ function setWindowProperty(status, value) {
+ WindowManager.surfaceWindowPropertyChanged(root, status, value)
+ windowPropertyChanged(status, value)
+ }
+}
diff --git a/tests/dummyimports/QtApplicationManager/Notification.qml b/tests/dummyimports/QtApplicationManager/Notification.qml
new file mode 100644
index 00000000..50a84774
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/Notification.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+import QtQml 2.0
+
+QtObject {
+ property string summary
+ property int timeout
+ property variant actions
+}
diff --git a/tests/dummyimports/QtApplicationManager/SystemMonitor.qml b/tests/dummyimports/QtApplicationManager/SystemMonitor.qml
new file mode 100644
index 00000000..4a2d0467
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/SystemMonitor.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+pragma Singleton
+
+import QtQml 2.0
+
+QtObject {
+ property int reportingInterval
+ property int reportingRange
+ property bool cpuLoadReportingEnabled
+ property bool fpsReportingEnabled
+ signal fpsReportingChanged(real average, real minimum, real maximum, real jitter)
+}
diff --git a/tests/dummyimports/QtApplicationManager/WindowManager.qml b/tests/dummyimports/QtApplicationManager/WindowManager.qml
new file mode 100644
index 00000000..276fa02f
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/WindowManager.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.2
+import QtApplicationManager 1.0
+
+QtObject {
+ id: root
+ property int count: ApplicationManager.count
+ property var surfaceItems: []
+ property Connections conn: Connections {
+ target: ApplicationManager
+ onEmitSurface: {
+ surfaceItems[index] = item
+ root.surfaceItemReady(index, item)
+ }
+ }
+
+ signal surfaceItemReady(int index, Item item)
+ signal surfaceItemClosing()
+ signal surfaceItemLost()
+ signal raiseApplicationWindow()
+ signal surfaceWindowPropertyChanged(Item surfaceItem, string name, var value)
+
+ function setSurfaceWindowProperty(appItem, type, status) {
+ appItem.windowPropertyChanged(type, status)
+ }
+
+ function surfaceWindowProperty(item, type) {
+ return false
+ }
+
+ function get(index) {
+ var entry = ApplicationManager.get(index)
+ entry.surfaceItem = surfaceItems[index]
+ return entry
+ }
+
+ Component.onCompleted: {
+ for (var i = 0; i < root.count; i++) {
+ surfaceItems.push(null)
+ }
+ }
+
+}
diff --git a/tests/dummyimports/QtApplicationManager/qmldir b/tests/dummyimports/QtApplicationManager/qmldir
new file mode 100644
index 00000000..6af7b9d7
--- /dev/null
+++ b/tests/dummyimports/QtApplicationManager/qmldir
@@ -0,0 +1,7 @@
+singleton ApplicationManager 1.0 ApplicationManager.qml
+ApplicationManagerWindow 1.0 ApplicationManagerWindow.qml
+ApplicationInstaller 1.0 ApplicationInstaller.js
+ApplicationIPCInterface 1.0 ApplicationIPCInterface.qml
+Notification 1.0 Notification.qml
+singleton WindowManager 1.0 WindowManager.qml
+singleton SystemMonitor 1.0 SystemMonitor.qml
diff --git a/tests/dummyimports/dummyimports.pro b/tests/dummyimports/dummyimports.pro
new file mode 100644
index 00000000..338e3e60
--- /dev/null
+++ b/tests/dummyimports/dummyimports.pro
@@ -0,0 +1,6 @@
+TEMPLATE = aux
+
+OTHER_FILES += \
+ QtApplicationManager/*.js \
+ QtApplicationManager/*.qml \
+ QtApplicationManager/qmldir \
diff --git a/tests/qmltests/qmltests.pro b/tests/qmltests/qmltests.pro
new file mode 100644
index 00000000..721414cf
--- /dev/null
+++ b/tests/qmltests/qmltests.pro
@@ -0,0 +1,20 @@
+TEMPLATE=app
+TARGET=triton-qmltestsrunner
+SOURCES += testrunner.cpp
+
+CONFIG += qmltestcase
+
+IMPORTPATH = $$BUILD_DIR/imports/shared/ $$SOURCE_DIR/sysui $$SOURCE_DIR/tests/dummyimports
+
+COMPONENT_NAMES = ApplicationWidget
+COMPONENT_NAMES += WidgetDrawer
+
+for(COMPONENT_NAME, COMPONENT_NAMES) {
+ targetName = try$$COMPONENT_NAME
+ QMAKE_EXTRA_TARGETS += $${targetName}
+ $${targetName}.commands = $$OUT_PWD/../triton-qmlscene/triton-qmlscene
+ !isEmpty(IMPORTPATH) {
+ for(import, IMPORTPATH): $${targetName}.commands += -I \"$$import\"
+ }
+ $${targetName}.commands += $$PWD/tst_$${COMPONENT_NAME}.qml
+}
diff --git a/tests/qmltests/testrunner.cpp b/tests/qmltests/testrunner.cpp
new file mode 100644
index 00000000..663febe9
--- /dev/null
+++ b/tests/qmltests/testrunner.cpp
@@ -0,0 +1,2 @@
+#include <QtQuickTest/quicktest.h>
+QUICK_TEST_MAIN(neptune-qmltests)
diff --git a/tests/qmltests/tst_ApplicationWidget.qml b/tests/qmltests/tst_ApplicationWidget.qml
new file mode 100644
index 00000000..3f11f193
--- /dev/null
+++ b/tests/qmltests/tst_ApplicationWidget.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.6
+import QtTest 1.1
+
+// sysui, for getting ApplicationWidget
+import display 1.0
+
+Item {
+ width: 600
+ height: 600
+
+ ApplicationWidget {
+ y: 200
+ width: 600
+ height: 200
+
+ Rectangle { color: "green"; anchors.fill: parent }
+ }
+
+ TestCase {
+ name: "ApplicationWidget"
+ when: windowShown
+
+ function test_pass() {
+ compare(2 + 2, 4, "2 + 2")
+ }
+ }
+}
+
diff --git a/tests/qmltests/tst_WidgetDrawer.qml b/tests/qmltests/tst_WidgetDrawer.qml
new file mode 100644
index 00000000..9d282c4d
--- /dev/null
+++ b/tests/qmltests/tst_WidgetDrawer.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.6
+import QtTest 1.1
+
+// sysui, for getting WidgetDrawer
+import display 1.0
+
+Item {
+ width: 600
+ height: 600
+
+ WidgetDrawer {
+ y: 200
+ width: 600
+ height: 200
+
+ Rectangle { color: "green"; anchors.fill: parent }
+ }
+
+ TestCase {
+ name: "WidgetDrawer"
+ when: windowShown
+
+ function test_pass() {
+ compare(2 + 2, 4, "2 + 2")
+ }
+ }
+}
diff --git a/tests/tests.pro b/tests/tests.pro
index 96710850..1148860a 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1 +1,2 @@
TEMPLATE = subdirs
+SUBDIRS += qmltests triton-qmlscene
diff --git a/tests/triton-qmlscene/README b/tests/triton-qmlscene/README
new file mode 100644
index 00000000..80101478
--- /dev/null
+++ b/tests/triton-qmlscene/README
@@ -0,0 +1,6 @@
+triton-qmlscene is useful when you want to manually interact with a qml file that has a TestCase in it.
+
+It's just qmlscene from qtdeclarative with minor modifications. Namely:
+ - Made it register a dummy QTestRootObject singleton type under a Qt.test.qtestroot so that qml files
+ that have a TestCase (ie, that import QtTest) can be loaded and displayed.
+ - Added a MouseTouchAdaptor for emulating touch interaction with a mouse device
diff --git a/tests/triton-qmlscene/triton-qmlscene.cpp b/tests/triton-qmlscene/triton-qmlscene.cpp
new file mode 100644
index 00000000..33a10a8c
--- /dev/null
+++ b/tests/triton-qmlscene/triton-qmlscene.cpp
@@ -0,0 +1,743 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qabstractanimation.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qregularexpression.h>
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QOpenGLFunctions>
+
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlcontext.h>
+
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+
+#include <private/qabstractanimation_p.h>
+#include <private/qopenglcontext_p.h>
+
+#ifdef QT_WIDGETS_LIB
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QFileDialog>
+#endif
+
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
+
+#ifdef TRITON_ENABLE_TOUCH_EMULATION
+# include <MouseTouchAdaptor.h>
+#endif
+
+#ifdef QML_RUNTIME_TESTING
+class RenderStatistics
+{
+public:
+ static void updateStats();
+ static void printTotalStats();
+private:
+ static QVector<qreal> timePerFrame;
+ static QVector<int> timesPerFrames;
+};
+
+QVector<qreal> RenderStatistics::timePerFrame;
+QVector<int> RenderStatistics::timesPerFrames;
+
+void RenderStatistics::updateStats()
+{
+ static QTime time;
+ static int frames;
+ static int lastTime;
+
+ if (frames == 0) {
+ time.start();
+ } else {
+ int elapsed = time.elapsed();
+ timesPerFrames.append(elapsed - lastTime);
+ lastTime = elapsed;
+
+ if (elapsed > 5000) {
+ qreal avgtime = elapsed / (qreal) frames;
+ qreal var = 0;
+ for (int i = 0; i < timesPerFrames.size(); ++i) {
+ qreal diff = timesPerFrames.at(i) - avgtime;
+ var += diff * diff;
+ }
+ var /= timesPerFrames.size();
+
+ printf("Average time per frame: %f ms (%i fps), std.dev: %f ms\n", avgtime, qRound(1000. / avgtime), qSqrt(var));
+
+ timePerFrame.append(avgtime);
+ timesPerFrames.clear();
+ time.start();
+ lastTime = 0;
+ frames = 0;
+ }
+ }
+ ++frames;
+}
+
+void RenderStatistics::printTotalStats()
+{
+ int count = timePerFrame.count();
+ if (count == 0)
+ return;
+
+ qreal minTime = 0;
+ qreal maxTime = 0;
+ qreal avg = 0;
+ for (int i = 0; i < count; ++i) {
+ minTime = minTime == 0 ? timePerFrame.at(i) : qMin(minTime, timePerFrame.at(i));
+ maxTime = qMax(maxTime, timePerFrame.at(i));
+ avg += timePerFrame.at(i);
+ }
+ avg /= count;
+
+ puts(" ");
+ puts("----- Statistics -----");
+ printf("Average time per frame: %f ms (%i fps)\n", avg, qRound(1000. / avg));
+ printf("Best time per frame: %f ms (%i fps)\n", minTime, int(1000 / minTime));
+ printf("Worst time per frame: %f ms (%i fps)\n", maxTime, int(1000 / maxTime));
+ puts("----------------------");
+ puts(" ");
+}
+#endif
+
+struct Options
+{
+ enum QmlApplicationType
+ {
+ QmlApplicationTypeGui,
+ QmlApplicationTypeWidget,
+#ifdef QT_WIDGETS_LIB
+ DefaultQmlApplicationType = QmlApplicationTypeWidget
+#else
+ DefaultQmlApplicationType = QmlApplicationTypeGui
+#endif
+ };
+
+ Options()
+ : originalQml(false)
+ , originalQmlRaster(false)
+ , maximized(false)
+ , fullscreen(false)
+ , transparent(false)
+ , clip(false)
+ , versionDetection(true)
+ , slowAnimations(false)
+ , quitImmediately(false)
+ , resizeViewToRootItem(false)
+ , multisample(false)
+ , coreProfile(false)
+ , verbose(false)
+ , applicationType(DefaultQmlApplicationType)
+ , textRenderType(QQuickWindow::textRenderType())
+ {
+ // QtWebEngine needs a shared context in order for the GPU thread to
+ // upload textures.
+ applicationAttributes.append(Qt::AA_ShareOpenGLContexts);
+ }
+
+ QUrl url;
+ bool originalQml;
+ bool originalQmlRaster;
+ bool maximized;
+ bool fullscreen;
+ bool transparent;
+ bool clip;
+ bool versionDetection;
+ bool slowAnimations;
+ bool quitImmediately;
+ bool resizeViewToRootItem;
+ bool multisample;
+ bool coreProfile;
+ bool verbose;
+ QVector<Qt::ApplicationAttribute> applicationAttributes;
+ QString translationFile;
+ QmlApplicationType applicationType;
+ QQuickWindow::TextRenderType textRenderType;
+};
+
+#if defined(QMLSCENE_BUNDLE)
+QFileInfoList findQmlFiles(const QString &dirName)
+{
+ QDir dir(dirName);
+
+ QFileInfoList ret;
+ if (dir.exists()) {
+ const QFileInfoList fileInfos = dir.entryInfoList(QStringList() << "*.qml",
+ QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
+
+ for (const QFileInfo &fileInfo : fileInfos) {
+ if (fileInfo.isDir())
+ ret += findQmlFiles(fileInfo.filePath());
+ else if (fileInfo.fileName().length() > 0 && fileInfo.fileName().at(0).isLower())
+ ret.append(fileInfo);
+ }
+ }
+
+ return ret;
+}
+
+static int displayOptionsDialog(Options *options)
+{
+ QDialog dialog;
+
+ QFormLayout *layout = new QFormLayout(&dialog);
+
+ QComboBox *qmlFileComboBox = new QComboBox(&dialog);
+ const QFileInfoList fileInfos = findQmlFiles(":/bundle") + findQmlFiles("./qmlscene-resources");
+
+ for (const QFileInfo &fileInfo : fileInfos)
+ qmlFileComboBox->addItem(fileInfo.dir().dirName() + QLatin1Char('/') + fileInfo.fileName(), QVariant::fromValue(fileInfo));
+
+ QCheckBox *originalCheckBox = new QCheckBox(&dialog);
+ originalCheckBox->setText("Use original QML viewer");
+ originalCheckBox->setChecked(options->originalQml);
+
+ QCheckBox *fullscreenCheckBox = new QCheckBox(&dialog);
+ fullscreenCheckBox->setText("Start fullscreen");
+ fullscreenCheckBox->setChecked(options->fullscreen);
+
+ QCheckBox *maximizedCheckBox = new QCheckBox(&dialog);
+ maximizedCheckBox->setText("Start maximized");
+ maximizedCheckBox->setChecked(options->maximized);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal,
+ &dialog);
+ QObject::connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ QObject::connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
+
+ layout->addRow("Qml file:", qmlFileComboBox);
+ layout->addWidget(originalCheckBox);
+ layout->addWidget(maximizedCheckBox);
+ layout->addWidget(fullscreenCheckBox);
+ layout->addWidget(buttonBox);
+
+ int result = dialog.exec();
+ if (result == QDialog::Accepted) {
+ QVariant variant = qmlFileComboBox->itemData(qmlFileComboBox->currentIndex());
+ QFileInfo fileInfo = variant.value<QFileInfo>();
+
+ if (fileInfo.canonicalFilePath().startsWith(QLatin1Char(':')))
+ options->file = QUrl("qrc" + fileInfo.canonicalFilePath());
+ else
+ options->file = QUrl::fromLocalFile(fileInfo.canonicalFilePath());
+ options->originalQml = originalCheckBox->isChecked();
+ options->maximized = maximizedCheckBox->isChecked();
+ options->fullscreen = fullscreenCheckBox->isChecked();
+ }
+ return result;
+}
+#endif
+
+static bool checkVersion(const QUrl &url)
+{
+ if (!qgetenv("QMLSCENE_IMPORT_NAME").isEmpty())
+ fprintf(stderr, "QMLSCENE_IMPORT_NAME is no longer supported.\n");
+
+ if (!url.isLocalFile())
+ return true;
+
+ const QString fileName = url.toLocalFile();
+ QFile f(fileName);
+ if (!f.open(QFile::ReadOnly | QFile::Text)) {
+ fprintf(stderr, "qmlscene: failed to check version of file '%s', could not open...\n",
+ qPrintable(fileName));
+ return false;
+ }
+
+ QRegularExpression quick1("^\\s*import +QtQuick +1\\.\\w*");
+ QRegularExpression qt47("^\\s*import +Qt +4\\.7");
+
+ QTextStream stream(&f);
+ bool codeFound= false;
+ while (!codeFound) {
+ QString line = stream.readLine();
+ if (line.contains(QLatin1Char('{'))) {
+ codeFound = true;
+ } else {
+ QString import;
+ QRegularExpressionMatch match = quick1.match(line);
+ if (match.hasMatch())
+ import = match.captured(0).trimmed();
+ else if ((match = qt47.match(line)).hasMatch())
+ import = match.captured(0).trimmed();
+
+ if (!import.isNull()) {
+ fprintf(stderr, "qmlscene: '%s' is no longer supported.\n"
+ "Use qmlviewer to load file '%s'.\n",
+ qPrintable(import),
+ qPrintable(fileName));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+static void displayFileDialog(Options *options)
+{
+#if defined(QT_WIDGETS_LIB) && QT_CONFIG(filedialog)
+ if (options->applicationType == Options::QmlApplicationTypeWidget) {
+ QString fileName = QFileDialog::getOpenFileName(0, "Open QML file", QString(), "QML Files (*.qml)");
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ options->url = QUrl::fromLocalFile(fi.canonicalFilePath());
+ }
+ return;
+ }
+#endif // QT_WIDGETS_LIB && QT_CONFIG(filedialog)
+ Q_UNUSED(options);
+ puts("No filename specified...");
+}
+
+#if QT_CONFIG(translation)
+static void loadTranslationFile(QTranslator &translator, const QString& directory)
+{
+ translator.load(QLatin1String("qml_" )+QLocale::system().name(), directory + QLatin1String("/i18n"));
+ QCoreApplication::installTranslator(&translator);
+}
+#endif
+
+static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory)
+{
+ QDir dir(directory+"/dummydata", "*.qml");
+ QStringList list = dir.entryList();
+ for (int i = 0; i < list.size(); ++i) {
+ QString qml = list.at(i);
+ QQmlComponent comp(&engine, dir.filePath(qml));
+ QObject *dummyData = comp.create();
+
+ if (comp.isError()) {
+ const QList<QQmlError> errors = comp.errors();
+ for (const QQmlError &error : errors)
+ fprintf(stderr, "%s\n", qPrintable(error.toString()));
+ }
+
+ if (dummyData) {
+ fprintf(stderr, "Loaded dummy data: %s\n", qPrintable(dir.filePath(qml)));
+ qml.truncate(qml.length()-4);
+ engine.rootContext()->setContextProperty(qml, dummyData);
+ dummyData->setParent(&engine);
+ }
+ }
+}
+
+static void usage()
+{
+ puts("Usage: qmlscene [options] <filename>");
+ puts(" ");
+ puts(" Options:");
+ puts(" --maximized ...................... Run maximized");
+ puts(" --fullscreen ..................... Run fullscreen");
+ puts(" --transparent .................... Make the window transparent");
+ puts(" --multisample .................... Enable multisampling (OpenGL anti-aliasing)");
+ puts(" --core-profile ................... Request a core profile OpenGL context");
+ puts(" --no-version-detection ........... Do not try to detect the version of the .qml file");
+ puts(" --slow-animations ................ Run all animations in slow motion");
+ puts(" --resize-to-root ................. Resize the window to the size of the root item");
+ puts(" --quit ........................... Quit immediately after starting");
+ puts(" --disable-context-sharing ........ Disable the use of a shared GL context for QtQuick Windows\n"
+ " .........(remove AA_ShareOpenGLContexts)");
+ puts(" --desktop..........................Force use of desktop GL (AA_UseDesktopOpenGL)");
+ puts(" --gles.............................Force use of GLES (AA_UseOpenGLES)");
+ puts(" --software.........................Force use of software rendering (AA_UseOpenGLES)");
+ puts(" --scaling..........................Enable High DPI scaling (AA_EnableHighDpiScaling)");
+ puts(" --no-scaling.......................Disable High DPI scaling (AA_DisableHighDpiScaling)");
+ puts(" --verbose..........................Print version and graphical diagnostics for the run-time");
+#ifdef QT_WIDGETS_LIB
+ puts(" --apptype [gui|widgets] ...........Select which application class to use. Default is widgets.");
+#endif
+ puts(" --textrendertype [qt|native].......Select the default render type for text-like elements.");
+ puts(" -I <path> ........................ Add <path> to the list of import paths");
+ puts(" -P <path> ........................ Add <path> to the list of plugin paths");
+ puts(" -translation <translationfile> ... Set the language to run in");
+
+ puts(" ");
+ exit(1);
+}
+#if QT_CONFIG(opengl)
+// Listen on GL context creation of the QQuickWindow in order to print diagnostic output.
+class DiagnosticGlContextCreationListener : public QObject {
+ Q_OBJECT
+public:
+ explicit DiagnosticGlContextCreationListener(QQuickWindow *window) : QObject(window)
+ {
+ connect(window, &QQuickWindow::openglContextCreated,
+ this, &DiagnosticGlContextCreationListener::onOpenGlContextCreated);
+ }
+
+private slots:
+ void onOpenGlContextCreated(QOpenGLContext *context)
+ {
+ context->makeCurrent(qobject_cast<QQuickWindow *>(parent()));
+ QOpenGLFunctions functions(context);
+ QByteArray output = "Vendor : ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR));
+ output += "\nRenderer: ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER));
+ output += "\nVersion : ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_VERSION));
+ output += "\nLanguage: ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION));
+ puts(output.constData());
+ context->doneCurrent();
+ deleteLater();
+ }
+
+};
+#endif
+
+static void setWindowTitle(bool verbose, const QObject *topLevel, QWindow *window)
+{
+ const QString oldTitle = window->title();
+ QString newTitle = oldTitle;
+ if (newTitle.isEmpty()) {
+ newTitle = QLatin1String("qmlscene");
+ if (!qobject_cast<const QWindow *>(topLevel) && !topLevel->objectName().isEmpty())
+ newTitle += QLatin1String(": ") + topLevel->objectName();
+ }
+ if (verbose) {
+ newTitle += QLatin1String(" [Qt ") + QLatin1String(QT_VERSION_STR) + QLatin1Char(' ')
+ + QGuiApplication::platformName() + QLatin1Char(' ');
+#if QT_CONFIG(opengl)
+ newTitle += QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
+ ? QLatin1String("GL") : QLatin1String("GLES");
+#endif
+ newTitle += QLatin1Char(']');
+ }
+ if (oldTitle != newTitle)
+ window->setTitle(newTitle);
+}
+
+static QUrl parseUrlArgument(const QString &arg)
+{
+ const QUrl url = QUrl::fromUserInput(arg, QDir::currentPath(), QUrl::AssumeLocalFile);
+ if (!url.isValid()) {
+ fprintf(stderr, "Invalid URL: \"%s\"\n", qPrintable(arg));
+ return QUrl();
+ }
+ if (url.isLocalFile()) {
+ const QFileInfo fi(url.toLocalFile());
+ if (!fi.exists()) {
+ fprintf(stderr, "\"%s\" does not exist.\n",
+ qPrintable(QDir::toNativeSeparators(fi.absoluteFilePath())));
+ return QUrl();
+ }
+ }
+ return url;
+}
+
+static QQuickWindow::TextRenderType parseTextRenderType(const QString &renderType)
+{
+ if (renderType == QLatin1String("qt"))
+ return QQuickWindow::QtTextRendering;
+ else if (renderType == QLatin1String("native"))
+ return QQuickWindow::NativeTextRendering;
+
+ usage();
+
+ Q_UNREACHABLE();
+ return QQuickWindow::QtTextRendering;
+}
+
+class DummyTestRootObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged)
+
+public:
+ DummyTestRootObject(QObject *o) : QObject(o) {}
+
+ bool windowShown() const { return false; }
+
+Q_SIGNALS:
+ void windowShownChanged();
+};
+
+static QObject *s_testRootObject = nullptr;
+static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine)
+{
+ Q_UNUSED(jsEngine);
+ if (!s_testRootObject) {
+ s_testRootObject = new DummyTestRootObject(engine);
+ }
+ return s_testRootObject;
+}
+
+int main(int argc, char ** argv)
+{
+ Options options;
+
+ QStringList imports;
+ QStringList pluginPaths;
+
+ // Parse arguments for application attributes to be applied before Q[Gui]Application creation.
+ for (int i = 1; i < argc; ++i) {
+ const char *arg = argv[i];
+ if (!qstrcmp(arg, "--disable-context-sharing")) {
+ options.applicationAttributes.removeAll(Qt::AA_ShareOpenGLContexts);
+ } else if (!qstrcmp(arg, "--gles")) {
+ options.applicationAttributes.append(Qt::AA_UseOpenGLES);
+ } else if (!qstrcmp(arg, "--software")) {
+ options.applicationAttributes.append(Qt::AA_UseSoftwareOpenGL);
+ } else if (!qstrcmp(arg, "--desktop")) {
+ options.applicationAttributes.append(Qt::AA_UseDesktopOpenGL);
+ } else if (!qstrcmp(arg, "--scaling")) {
+ options.applicationAttributes.append(Qt::AA_EnableHighDpiScaling);
+ } else if (!qstrcmp(arg, "--no-scaling")) {
+ options.applicationAttributes.append(Qt::AA_DisableHighDpiScaling);
+ } else if (!qstrcmp(arg, "--apptype")) {
+ if (++i >= argc)
+ usage();
+ if (!qstrcmp(argv[i], "gui"))
+ options.applicationType = Options::QmlApplicationTypeGui;
+ }
+ }
+
+ for (Qt::ApplicationAttribute a : qAsConst(options.applicationAttributes))
+ QCoreApplication::setAttribute(a);
+ QScopedPointer<QGuiApplication> app;
+#ifdef QT_WIDGETS_LIB
+ if (options.applicationType == Options::QmlApplicationTypeWidget)
+ app.reset(new QApplication(argc, argv));
+#endif
+ if (app.isNull())
+ app.reset(new QGuiApplication(argc, argv));
+ QCoreApplication::setApplicationName(QStringLiteral("Viewer for Triton qml tests"));
+ QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
+ QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org"));
+ QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
+
+ const QStringList arguments = QCoreApplication::arguments();
+ for (int i = 1, size = arguments.size(); i < size; ++i) {
+ if (!arguments.at(i).startsWith(QLatin1Char('-'))) {
+ options.url = parseUrlArgument(arguments.at(i));
+ } else {
+ const QString lowerArgument = arguments.at(i).toLower();
+ if (lowerArgument == QLatin1String("--maximized"))
+ options.maximized = true;
+ else if (lowerArgument == QLatin1String("--fullscreen"))
+ options.fullscreen = true;
+ else if (lowerArgument == QLatin1String("--transparent"))
+ options.transparent = true;
+ else if (lowerArgument == QLatin1String("--clip"))
+ options.clip = true;
+ else if (lowerArgument == QLatin1String("--no-version-detection"))
+ options.versionDetection = false;
+ else if (lowerArgument == QLatin1String("--slow-animations"))
+ options.slowAnimations = true;
+ else if (lowerArgument == QLatin1String("--quit"))
+ options.quitImmediately = true;
+ else if (lowerArgument == QLatin1String("-translation"))
+ options.translationFile = QLatin1String(argv[++i]);
+ else if (lowerArgument == QLatin1String("--resize-to-root"))
+ options.resizeViewToRootItem = true;
+ else if (lowerArgument == QLatin1String("--multisample"))
+ options.multisample = true;
+ else if (lowerArgument == QLatin1String("--core-profile"))
+ options.coreProfile = true;
+ else if (lowerArgument == QLatin1String("--verbose"))
+ options.verbose = true;
+ else if (lowerArgument == QLatin1String("-i") && i + 1 < size)
+ imports.append(arguments.at(++i));
+ else if (lowerArgument == QLatin1String("-p") && i + 1 < size)
+ pluginPaths.append(arguments.at(++i));
+ else if (lowerArgument == QLatin1String("--apptype"))
+ ++i; // Consume previously parsed argument
+ else if (lowerArgument == QLatin1String("--textrendertype") && i + 1 < size)
+ options.textRenderType = parseTextRenderType(arguments.at(++i));
+ else if (lowerArgument == QLatin1String("--help")
+ || lowerArgument == QLatin1String("-help")
+ || lowerArgument == QLatin1String("--h")
+ || lowerArgument == QLatin1String("-h"))
+ usage();
+ }
+ }
+
+#if QT_CONFIG(translation)
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ if (qtTranslator.load(QLatin1String("qt_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ app->installTranslator(&qtTranslator);
+ if (translator.load(QLatin1String("qmlscene_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ app->installTranslator(&translator);
+
+ QTranslator qmlTranslator;
+ if (!options.translationFile.isEmpty()) {
+ if (qmlTranslator.load(options.translationFile)) {
+ app->installTranslator(&qmlTranslator);
+ } else {
+ fprintf(stderr, "Could not load the translation file \"%s\"\n",
+ qPrintable(options.translationFile));
+ }
+ }
+#endif
+
+ QQuickWindow::setTextRenderType(options.textRenderType);
+
+ QUnifiedTimer::instance()->setSlowModeEnabled(options.slowAnimations);
+
+ if (options.url.isEmpty())
+#if defined(QMLSCENE_BUNDLE)
+ displayOptionsDialog(&options);
+#else
+ displayFileDialog(&options);
+#endif
+
+ int exitCode = 0;
+
+ if (options.verbose)
+ puts(QLibraryInfo::build());
+
+ if (!options.url.isEmpty()) {
+ if (!options.versionDetection || checkVersion(options.url)) {
+#if QT_CONFIG(translation)
+ QTranslator translator;
+#endif
+
+ // TODO: as soon as the engine construction completes, the debug service is
+ // listening for connections. But actually we aren't ready to debug anything.
+ QQmlEngine engine;
+ QPointer<QQmlComponent> component = new QQmlComponent(&engine);
+ for (int i = 0; i < imports.size(); ++i)
+ engine.addImportPath(imports.at(i));
+ for (int i = 0; i < pluginPaths.size(); ++i)
+ engine.addPluginPath(pluginPaths.at(i));
+ if (options.url.isLocalFile()) {
+ QFileInfo fi(options.url.toLocalFile());
+#if QT_CONFIG(translation)
+ loadTranslationFile(translator, fi.path());
+#endif
+ loadDummyDataFiles(engine, fi.path());
+ }
+
+ qmlRegisterSingletonType<QObject>("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject);
+
+ QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ QObject::connect(&engine, &QQmlEngine::exit, QCoreApplication::instance(), &QCoreApplication::exit);
+ component->loadUrl(options.url);
+ while (component->isLoading())
+ QCoreApplication::processEvents();
+ if ( !component->isReady() ) {
+ fprintf(stderr, "%s\n", qPrintable(component->errorString()));
+ return -1;
+ }
+
+ QObject *topLevel = component->create();
+ if (!topLevel && component->isError()) {
+ fprintf(stderr, "%s\n", qPrintable(component->errorString()));
+ return -1;
+ }
+ QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(topLevel));
+ if (window) {
+ engine.setIncubationController(window->incubationController());
+ } else {
+ QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel);
+ if (contentItem) {
+ QQuickView* qxView = new QQuickView(&engine, NULL);
+ window.reset(qxView);
+ // Set window default properties; the qml can still override them
+ if (options.resizeViewToRootItem)
+ qxView->setResizeMode(QQuickView::SizeViewToRootObject);
+ else
+ qxView->setResizeMode(QQuickView::SizeRootObjectToView);
+ qxView->setContent(options.url, component, contentItem);
+ }
+ }
+
+#ifdef TRITON_ENABLE_TOUCH_EMULATION
+ QScopedPointer<MouseTouchAdaptor> mouseTouchAdaptor;
+ if (QTouchDevice::devices().isEmpty())
+ mouseTouchAdaptor.reset(MouseTouchAdaptor::instance());
+#endif
+
+ if (window) {
+ setWindowTitle(options.verbose, topLevel, window.data());
+#if QT_CONFIG(opengl)
+ if (options.verbose)
+ new DiagnosticGlContextCreationListener(window.data());
+#endif
+ QSurfaceFormat surfaceFormat = window->requestedFormat();
+ if (options.multisample)
+ surfaceFormat.setSamples(16);
+ if (options.transparent) {
+ surfaceFormat.setAlphaBufferSize(8);
+ window->setClearBeforeRendering(true);
+ window->setColor(QColor(Qt::transparent));
+ window->setFlags(Qt::FramelessWindowHint);
+ }
+ if (options.coreProfile) {
+ surfaceFormat.setVersion(4, 1);
+ surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
+ }
+ window->setFormat(surfaceFormat);
+
+ if (window->flags() == Qt::Window) // Fix window flags unless set by QML.
+ window->setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint);
+
+ if (options.fullscreen)
+ window->showFullScreen();
+ else if (options.maximized)
+ window->showMaximized();
+ else if (!window->isVisible())
+ window->show();
+ }
+
+ if (options.quitImmediately)
+ QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
+
+ // Now would be a good time to inform the debug service to start listening.
+
+ exitCode = app->exec();
+
+#ifdef QML_RUNTIME_TESTING
+ RenderStatistics::printTotalStats();
+#endif
+ // Ready to exit. Notice that the component might be owned by
+ // QQuickView if one was created. That case is tracked by
+ // QPointer, so it is safe to delete the component here.
+ delete component;
+ }
+ }
+
+ return exitCode;
+}
+
+#include "triton-qmlscene.moc"
diff --git a/tests/triton-qmlscene/triton-qmlscene.pro b/tests/triton-qmlscene/triton-qmlscene.pro
new file mode 100644
index 00000000..e0fa24ee
--- /dev/null
+++ b/tests/triton-qmlscene/triton-qmlscene.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = triton-qmlscene
+
+QT += qml quick quick-private gui-private core-private
+
+SOURCES = triton-qmlscene.cpp
+
+unix:!macos: {
+ CONFIG += link_pkgconfig
+ PKGCONFIG += xcb x11 xi
+ SOURCES += ../../src/MouseTouchAdaptor.cpp
+ HEADERS += ../../src/MouseTouchAdaptor.h
+ DEFINES += TRITON_ENABLE_TOUCH_EMULATION
+ INCLUDEPATH += $$SOURCE_DIR/src
+ QT += testlib
+}