diff options
-rw-r--r-- | qwebchannel.pro | 1 | ||||
-rw-r--r-- | src/src.pro | 4 | ||||
-rw-r--r-- | tests/qml/WebChannelTest.qml | 124 | ||||
-rw-r--r-- | tests/qml/method.html | 20 | ||||
-rw-r--r-- | tests/qml/property.html | 24 | ||||
-rw-r--r-- | tests/qml/qml.pro | 2 | ||||
-rw-r--r-- | tests/qml/signal.html | 20 | ||||
-rw-r--r-- | tests/qml/tst_metaobjectpublisher.qml | 162 | ||||
-rw-r--r-- | tests/qml/tst_webchannel.qml | 76 |
9 files changed, 359 insertions, 74 deletions
diff --git a/qwebchannel.pro b/qwebchannel.pro index 9611cb3..bbb213a 100644 --- a/qwebchannel.pro +++ b/qwebchannel.pro @@ -6,3 +6,4 @@ SUBDIRS = \ tests examples.depends = src +tests.depends = src diff --git a/src/src.pro b/src/src.pro index c20f118..bc61f5b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -9,8 +9,8 @@ CONFIG += qt plugin TARGET = $$qtLibraryTarget($$TARGET) # Input -SOURCES += qwebchannel_plugin.cpp -HEADERS += qwebchannel_plugin.h +SOURCES += $$PWD/qwebchannel_plugin.cpp +HEADERS += $$PWD/qwebchannel_plugin.h RESOURCES += \ resources.qrc diff --git a/tests/qml/WebChannelTest.qml b/tests/qml/WebChannelTest.qml new file mode 100644 index 0000000..ca2996d --- /dev/null +++ b/tests/qml/WebChannelTest.qml @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 + +import Qt.labs.WebChannel 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 + +TestCase { + // only run after the webchannel has finished initialization + when: webChannel.baseUrl != "" + + property var lastLoadStatus + + WebView { + id: view + + experimental.preferences.developerExtrasEnabled: 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" + } + } + + WebChannel { + id: webChannel + } + property var webChannel: webChannel + + SignalSpy { + id: rawMessageSpy + target: webChannel + signalName: "onRawMessageReceived" + } + property var rawMessageSpy: rawMessageSpy + property var rawMessageIdx: 0; + + SignalSpy { + id: pongSpy + target: webChannel + signalName: "onPongReceived" + } + property var pongSpy: pongSpy + + function loadUrl(url) + { + verify(webChannel.baseUrl != "", "webChannel.baseUrl is empty"); + view.url = url + "?webChannelBaseUrl=" + webChannel.baseUrl; + // now wait for page to finish loading + do { + loadingSpy.wait(500); + } while (view.loading); + compare(lastLoadStatus, WebView.LoadSucceededStatus); + } + + function cleanup() + { + view.url = ""; + loadingSpy.clear(); + rawMessageSpy.clear(); + rawMessageIdx = 0; + pongSpy.clear(); + } + + 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); + } +} diff --git a/tests/qml/method.html b/tests/qml/method.html new file mode 100644 index 0000000..618550f --- /dev/null +++ b/tests/qml/method.html @@ -0,0 +1,20 @@ +<html> + <head> + <script type="text/javascript" src="qrc:///qwebchannel/webchannel.js"></script> + <script type="text/javascript" src="qrc:///qwebchannel/qobject.js"></script> + <script type="text/javascript"> + //BEGIN SETUP + var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]); + new QWebChannel(baseUrl, function(channel) { + setupQObjectWebChannel(channel, function() { + channel.subscribe("invokeMethod", function(arg) { + myObj.myMethod(arg); + }); + }); + }); + //END SETUP + </script> + </head> + <body> + </body> +</html> diff --git a/tests/qml/property.html b/tests/qml/property.html new file mode 100644 index 0000000..1a8360a --- /dev/null +++ b/tests/qml/property.html @@ -0,0 +1,24 @@ +<html> + <head> + <script type="text/javascript" src="qrc:///qwebchannel/webchannel.js"></script> + <script type="text/javascript" src="qrc:///qwebchannel/qobject.js"></script> + <script type="text/javascript"> + //BEGIN SETUP + var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]); + new QWebChannel(baseUrl, function(channel) { + setupQObjectWebChannel(channel, function() { + 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/qml/qml.pro b/tests/qml/qml.pro index d687e63..c969291 100644 --- a/tests/qml/qml.pro +++ b/tests/qml/qml.pro @@ -4,7 +4,7 @@ TARGET = qml CONFIG += warn_on qmltestcase -IMPORTPATH += $$OUT_PWD/../../src +IMPORTPATH += $$OUT_PWD/../../src $$PWD SOURCES += \ qml.cpp diff --git a/tests/qml/signal.html b/tests/qml/signal.html new file mode 100644 index 0000000..e3815cb --- /dev/null +++ b/tests/qml/signal.html @@ -0,0 +1,20 @@ +<html> + <head> + <script type="text/javascript" src="qrc:///qwebchannel/webchannel.js"></script> + <script type="text/javascript" src="qrc:///qwebchannel/qobject.js"></script> + <script type="text/javascript"> + //BEGIN SETUP + var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]); + new QWebChannel(baseUrl, function(channel) { + setupQObjectWebChannel(channel, function() { + myObj.mySignal.connect(function(arg) { + channel.exec({label: "signalReceived", value: arg}); + }); + }); + }); + //END SETUP + </script> + </head> + <body> + </body> +</html> diff --git a/tests/qml/tst_metaobjectpublisher.qml b/tests/qml/tst_metaobjectpublisher.qml new file mode 100644 index 0000000..7739b06 --- /dev/null +++ b/tests/qml/tst_metaobjectpublisher.qml @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +import Qt.labs.WebChannel 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; + } + } + + MetaObjectPublisher { + id: publisher + webChannel: test.webChannel + + Connections { + target: webChannel + onRawMessageReceived: { + var message = JSON.parse(rawMessage); + verify(message); + publisher.handleRequest(message); + } + } + } + + function initTestCase() + { + publisher.registerObjects({ + "myObj": myObj + }); + } + + function awaitInit() + { + var msg = awaitMessage(); + verify(msg); + verify(msg.data); + verify(msg.data.type); + compare(msg.data.type, "Qt.init"); + } + + function awaitIdle() + { + var msg = awaitMessage(); + verify(msg); + verify(msg.data); + compare(msg.data.type, "Qt.idle"); + verify(publisher.clientIsIdle) + } + + function test_property() + { + loadUrl("property.html"); + awaitInit(); + var msg = awaitMessage(); + compare(msg.data.label, "init"); + compare(msg.data.value, 1); + compare(myObj.myProperty, 1); + + awaitIdle(); + + // change property, should be propagated to HTML client and a message be send there + myObj.myProperty = 2; + msg = awaitMessage(); + compare(msg.data.label, "changed"); + compare(msg.data.value, 2); + compare(myObj.myProperty, 2); + + awaitIdle(); + + // now trigger a write from the client side + webChannel.sendMessage("setProperty", 3); + msg = awaitMessage(); + compare(myObj.myProperty, 3); + + // the above write is also propagated to the HTML client + msg = awaitMessage(); + 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, "Qt.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, "Qt.connectToSignal"); + compare(msg.data.object, "myObj"); + compare(msg.data.signal, "mySignal"); + + awaitIdle(); + + myObj.mySignal("test"); + + msg = awaitMessage(); + compare(msg.data.label, "signalReceived"); + compare(msg.data.value, "test"); + } +} diff --git a/tests/qml/tst_webchannel.qml b/tests/qml/tst_webchannel.qml index 10f885d..a915ea3 100644 --- a/tests/qml/tst_webchannel.qml +++ b/tests/qml/tst_webchannel.qml @@ -32,96 +32,31 @@ ****************************************************************************/ import QtQuick 2.0 -import QtTest 1.0 -import Qt.labs.WebChannel 1.0 -import QtWebKit 3.0 - -TestCase { +WebChannelTest { name: "WebChannel" - // only run after the webchannel has finished initialization - when: webChannel.baseUrl != "" - - property var lastLoadStatus - - WebView { - id: view - - 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" - } - } - - WebChannel { - id: webChannel - } - - SignalSpy { - id: rawMessageSpy - target: webChannel - signalName: "onRawMessageReceived" - } - - SignalSpy { - id: pongSpy - target: webChannel - signalName: "onPongReceived" - } - - function loadUrl(url) - { - verify(webChannel.baseUrl != "", "webChannel.baseUrl is empty"); - view.url = url + "?webChannelBaseUrl=" + webChannel.baseUrl; - // now wait for page to finish loading - do { - loadingSpy.wait(500); - } while (view.loading); - compare(lastLoadStatus, WebView.LoadSucceededStatus); - } - - function cleanup() - { - view.url = ""; - loadingSpy.clear(); - rawMessageSpy.clear(); - } - - //BEGIN TESTS function test_receiveRawMessage() { loadUrl("receiveRaw.html"); - rawMessageSpy.wait(500); - compare(rawMessageSpy.signalArguments[0][0], "foobar"); + compare(awaitRawMessage(), "foobar"); } function test_sendMessage() { loadUrl("send.html"); webChannel.sendMessage("myMessage", "foobar"); - rawMessageSpy.wait(500); - compare(rawMessageSpy.signalArguments[0][0], "myMessagePong:foobar"); + compare(awaitRawMessage(), "myMessagePong:foobar"); } function test_respondMessage() { loadUrl("respond.html"); - rawMessageSpy.wait(500); - var msg = JSON.parse(rawMessageSpy.signalArguments[0][0]); + var msg = awaitMessage(); verify(msg.id); compare(msg.data, "foobar"); webChannel.respond(msg.id, "barfoo"); - rawMessageSpy.wait(500); - compare(rawMessageSpy.signalArguments[1][0], "received:barfoo"); + compare(awaitRawMessage(), "received:barfoo"); } function test_ping() @@ -131,5 +66,4 @@ TestCase { pongSpy.wait(500); compare(pongSpy.count, 1); } - //END TESTS } |