summaryrefslogtreecommitdiff
path: root/tests/auto
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2014-07-02 16:03:37 +0200
committerMilian Wolff <milian.wolff@kdab.com>2014-07-03 13:44:42 +0200
commit5418f5795e2fd657efa3ceede749228c1e10d25c (patch)
tree0d3109f25ab416befbaa44ba26f1380d64b30db6 /tests/auto
parent3c1884f15ed1120bf36efb918cad0bcb461d5193 (diff)
downloadqtwebchannel-5418f5795e2fd657efa3ceede749228c1e10d25c.tar.gz
Add cmake test, adapt test directory layout and point to dev branches.
The auto tests are now located in tests/auto instead of directly in tests/. This is required to ensure the cmake test is found. Furthermore, the sync.profile is updated to point to refs/heads/dev, as we target Qt 5.4 with this new module. Change-Id: I1e6e99968b7081b5774eaf30319cac1fbaed35c2 Reviewed-by: Sergio Ahumada <sahumada@blackberry.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/auto.pro7
-rw-r--r--tests/auto/cmake/CMakeLists.txt14
-rw-r--r--tests/auto/cmake/cmake.pro7
-rw-r--r--tests/auto/qml/TestWebView.qml81
-rw-r--r--tests/auto/qml/WebChannelTest.qml157
-rw-r--r--tests/auto/qml/data/bench_init.html13
-rw-r--r--tests/auto/qml/data/disconnect.html21
-rw-r--r--tests/auto/qml/data/grouping.html17
-rw-r--r--tests/auto/qml/data/method.html17
-rw-r--r--tests/auto/qml/data/multiclient.html19
-rw-r--r--tests/auto/qml/data/property.html21
-rw-r--r--tests/auto/qml/data/receiveRaw.html15
-rw-r--r--tests/auto/qml/data/send.html17
-rw-r--r--tests/auto/qml/data/signal.html17
-rw-r--r--tests/auto/qml/data/testsetup.js47
-rw-r--r--tests/auto/qml/data/wrapper.html28
-rw-r--r--tests/auto/qml/qml.cpp44
-rw-r--r--tests/auto/qml/qml.pro19
-rw-r--r--tests/auto/qml/tst_bench.qml123
-rw-r--r--tests/auto/qml/tst_metaobjectpublisher.qml272
-rw-r--r--tests/auto/qml/tst_multiclient.qml99
-rw-r--r--tests/auto/qml/tst_webchannel.qml59
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp345
-rw-r--r--tests/auto/webchannel/tst_webchannel.h237
-rw-r--r--tests/auto/webchannel/webchannel.pro14
25 files changed, 1710 insertions, 0 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
new file mode 100644
index 0000000..4c998e9
--- /dev/null
+++ b/tests/auto/auto.pro
@@ -0,0 +1,7 @@
+TEMPLATE = subdirs
+
+SUBDIRS += cmake webchannel
+
+qtHaveModule(webkit):qtHaveModule(quick) {
+ SUBDIRS += qml
+}
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
new file mode 100644
index 0000000..1d588ac
--- /dev/null
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(qmake_cmake_files)
+
+enable_testing()
+
+find_package(Qt5Core REQUIRED)
+
+include("${_Qt5CTestMacros}")
+
+test_module_includes(
+ WebChannel QWebChannel
+)
diff --git a/tests/auto/cmake/cmake.pro b/tests/auto/cmake/cmake.pro
new file mode 100644
index 0000000..54d329c
--- /dev/null
+++ b/tests/auto/cmake/cmake.pro
@@ -0,0 +1,7 @@
+
+# Cause make to do nothing.
+TEMPLATE = subdirs
+
+CMAKE_QT_MODULES_UNDER_TEST = webchannel
+
+CONFIG += ctest_testcase
diff --git a/tests/auto/qml/TestWebView.qml b/tests/auto/qml/TestWebView.qml
new file mode 100644
index 0000000..3b12f38
--- /dev/null
+++ b/tests/auto/qml/TestWebView.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+
+WebView {
+ id: view
+ property var lastLoadStatus
+
+ experimental.preferences.developerExtrasEnabled: true
+ experimental.preferences.navigatorQtObjectEnabled: true
+
+ onLoadingChanged: {
+ // NOTE: we cannot use spy.signalArguments nor save the loadRequest anywhere, as it gets
+ // deleted after the slots connected to the signal have finished... i.e. it's a weak pointer,
+ // not a shared pointer. As such, we have to copy out the interesting data we need later on here...
+ lastLoadStatus = loadRequest.status
+ }
+
+ SignalSpy {
+ id: loadingSpy
+ target: view
+ signalName: "onLoadingChanged"
+ }
+
+ function waitForLoaded()
+ {
+ do {
+ loadingSpy.wait(500);
+ } while (loading);
+ return lastLoadStatus == WebView.LoadSucceededStatus;
+ }
+
+ function clear()
+ {
+ url = "";
+ loadingSpy.clear()
+ }
+}
diff --git a/tests/auto/qml/WebChannelTest.qml b/tests/auto/qml/WebChannelTest.qml
new file mode 100644
index 0000000..9a0baa9
--- /dev/null
+++ b/tests/auto/qml/WebChannelTest.qml
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+
+import QtWebChannel 1.0
+
+TestCase {
+ property var lastLoadStatus
+ property bool useWebViewTransport: false
+
+ // only run after the webchannel has finished initialization
+ when: webSocketTransport.baseUrl != ""
+
+ WebViewTransport {
+ id: webViewTransport
+ webViewExperimental: defaultView.experimental
+ }
+ WebSocketTransport {
+ id: webSocketTransport
+ }
+
+ TestWebView {
+ id: defaultView
+ }
+
+ WebChannel {
+ id: webChannel
+ }
+ property var webChannel: webChannel
+
+ SignalSpy {
+ id: rawMessageSpy
+ target: useWebViewTransport ? webViewTransport : webSocketTransport;
+ signalName: "onMessageReceived"
+ }
+ property var rawMessageSpy: rawMessageSpy
+ property var rawMessageIdx: 0;
+
+ function urlForFile(file)
+ {
+ verify(useWebViewTransport || webSocketTransport.baseUrl != "", "webSocketTransport.baseUrl is empty");
+ return "data/" + file + (!useWebViewTransport ? "?webChannelBaseUrl=" + webSocketTransport.baseUrl : "");
+ }
+
+ // load file in the given view or use the global one by default
+ function loadUrl(file, view)
+ {
+ if (useWebViewTransport) {
+ webChannel.disconnectFrom(webSocketTransport);
+ webChannel.connectTo(webViewTransport);
+ } else {
+ webChannel.disconnectFrom(webViewTransport);
+ webChannel.connectTo(webSocketTransport);
+ }
+ if (!view) {
+ view = defaultView;
+ }
+ view.url = urlForFile(file);
+ view.waitForLoaded();
+ }
+
+ function cleanup()
+ {
+ defaultView.clear();
+ rawMessageSpy.clear();
+ rawMessageIdx = 0;
+ }
+
+ function awaitRawMessage()
+ {
+ rawMessageSpy.wait(500);
+ if (rawMessageSpy.signalArguments.length <= rawMessageIdx) {
+ // still no message received, fail
+ return null;
+ }
+ return rawMessageSpy.signalArguments[rawMessageIdx++][0];
+ }
+
+ function awaitMessage()
+ {
+ var msg = awaitRawMessage()
+ if (!msg) {
+ return msg;
+ }
+ return JSON.parse(msg);
+ }
+
+ function awaitInit()
+ {
+ var msg = awaitMessage();
+ verify(msg);
+ verify(msg.data);
+ verify(msg.data.type);
+ compare(msg.data.type, qWebChannelMessageTypes.init);
+ }
+
+ function awaitIdle()
+ {
+ var msg = awaitMessage();
+ verify(msg);
+ verify(msg.data);
+ compare(msg.data.type, qWebChannelMessageTypes.idle);
+ verify(webChannel.test_clientIsIdle())
+ }
+
+ property var qWebChannelMessageTypes: ({
+ signal: 1,
+ propertyUpdate: 2,
+ init: 3,
+ idle: 4,
+ debug: 5,
+ invokeMethod: 6,
+ connectToSignal: 7,
+ disconnectFromSignal: 8,
+ setProperty: 9,
+ });
+}
diff --git a/tests/auto/qml/data/bench_init.html b/tests/auto/qml/data/bench_init.html
new file mode 100644
index 0000000..7d3af5b
--- /dev/null
+++ b/tests/auto/qml/data/bench_init.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {});
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/disconnect.html b/tests/auto/qml/data/disconnect.html
new file mode 100644
index 0000000..a9a479c
--- /dev/null
+++ b/tests/auto/qml/data/disconnect.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ myObj.mySignal.connect(function(arg) {
+ channel.exec({label: "mySignalReceived", args: [arg]});
+ myObj.mySignal.disconnect(this);
+ });
+ channel.subscribe("report", function() {
+ channel.exec({label: "report"});
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/grouping.html b/tests/auto/qml/data/grouping.html
new file mode 100644
index 0000000..f2d7aec
--- /dev/null
+++ b/tests/auto/qml/data/grouping.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ window.channel = createWebChannel(function(channel) {
+ channel.subscribe(QWebChannelMessageTypes.propertyUpdate, function() {
+ channel.exec({label: "gotPropertyUpdate", values: [myObj.myProperty(), myOtherObj.foo(), myOtherObj.bar()]});
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/method.html b/tests/auto/qml/data/method.html
new file mode 100644
index 0000000..6dbaa90
--- /dev/null
+++ b/tests/auto/qml/data/method.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ channel.subscribe("invokeMethod", function(arg) {
+ myObj.myMethod(arg);
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/multiclient.html b/tests/auto/qml/data/multiclient.html
new file mode 100644
index 0000000..1573a1a
--- /dev/null
+++ b/tests/auto/qml/data/multiclient.html
@@ -0,0 +1,19 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ foo.ping.connect(function() {
+ foo.pong(function(value) {
+ channel.exec({pongAnswer: value});
+ });
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/property.html b/tests/auto/qml/data/property.html
new file mode 100644
index 0000000..9565aaa
--- /dev/null
+++ b/tests/auto/qml/data/property.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ channel.exec({label: "init", value: myObj.myProperty()});
+ myObj.myPropertyChanged.connect(function() {
+ channel.exec({label: "changed", value: myObj.myProperty()});
+ });
+ channel.subscribe("setProperty", function(newValue) {
+ myObj.myProperty = newValue;
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/receiveRaw.html b/tests/auto/qml/data/receiveRaw.html
new file mode 100644
index 0000000..139b2b1
--- /dev/null
+++ b/tests/auto/qml/data/receiveRaw.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ channel.send("foobar");
+ }, true /* raw */);
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/send.html b/tests/auto/qml/data/send.html
new file mode 100644
index 0000000..c60fbf4
--- /dev/null
+++ b/tests/auto/qml/data/send.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ channel.subscribe("myMessage", function(payload) {
+ channel.send("myMessagePong:" + payload);
+ });
+ }, true /* raw */);
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/signal.html b/tests/auto/qml/data/signal.html
new file mode 100644
index 0000000..bdce0c7
--- /dev/null
+++ b/tests/auto/qml/data/signal.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ myObj.mySignal.connect(function(arg) {
+ channel.exec({label: "signalReceived", value: arg});
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/data/testsetup.js b/tests/auto/qml/data/testsetup.js
new file mode 100644
index 0000000..c0db83a
--- /dev/null
+++ b/tests/auto/qml/data/testsetup.js
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+window.createWebChannel = function(callback, raw)
+{
+ var baseUrlMatch = /[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search);
+ var transport = baseUrlMatch ? baseUrlMatch[1] : navigator.qt;
+ return new QWebChannel(transport, callback, raw);
+}
diff --git a/tests/auto/qml/data/wrapper.html b/tests/auto/qml/data/wrapper.html
new file mode 100644
index 0000000..a556486
--- /dev/null
+++ b/tests/auto/qml/data/wrapper.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript" src="testsetup.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ createWebChannel(function(channel) {
+ myFactory.create("testObj", function(obj) {
+ window[obj.objectName()] = obj;
+ obj.mySignal.connect(function(arg1, arg2) {
+ channel.exec({label: "signalReceived", args: [arg1, arg2]});
+ });
+ obj.myProperty = 42;
+ obj.myMethod("foobar");
+ });
+ channel.subscribe("triggerDelete", function() {
+ testObj.deleteLater();
+ });
+ channel.subscribe("report", function() {
+ channel.exec({label:"report", obj: testObj})
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/qml/qml.cpp b/tests/auto/qml/qml.cpp
new file mode 100644
index 0000000..7267842
--- /dev/null
+++ b/tests/auto/qml/qml.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQuickTest/quicktest.h>
+
+QUICK_TEST_MAIN(qml)
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
new file mode 100644
index 0000000..f86dc90
--- /dev/null
+++ b/tests/auto/qml/qml.pro
@@ -0,0 +1,19 @@
+QT += testlib webchannel
+TEMPLATE = app
+TARGET = qml
+
+CONFIG += warn_on qmltestcase
+
+# TODO: running tests without requiring make install
+IMPORTPATH += $$OUT_PWD/../../../qml $$PWD
+
+SOURCES += \
+ qml.cpp
+
+OTHER_FILES += \
+ WebChannelTest.qml \
+ tst_webchannel.qml \
+ tst_metaobjectpublisher.qml \
+ tst_bench.qml
+
+TESTDATA = data/*
diff --git a/tests/auto/qml/tst_bench.qml b/tests/auto/qml/tst_bench.qml
new file mode 100644
index 0000000..056dda9
--- /dev/null
+++ b/tests/auto/qml/tst_bench.qml
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+import QtWebChannel 1.0
+
+WebChannelTest {
+ name: "Bench"
+ id: test
+
+ Component {
+ id: component
+ QtObject {
+ property var p0 : 0
+ property var p1 : 0
+ property var p2 : 0
+ property var p3 : 0
+ property var p4 : 0
+ property var p5 : 0
+ property var p6 : 0
+ property var p7 : 0
+ property var p8 : 0
+ property var p9 : 0
+ function m0(arg1, arg2) {}
+ function m1(arg1, arg2) {}
+ function m2(arg1, arg2) {}
+ function m3(arg1, arg2) {}
+ function m4(arg1, arg2) {}
+ function m5(arg1, arg2) {}
+ function m6(arg1, arg2) {}
+ function m7(arg1, arg2) {}
+ function m8(arg1, arg2) {}
+ function m9(arg1, arg2) {}
+ signal s0(var arg1, var arg2)
+ signal s1(var arg1, var arg2)
+ signal s2(var arg1, var arg2)
+ signal s3(var arg1, var arg2)
+ signal s4(var arg1, var arg2)
+ signal s5(var arg1, var arg2)
+ signal s6(var arg1, var arg2)
+ signal s7(var arg1, var arg2)
+ signal s8(var arg1, var arg2)
+ signal s9(var arg1, var arg2)
+ }
+ }
+
+ property var objects: ({})
+
+ function initTestCase()
+ {
+ for (var i = 0; i < 100; ++i) {
+ var id = "obj" + i;
+ var properties = {objectName: id};
+ objects[id] = component.createObject(test, properties);
+ }
+
+ webChannel.registerObjects(objects);
+ }
+
+ function benchmark_init_baseline()
+ {
+ loadUrl("bench_init.html");
+ }
+
+ function benchmark_init_webview()
+ {
+ useWebViewTransport = true;
+ loadUrl("bench_init.html");
+ // init
+ awaitMessage();
+ // idle
+ awaitMessage();
+ }
+
+ function benchmark_init_websocket()
+ {
+ useWebViewTransport = false;
+ loadUrl("bench_init.html");
+ // init
+ awaitMessage();
+ // idle
+ awaitMessage();
+ }
+}
diff --git a/tests/auto/qml/tst_metaobjectpublisher.qml b/tests/auto/qml/tst_metaobjectpublisher.qml
new file mode 100644
index 0000000..e07f105
--- /dev/null
+++ b/tests/auto/qml/tst_metaobjectpublisher.qml
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+import QtWebChannel 1.0
+
+WebChannelTest {
+ name: "MetaObjectPublisher"
+ id: test
+
+ property var lastMethodArg
+
+ QtObject {
+ id: myObj
+ property int myProperty: 1
+
+ signal mySignal(var arg)
+
+ function myMethod(arg)
+ {
+ lastMethodArg = arg;
+ }
+
+ WebChannel.id: "myObj"
+ }
+ QtObject {
+ id: myOtherObj
+ property var foo: 1
+ property var bar: 1
+ WebChannel.id: "myOtherObj"
+ }
+ QtObject {
+ id: myFactory
+ property var lastObj
+ function create(id)
+ {
+ lastObj = component.createObject(myFactory, {objectName: id});
+ return lastObj;
+ }
+ WebChannel.id: "myFactory"
+ }
+
+ Component {
+ id: component
+ QtObject {
+ property var myProperty : 0
+ function myMethod(arg) {
+ mySignal(arg, myProperty);
+ }
+ signal mySignal(var arg1, var arg2)
+ }
+ }
+
+ function initTestCase()
+ {
+ webChannel.registeredObjects = [myObj, myOtherObj, myFactory];
+ }
+
+ function awaitMessageSkipIdle()
+ {
+ var msg;
+ do {
+ msg = awaitMessage();
+ verify(msg);
+ verify(msg.data);
+ } while (msg.data.type === qWebChannelMessageTypes.idle);
+ return msg;
+ }
+
+ function test_property()
+ {
+ myObj.myProperty = 1
+ loadUrl("property.html");
+ awaitInit();
+ var msg = awaitMessageSkipIdle();
+ compare(msg.data.label, "init");
+ compare(msg.data.value, 1);
+ compare(myObj.myProperty, 1);
+
+ // change property, should be propagated to HTML client and a message be send there
+ myObj.myProperty = 2;
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.label, "changed");
+ compare(msg.data.value, 2);
+ compare(myObj.myProperty, 2);
+
+ // now trigger a write from the client side
+ webChannel.sendMessage("setProperty", 3);
+ msg = awaitMessageSkipIdle();
+ compare(myObj.myProperty, 3);
+
+ // the above write is also propagated to the HTML client
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.label, "changed");
+ compare(msg.data.value, 3);
+
+ awaitIdle();
+ }
+
+ function test_method()
+ {
+ loadUrl("method.html");
+ awaitInit();
+ awaitIdle();
+
+ webChannel.sendMessage("invokeMethod", "test");
+
+ var msg = awaitMessage();
+ compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ compare(msg.data.object, "myObj");
+ compare(msg.data.args, ["test"]);
+
+ compare(lastMethodArg, "test")
+ }
+
+ function test_signal()
+ {
+ loadUrl("signal.html");
+ awaitInit();
+
+ var msg = awaitMessage();
+ compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ compare(msg.data.object, "myObj");
+
+ awaitIdle();
+
+ myObj.mySignal("test");
+
+ msg = awaitMessage();
+ compare(msg.data.label, "signalReceived");
+ compare(msg.data.value, "test");
+ }
+
+ function test_grouping()
+ {
+ loadUrl("grouping.html");
+ awaitInit();
+ awaitIdle();
+
+ // change properties a lot, we expect this to be grouped into a single update notification
+ for (var i = 0; i < 10; ++i) {
+ myObj.myProperty = i;
+ myOtherObj.foo = i;
+ myOtherObj.bar = i;
+ }
+
+ var msg = awaitMessage();
+ verify(msg);
+ compare(msg.data.label, "gotPropertyUpdate");
+ compare(msg.data.values, [myObj.myProperty, myOtherObj.foo, myOtherObj.bar]);
+
+ awaitIdle();
+ }
+
+ function test_wrapper()
+ {
+ loadUrl("wrapper.html");
+ awaitInit();
+
+ var msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ compare(msg.data.object, "myFactory");
+ verify(myFactory.lastObj);
+ compare(myFactory.lastObj.objectName, "testObj");
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ verify(msg.data.object);
+ var objId = msg.data.object;
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ compare(msg.data.object, objId);
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.setProperty);
+ compare(msg.data.object, objId);
+ compare(myFactory.lastObj.myProperty, 42);
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ compare(msg.data.object, objId);
+ compare(msg.data.args, ["foobar"]);
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.label, "signalReceived");
+ compare(msg.data.args, ["foobar", 42]);
+
+ // pass QObject* on the fly and trigger deleteLater from client side
+ webChannel.sendMessage("triggerDelete");
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ compare(msg.data.object, objId);
+
+ webChannel.sendMessage("report");
+
+ msg = awaitMessageSkipIdle();
+ compare(msg.data.label, "report");
+ compare(msg.data.obj, {});
+ }
+
+ function test_disconnect()
+ {
+ loadUrl("disconnect.html");
+ awaitInit();
+
+ var msg = awaitMessage();
+ compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ compare(msg.data.object, "myObj");
+
+ awaitIdle();
+
+ myObj.mySignal(42);
+
+ msg = awaitMessage();
+ compare(msg.data.label, "mySignalReceived");
+ compare(msg.data.args, [42]);
+
+ msg = awaitMessage();
+ compare(msg.data.type, qWebChannelMessageTypes.disconnectFromSignal);
+ compare(msg.data.object, "myObj");
+
+ myObj.mySignal(0);
+
+ // apparently one cannot expect failure in QML, so trigger another message
+ // and verify no mySignalReceived was triggered by the above emission
+ webChannel.sendMessage("report");
+
+ msg = awaitMessage();
+ compare(msg.data.label, "report");
+ }
+}
diff --git a/tests/auto/qml/tst_multiclient.qml b/tests/auto/qml/tst_multiclient.qml
new file mode 100644
index 0000000..519a63c
--- /dev/null
+++ b/tests/auto/qml/tst_multiclient.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+import QtWebChannel 1.0
+
+WebChannelTest {
+ name: "MultiClient"
+ id: test
+
+ QtObject {
+ id: foo
+ property int bar: 0
+
+ signal ping()
+
+ function pong()
+ {
+ return ++bar;
+ }
+
+ WebChannel.id: "foo"
+ }
+
+ TestWebView {
+ id: client1
+ }
+ TestWebView {
+ id: client2
+ }
+
+ function initTestCase()
+ {
+ webChannel.registeredObjects = [foo];
+ }
+
+ function test_multiclient()
+ {
+ loadUrl("multiclient.html", client1);
+ loadUrl("multiclient.html", client2);
+ // init, connect & idle messages for two clients
+ for (var i = 0; i < 3 * 2; ++i) {
+ awaitMessage();
+ }
+
+ foo.ping();
+
+ // invoke of pong method
+ awaitMessage();
+ awaitMessage();
+
+ var msg = awaitMessage();
+ compare(msg.data.pongAnswer, 1);
+ msg = awaitMessage();
+ compare(msg.data.pongAnswer, 2);
+
+ awaitIdle();
+ awaitIdle();
+ }
+}
diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml
new file mode 100644
index 0000000..dddba71
--- /dev/null
+++ b/tests/auto/qml/tst_webchannel.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+WebChannelTest {
+ name: "WebChannel"
+
+ function test_receiveRawMessage()
+ {
+ loadUrl("receiveRaw.html");
+ compare(awaitRawMessage(), "foobar");
+ }
+
+ function test_sendMessage()
+ {
+ loadUrl("send.html");
+ webChannel.sendMessage("myMessage", "foobar");
+ compare(awaitRawMessage(), "myMessagePong:foobar");
+ }
+}
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
new file mode 100644
index 0000000..ece02a8
--- /dev/null
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -0,0 +1,345 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_webchannel.h"
+
+#include <qwebchannel.h>
+#include <qwebchannel_p.h>
+#include <qmetaobjectpublisher_p.h>
+#include <qwebsockettransport.h>
+
+#include <QtTest>
+
+TestWebChannel::TestWebChannel(QObject *parent)
+ : QObject(parent)
+ , m_dummyTransport(new DummyTransport(this))
+ , m_lastInt(0)
+ , m_lastDouble(0)
+{
+}
+
+TestWebChannel::~TestWebChannel()
+{
+
+}
+
+void TestWebChannel::setInt(int i)
+{
+ m_lastInt = i;
+}
+
+void TestWebChannel::setDouble(double d)
+{
+ m_lastDouble = d;
+}
+
+void TestWebChannel::setVariant(const QVariant &v)
+{
+ m_lastVariant = v;
+}
+
+void TestWebChannel::testInitWebSocketTransport()
+{
+ QWebSocketTransport transport;
+ QSignalSpy initSpy(&transport, SIGNAL(initialized()));
+ QSignalSpy baseUrlSpy(&transport, SIGNAL(baseUrlChanged(QString)));
+
+ QVERIFY(initSpy.wait());
+ QCOMPARE(initSpy.size(), 1);
+ QCOMPARE(baseUrlSpy.size(), 1);
+ QCOMPARE(baseUrlSpy.first().size(), 1);
+ QCOMPARE(transport.baseUrl(), baseUrlSpy.first().first().toString());
+ QVERIFY(!transport.baseUrl().isEmpty());
+}
+
+void TestWebChannel::testRegisterObjects()
+{
+ QWebChannel channel;
+ QObject plain;
+
+ QHash<QString, QObject*> objects;
+ objects[QStringLiteral("plain")] = &plain;
+ objects[QStringLiteral("channel")] = &channel;
+ objects[QStringLiteral("publisher")] = channel.d->publisher;
+ objects[QStringLiteral("test")] = this;
+
+ channel.registerObjects(objects);
+}
+
+void TestWebChannel::testInfoForObject()
+{
+ TestObject obj;
+ obj.setObjectName("myTestObject");
+
+ QWebChannel channel;
+ const QJsonObject info = channel.d->publisher->classInfoForObject(&obj);
+
+ QCOMPARE(info.keys(), QStringList() << "enums" << "methods" << "properties" << "signals");
+
+ { // enums
+ QJsonObject fooEnum;
+ fooEnum["Asdf"] = TestObject::Asdf;
+ fooEnum["Bar"] = TestObject::Bar;
+ QJsonObject expected;
+ expected["Foo"] = fooEnum;
+ QCOMPARE(info["enums"].toObject(), expected);
+ }
+
+ { // methods & slots
+ QJsonArray expected;
+ {
+ QJsonArray method;
+ method.append(QStringLiteral("deleteLater"));
+ method.append(obj.metaObject()->indexOfMethod("deleteLater()"));
+ expected.append(method);
+ }
+ {
+ QJsonArray method;
+ method.append(QStringLiteral("slot1"));
+ method.append(obj.metaObject()->indexOfMethod("slot1()"));
+ expected.append(method);
+ }
+ {
+ QJsonArray method;
+ method.append(QStringLiteral("slot2"));
+ method.append(obj.metaObject()->indexOfMethod("slot2(QString)"));
+ expected.append(method);
+ }
+ {
+ QJsonArray method;
+ method.append(QStringLiteral("method1"));
+ method.append(obj.metaObject()->indexOfMethod("method1()"));
+ expected.append(method);
+ }
+ QCOMPARE(info["methods"].toArray(), expected);
+ }
+
+ { // signals
+ QJsonArray expected;
+ {
+ QJsonArray signal;
+ signal.append(QStringLiteral("destroyed"));
+ signal.append(obj.metaObject()->indexOfMethod("destroyed(QObject*)"));
+ expected.append(signal);
+ }
+ {
+ QJsonArray signal;
+ signal.append(QStringLiteral("sig1"));
+ signal.append(obj.metaObject()->indexOfMethod("sig1()"));
+ expected.append(signal);
+ }
+ {
+ QJsonArray signal;
+ signal.append(QStringLiteral("sig2"));
+ signal.append(obj.metaObject()->indexOfMethod("sig2(QString)"));
+ expected.append(signal);
+ }
+ QCOMPARE(info["signals"].toArray(), expected);
+ }
+
+ { // properties
+ QJsonArray expected;
+ {
+ QJsonArray property;
+ property.append(obj.metaObject()->indexOfProperty("objectName"));
+ property.append(QStringLiteral("objectName"));
+ {
+ QJsonArray signal;
+ signal.append(1);
+ signal.append(obj.metaObject()->indexOfMethod("objectNameChanged(QString)"));
+ property.append(signal);
+ }
+ property.append(obj.objectName());
+ expected.append(property);
+ }
+ {
+ QJsonArray property;
+ property.append(obj.metaObject()->indexOfProperty("foo"));
+ property.append(QStringLiteral("foo"));
+ {
+ QJsonArray signal;
+ property.append(signal);
+ }
+ property.append(obj.foo());
+ expected.append(property);
+ }
+ {
+ QJsonArray property;
+ property.append(obj.metaObject()->indexOfProperty("asdf"));
+ property.append(QStringLiteral("asdf"));
+ {
+ QJsonArray signal;
+ signal.append(1);
+ signal.append(obj.metaObject()->indexOfMethod("asdfChanged()"));
+ property.append(signal);
+ }
+ property.append(obj.asdf());
+ expected.append(property);
+ }
+ {
+ QJsonArray property;
+ property.append(obj.metaObject()->indexOfProperty("bar"));
+ property.append(QStringLiteral("bar"));
+ {
+ QJsonArray signal;
+ signal.append(QStringLiteral("theBarHasChanged"));
+ signal.append(obj.metaObject()->indexOfMethod("theBarHasChanged()"));
+ property.append(signal);
+ }
+ property.append(obj.bar());
+ expected.append(property);
+ }
+ QCOMPARE(info["properties"].toArray(), expected);
+ }
+}
+
+void TestWebChannel::testInvokeMethodConversion()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ QJsonArray args;
+ args.append(QJsonValue(1000));
+
+ {
+ int method = metaObject()->indexOfMethod("setInt(int)");
+ QVERIFY(method != -1);
+ QVERIFY(!channel.d->publisher->invokeMethod(this, method, args, QJsonValue()).isEmpty());
+ QCOMPARE(m_lastInt, args.at(0).toInt());
+ }
+ {
+ int method = metaObject()->indexOfMethod("setDouble(double)");
+ QVERIFY(method != -1);
+ QVERIFY(!channel.d->publisher->invokeMethod(this, method, args, QJsonValue()).isEmpty());
+ QCOMPARE(m_lastDouble, args.at(0).toDouble());
+ }
+ {
+ int method = metaObject()->indexOfMethod("setVariant(QVariant)");
+ QVERIFY(method != -1);
+ QVERIFY(!channel.d->publisher->invokeMethod(this, method, args, QJsonValue()).isEmpty());
+ QCOMPARE(m_lastVariant, args.at(0).toVariant());
+ }
+}
+
+static QHash<QString, QObject*> createObjects(QObject *parent)
+{
+ const int num = 100;
+ QHash<QString, QObject*> objects;
+ objects.reserve(num);
+ for (int i = 0; i < num; ++i) {
+ objects[QStringLiteral("obj%1").arg(i)] = new BenchObject(parent);
+ }
+ return objects;
+}
+
+void TestWebChannel::benchClassInfo()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ QObject parent;
+ const QHash<QString, QObject*> objects = createObjects(&parent);
+
+ QBENCHMARK {
+ foreach (const QObject *object, objects) {
+ channel.d->publisher->classInfoForObject(object);
+ }
+ }
+}
+
+void TestWebChannel::benchInitializeClients()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ QObject parent;
+ channel.registerObjects(createObjects(&parent));
+
+ QMetaObjectPublisher *publisher = channel.d->publisher;
+ QBENCHMARK {
+ publisher->initializeClients();
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+ publisher->signalHandler.clear();
+ }
+}
+
+void TestWebChannel::benchPropertyUpdates()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ QObject parent;
+ const QHash<QString, QObject*> objects = createObjects(&parent);
+ QVector<BenchObject*> objectList;
+ objectList.reserve(objects.size());
+ foreach (QObject *obj, objects) {
+ objectList << qobject_cast<BenchObject*>(obj);
+ }
+
+ channel.registerObjects(objects);
+ channel.d->publisher->initializeClients();
+
+ QBENCHMARK {
+ foreach (BenchObject *obj, objectList) {
+ obj->change();
+ }
+
+ channel.d->publisher->clientIsIdle = true;
+ channel.d->publisher->sendPendingPropertyUpdates();
+ }
+}
+
+void TestWebChannel::benchRegisterObjects()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ QObject parent;
+ const QHash<QString, QObject*> objects = createObjects(&parent);
+
+ QBENCHMARK {
+ channel.registerObjects(objects);
+ }
+}
+
+QTEST_MAIN(TestWebChannel)
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
new file mode 100644
index 0000000..314fe99
--- /dev/null
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_WEBCHANNEL_H
+#define TST_WEBCHANNEL_H
+
+#include <QObject>
+#include <QVariant>
+#include <qwebchanneltransportinterface.h>
+
+class DummyTransport : public QObject, public QWebChannelTransportInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QWebChannelTransportInterface)
+public:
+ explicit DummyTransport(QObject *parent)
+ : QObject(parent)
+ {}
+ ~DummyTransport() {};
+
+ void sendMessage(const QString &/*message*/, int /*clientId*/) const Q_DECL_OVERRIDE
+ {}
+ void sendMessage(const QByteArray &/*message*/, int /*clientId*/) const Q_DECL_OVERRIDE
+ {}
+ void setMessageHandler(QWebChannelMessageHandlerInterface * /*handler*/) Q_DECL_OVERRIDE
+ {}
+};
+
+class TestObject : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(Foo)
+
+ Q_PROPERTY(Foo foo READ foo CONSTANT)
+ Q_PROPERTY(int asdf READ asdf NOTIFY asdfChanged)
+ Q_PROPERTY(QString bar READ bar NOTIFY theBarHasChanged)
+public:
+ explicit TestObject(QObject *parent = 0)
+ : QObject(parent)
+ { }
+
+ enum Foo {
+ Bar,
+ Asdf
+ };
+
+ Foo foo() const {return Bar;}
+ int asdf() const {return 42;}
+ QString bar() const {return QString();}
+
+ Q_INVOKABLE void method1() {}
+
+protected:
+ Q_INVOKABLE void method2() {}
+
+private:
+ Q_INVOKABLE void method3() {}
+
+signals:
+ void sig1();
+ void sig2(const QString&);
+ void asdfChanged();
+ void theBarHasChanged();
+
+public slots:
+ void slot1() {}
+ void slot2(const QString&) {}
+
+protected slots:
+ void slot3() {}
+
+private slots:
+ void slot4() {}
+};
+
+class BenchObject : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int p0 MEMBER m_p0 NOTIFY p0Changed)
+ Q_PROPERTY(int p1 MEMBER m_p1 NOTIFY p1Changed)
+ Q_PROPERTY(int p2 MEMBER m_p2 NOTIFY p2Changed)
+ Q_PROPERTY(int p3 MEMBER m_p3 NOTIFY p3Changed)
+ Q_PROPERTY(int p4 MEMBER m_p4 NOTIFY p4Changed)
+ Q_PROPERTY(int p5 MEMBER m_p5 NOTIFY p5Changed)
+ Q_PROPERTY(int p6 MEMBER m_p6 NOTIFY p6Changed)
+ Q_PROPERTY(int p7 MEMBER m_p7 NOTIFY p7Changed)
+ Q_PROPERTY(int p8 MEMBER m_p8 NOTIFY p8Changed)
+ Q_PROPERTY(int p9 MEMBER m_p9 NOTIFY p9Changed)
+public:
+ explicit BenchObject(QObject *parent = 0)
+ : QObject(parent)
+ , m_p0(0)
+ , m_p1(0)
+ , m_p2(0)
+ , m_p3(0)
+ , m_p4(0)
+ , m_p5(0)
+ , m_p6(0)
+ , m_p7(0)
+ , m_p8(0)
+ , m_p9(0)
+ { }
+
+ void change()
+ {
+ m_p0++;
+ m_p1++;
+ m_p2++;
+ m_p3++;
+ m_p4++;
+ m_p5++;
+ m_p6++;
+ m_p7++;
+ m_p8++;
+ m_p9++;
+ emit p0Changed(m_p0);
+ emit p1Changed(m_p1);
+ emit p2Changed(m_p2);
+ emit p3Changed(m_p3);
+ emit p4Changed(m_p4);
+ emit p5Changed(m_p5);
+ emit p6Changed(m_p6);
+ emit p7Changed(m_p7);
+ emit p8Changed(m_p8);
+ emit p9Changed(m_p9);
+ }
+
+signals:
+ void s0();
+ void s1();
+ void s2();
+ void s3();
+ void s4();
+ void s5();
+ void s6();
+ void s7();
+ void s8();
+ void s9();
+
+ void p0Changed(int);
+ void p1Changed(int);
+ void p2Changed(int);
+ void p3Changed(int);
+ void p4Changed(int);
+ void p5Changed(int);
+ void p6Changed(int);
+ void p7Changed(int);
+ void p8Changed(int);
+ void p9Changed(int);
+
+public slots:
+ void m0(){};
+ void m1(){};
+ void m2(){};
+ void m3(){};
+ void m4(){};
+ void m5(){};
+ void m6(){};
+ void m7(){};
+ void m8(){};
+ void m9(){};
+
+private:
+ int m_p0, m_p1, m_p2, m_p3, m_p4, m_p5, m_p6, m_p7, m_p8, m_p9;
+};
+
+class TestWebChannel : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit TestWebChannel(QObject *parent = 0);
+ virtual ~TestWebChannel();
+
+ Q_INVOKABLE void setInt(int i);
+ Q_INVOKABLE void setDouble(double d);
+ Q_INVOKABLE void setVariant(const QVariant &v);
+
+private slots:
+ void testInitWebSocketTransport();
+ void testRegisterObjects();
+ void testInfoForObject();
+ void testInvokeMethodConversion();
+
+ void benchClassInfo();
+ void benchInitializeClients();
+ void benchPropertyUpdates();
+ void benchRegisterObjects();
+
+private:
+ DummyTransport *m_dummyTransport;
+
+ int m_lastInt;
+ double m_lastDouble;
+ QVariant m_lastVariant;
+};
+
+#endif // TST_WEBCHANNEL_H
diff --git a/tests/auto/webchannel/webchannel.pro b/tests/auto/webchannel/webchannel.pro
new file mode 100644
index 0000000..71036dd
--- /dev/null
+++ b/tests/auto/webchannel/webchannel.pro
@@ -0,0 +1,14 @@
+QT = core webchannel-private testlib
+
+CONFIG += testcase strict_flags warn_on
+
+INCLUDEPATH += ../../../src/webchannel
+VPATH += ../../../src/webchannel
+
+TARGET = tst_webchannel
+
+SOURCES += \
+ tst_webchannel.cpp
+
+HEADERS += \
+ tst_webchannel.h