diff options
Diffstat (limited to 'tests/auto/qml')
-rw-r--r-- | tests/auto/qml/Client.qml | 24 | ||||
-rw-r--r-- | tests/auto/qml/testtransport.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qml/testtransport.h | 6 | ||||
-rw-r--r-- | tests/auto/qml/tst_metaobjectpublisher.qml | 320 | ||||
-rw-r--r-- | tests/auto/qml/tst_multiclient.qml | 13 | ||||
-rw-r--r-- | tests/auto/qml/tst_webchannel.qml | 242 |
6 files changed, 271 insertions, 358 deletions
diff --git a/tests/auto/qml/Client.qml b/tests/auto/qml/Client.qml index 9904fe8..d15fd58 100644 --- a/tests/auto/qml/Client.qml +++ b/tests/auto/qml/Client.qml @@ -68,15 +68,17 @@ Item { console.log("client posts message: ", message); } clientMessages.push(message); - serverTransport.textMessageReceived(message); + serverTransport.receiveMessage(message); } Component.onCompleted: { - serverTransport.sendTextMessageRequested.connect(function(message) { + serverTransport.sendMessageRequested.connect(function(message) { if (debug) { console.log("client received message: ", message); } - onmessage({data:message}); + if (onmessage) { + onmessage({data:message}); + } }); } } @@ -128,8 +130,11 @@ Item { function awaitMessage() { var msg = awaitRawMessage() + if (debug) { + console.log("handling message: ", msg); + } if (!msg) { - return msg; + return false; } return JSON.parse(msg); } @@ -138,17 +143,15 @@ Item { { var msg = awaitMessage(); verify(msg); - verify(msg.data); - verify(msg.data.type); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.init); + verify(msg.type); + compare(msg.type, JSClient.QWebChannelMessageTypes.init); } function awaitIdle() { var msg = awaitMessage(); verify(msg); - verify(msg.data); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.idle); + compare(msg.type, JSClient.QWebChannelMessageTypes.idle); verify(webChannel.clientIsIdle()) } @@ -158,8 +161,7 @@ Item { do { msg = awaitMessage(); verify(msg); - verify(msg.data); - } while (msg.data.type === JSClient.QWebChannelMessageTypes.idle); + } while (msg.type === JSClient.QWebChannelMessageTypes.idle); return msg; } diff --git a/tests/auto/qml/testtransport.cpp b/tests/auto/qml/testtransport.cpp index a332955..d73a4b8 100644 --- a/tests/auto/qml/testtransport.cpp +++ b/tests/auto/qml/testtransport.cpp @@ -41,6 +41,10 @@ #include "testtransport.h" +#include <QDebug> +#include <QJsonDocument> +#include <QJsonObject> + QT_BEGIN_NAMESPACE TestTransport::TestTransport(QObject *parent) @@ -49,9 +53,25 @@ TestTransport::TestTransport(QObject *parent) } -void TestTransport::sendTextMessage(const QString &message) +void TestTransport::sendMessage(const QJsonObject &message) +{ + emit sendMessageRequested(message); +} + +void TestTransport::receiveMessage(const QString &message) { - emit sendTextMessageRequested(message); + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error); + if (error.error) { + qWarning("Failed to parse JSON message: %s\nError is: %s", + qPrintable(message), qPrintable(error.errorString())); + return; + } else if (!doc.isObject()) { + qWarning("Received JSON message that is not an object: %s", + qPrintable(message)); + return; + } + emit messageReceived(doc.object(), this); } QT_END_NAMESPACE diff --git a/tests/auto/qml/testtransport.h b/tests/auto/qml/testtransport.h index dd07832..ed7eae9 100644 --- a/tests/auto/qml/testtransport.h +++ b/tests/auto/qml/testtransport.h @@ -52,10 +52,12 @@ class TestTransport : public QWebChannelAbstractTransport public: explicit TestTransport(QObject *parent = 0); - virtual void sendTextMessage(const QString &message); + virtual void sendMessage(const QJsonObject &message) Q_DECL_OVERRIDE; + + Q_INVOKABLE void receiveMessage(const QString &message); Q_SIGNALS: - void sendTextMessageRequested(const QString &message); + void sendMessageRequested(const QJsonObject &message); }; QT_END_NAMESPACE diff --git a/tests/auto/qml/tst_metaobjectpublisher.qml b/tests/auto/qml/tst_metaobjectpublisher.qml deleted file mode 100644 index 9b2088c..0000000 --- a/tests/auto/qml/tst_metaobjectpublisher.qml +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** 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 -import QtWebChannel.Tests 1.0 -import "qrc:///qtwebchannel/qwebchannel.js" as JSClient - -TestCase { - name: "MetaObjectPublisher" - - Client { - id: client - } - - 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) - } - } - - TestWebChannel { - id: webChannel - transports: [client.serverTransport] - registeredObjects: [myObj, myOtherObj, myFactory] - } - - function init() - { - myObj.myProperty = 1 - client.cleanup(); - } - - function test_property() - { - var channel = client.createChannel(function(channel) { - channel.exec({label: "init", value: channel.objects.myObj.myProperty}); - channel.objects.myObj.myPropertyChanged.connect(function() { - channel.exec({label: "changed", value: channel.objects.myObj.myProperty}); - }); - channel.subscribe("setProperty", function(newValue) { - channel.objects.myObj.myProperty = newValue; - }); - }); - - client.awaitInit(); - var msg = client.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 = client.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 = client.awaitMessageSkipIdle(); - compare(myObj.myProperty, 3); - - // the above write is also propagated to the HTML client - msg = client.awaitMessageSkipIdle(); - compare(msg.data.label, "changed"); - compare(msg.data.value, 3); - - client.awaitIdle(); - } - - function test_method() - { - var channel = client.createChannel(function (channel) { - channel.subscribe("invokeMethod", function (arg) { - channel.objects.myObj.myMethod(arg); - }); - }); - - client.awaitInit(); - client.awaitIdle(); - - webChannel.sendMessage("invokeMethod", "test"); - - var msg = client.awaitMessage(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.invokeMethod); - compare(msg.data.object, "myObj"); - compare(msg.data.args, ["test"]); - - compare(lastMethodArg, "test") - } - - function test_signal() - { - var channel = client.createChannel(function(channel) { - channel.objects.myObj.mySignal.connect(function(arg) { - channel.exec({label: "signalReceived", value: arg}); - }); - }); - client.awaitInit(); - - var msg = client.awaitMessage(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.connectToSignal); - compare(msg.data.object, "myObj"); - - client.awaitIdle(); - - myObj.mySignal("test"); - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.label, "signalReceived"); - compare(msg.data.value, "test"); - } - - function test_grouping() - { - var channel = client.createChannel(function(channel) { - channel.subscribe(JSClient.QWebChannelMessageTypes.propertyUpdate, function() { - channel.exec({label: "gotPropertyUpdate", values: [channel.objects.myObj.myProperty, channel.objects.myOtherObj.foo, channel.objects.myOtherObj.bar]}); - }); - }); - client.awaitInit(); - client.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 = client.awaitMessage(); - verify(msg); - compare(msg.data.label, "gotPropertyUpdate"); - compare(msg.data.values, [myObj.myProperty, myOtherObj.foo, myOtherObj.bar]); - - client.awaitIdle(); - } - - function test_wrapper() - { - var channel = client.createChannel(function(channel) { - channel.objects.myFactory.create("testObj", function(obj) { - channel.objects["testObj"] = obj; - obj.mySignal.connect(function(arg1, arg2) { - channel.exec({label: "signalReceived", args: [arg1, arg2]}); - }); - obj.myProperty = 42; - obj.myMethod("foobar"); - }); - channel.subscribe("triggerDelete", function() { - channel.objects.testObj.deleteLater(); - }); - channel.subscribe("report", function() { - channel.exec({label:"report", obj: channel.objects.testObj}) - }); - }); - client.awaitInit(); - - var msg = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.invokeMethod); - compare(msg.data.object, "myFactory"); - verify(myFactory.lastObj); - compare(myFactory.lastObj.objectName, "testObj"); - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.connectToSignal); - verify(msg.data.object); - var objId = msg.data.object; - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.connectToSignal); - compare(msg.data.object, objId); - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.setProperty); - compare(msg.data.object, objId); - compare(myFactory.lastObj.myProperty, 42); - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.invokeMethod); - compare(msg.data.object, objId); - compare(msg.data.args, ["foobar"]); - - msg = client.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 = client.awaitMessageSkipIdle(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.invokeMethod); - compare(msg.data.object, objId); - - client.awaitIdle(); - - webChannel.sendMessage("report"); - - msg = client.awaitMessageSkipIdle(); - compare(msg.data.label, "report"); - compare(msg.data.obj, {}); - } - - function test_disconnect() - { - var channel = client.createChannel(function(channel) { - channel.objects.myObj.mySignal.connect(function(arg) { - channel.exec({label: "mySignalReceived", args: [arg]}); - channel.objects.myObj.mySignal.disconnect(this); - }); - channel.subscribe("report", function() { - channel.exec({label: "report"}); - }); - }); - client.awaitInit(); - - var msg = client.awaitMessage(); - compare(msg.data.type, JSClient.QWebChannelMessageTypes.connectToSignal); - compare(msg.data.object, "myObj"); - - client.awaitIdle(); - - myObj.mySignal(42); - - msg = client.awaitMessage(); - compare(msg.data.label, "mySignalReceived"); - compare(msg.data.args, [42]); - - msg = client.awaitMessage(); - compare(msg.data.type, JSClient.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 = client.awaitMessage(); - compare(msg.data.label, "report"); - } -} diff --git a/tests/auto/qml/tst_multiclient.qml b/tests/auto/qml/tst_multiclient.qml index bca2a03..66357d1 100644 --- a/tests/auto/qml/tst_multiclient.qml +++ b/tests/auto/qml/tst_multiclient.qml @@ -56,9 +56,9 @@ TestCase { id: client2 } + property int bar: 0 QtObject { id: foo - property int bar: 0 signal ping() @@ -86,7 +86,7 @@ TestCase { { channel.objects.foo.ping.connect(function() { channel.objects.foo.pong(function(value) { - channel.exec({pongAnswer: value}); + channel.pongAnswer = value; }); }); } @@ -108,12 +108,7 @@ TestCase { client1.awaitMessage(); client2.awaitMessage(); - var msg = client1.awaitMessage(); - compare(msg.data.pongAnswer, 1); - msg = client2.awaitMessage(); - compare(msg.data.pongAnswer, 2); - - client1.awaitIdle(); - client2.awaitIdle(); + compare(c1.pongAnswer, 1); + compare(c2.pongAnswer, 2); } } diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml index 53c2b38..8ac59eb 100644 --- a/tests/auto/qml/tst_webchannel.qml +++ b/tests/auto/qml/tst_webchannel.qml @@ -44,6 +44,7 @@ import QtTest 1.0 import QtWebChannel 1.0 import QtWebChannel.Tests 1.0 +import "qrc:///qtwebchannel/qwebchannel.js" as JSClient TestCase { name: "WebChannel" @@ -52,35 +53,248 @@ TestCase { id: client } + 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) { + lastMethodArg = arg; + } + signal mySignal(var arg1, var arg2) + } + } + TestWebChannel { id: webChannel transports: [client.serverTransport] + registeredObjects: [myObj, myOtherObj, myFactory] } - function cleanup() + function init() { + myObj.myProperty = 1 client.cleanup(); } - function test_receiveRawMessage() + function test_property() { - var channel = client.createChannel(function (channel) { - channel.send("foobar"); - }, true /* raw */); - compare(client.awaitRawMessage(), "foobar"); + compare(myObj.myProperty, 1); + + var initialValue; + var changedValue; + + var channel = client.createChannel(function(channel) { + initialValue = channel.objects.myObj.myProperty; + channel.objects.myObj.myPropertyChanged.connect(function() { + changedValue = channel.objects.myObj.myProperty; + }); + // now trigger a write from the client side + channel.objects.myObj.myProperty = 3; + }); + + client.awaitInit(); + var msg = client.awaitMessage(); + + compare(initialValue, 1); + compare(myObj.myProperty, 3); + + client.awaitIdle(); + + // change property, should be propagated to HTML client and a message be send there + myObj.myProperty = 2; + compare(myObj.myProperty, 2); + client.awaitIdle(); + compare(changedValue, 2); } - function test_sendMessage() + function test_method() { var channel = client.createChannel(function (channel) { - channel.subscribe("myMessage", function(payload) { - channel.send("myMessagePong:" + payload); + channel.objects.myObj.myMethod("test"); + }); + + client.awaitInit(); + + var msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + compare(msg.object, "myObj"); + compare(msg.args, ["test"]); + + compare(lastMethodArg, "test") + + client.awaitIdle(); + } + + function test_signal() + { + var signalReceivedArg; + var channel = client.createChannel(function(channel) { + channel.objects.myObj.mySignal.connect(function(arg) { + signalReceivedArg = arg; + }); + }); + client.awaitInit(); + + var msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal); + compare(msg.object, "myObj"); + + client.awaitIdle(); + + myObj.mySignal("test"); + + compare(signalReceivedArg, "test"); + } + + function test_grouping() + { + var receivedPropertyUpdates = 0; + var properties = 0; + var channel = client.createChannel(function(channel) { + var originalHandler = channel.handlePropertyUpdate; + channel.handlePropertyUpdate = function(message) { + originalHandler(message); + receivedPropertyUpdates++; + properties = [channel.objects.myObj.myProperty, channel.objects.myOtherObj.foo, channel.objects.myOtherObj.bar]; + }; + }); + client.awaitInit(); + client.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; + } + + client.awaitIdle(); + compare(receivedPropertyUpdates, 1); + compare(properties, [myObj.myProperty, myOtherObj.foo, myOtherObj.bar]); + verify(!client.awaitMessage()); + } + + function test_wrapper() + { + var signalArgs; + var testObjBeforeDeletion; + var testObjAfterDeletion; + var channel = client.createChannel(function(channel) { + channel.objects.myFactory.create("testObj", function(obj) { + channel.objects.testObj = obj; + obj.mySignal.connect(function() { + signalArgs = arguments; + testObjBeforeDeletion = obj; + obj.deleteLater(); + testObjAfterDeletion = obj; + }); + obj.myProperty = 42; + obj.myMethod("foobar"); + }); + }); + client.awaitInit(); + + var msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + compare(msg.object, "myFactory"); + verify(myFactory.lastObj); + compare(myFactory.lastObj.objectName, "testObj"); + + // deleteLater signal connection + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal); + verify(msg.object); + var objId = msg.object; + + // mySignal connection + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal); + compare(msg.object, objId); + + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.setProperty); + compare(msg.object, objId); + compare(myFactory.lastObj.myProperty, 42); + + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + compare(msg.object, objId); + compare(msg.args, ["foobar"]); + compare(lastMethodArg, "foobar"); + + myFactory.lastObj.mySignal("foobar", 42); + + // deleteLater call + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + compare(msg.object, objId); + + compare(signalArgs, {"0": "foobar", "1": 42}); + + client.awaitIdle(); + + compare(JSON.stringify(testObjBeforeDeletion), JSON.stringify({})); + compare(JSON.stringify(testObjAfterDeletion), JSON.stringify({})); + compare(JSON.stringify(channel.objects.testObj), JSON.stringify({})); + } + + function test_disconnect() + { + var signalArg; + var channel = client.createChannel(function(channel) { + channel.objects.myObj.mySignal.connect(function(arg) { + signalArg = arg; + channel.objects.myObj.mySignal.disconnect(this); }); - channel.send("initialized"); - }, true /* raw */); + }); + client.awaitInit(); + + var msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal); + compare(msg.object, "myObj"); + + client.awaitIdle(); + + myObj.mySignal(42); + compare(signalArg, 42); + + msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.disconnectFromSignal); + compare(msg.object, "myObj"); - compare(client.awaitRawMessage(), "initialized"); - webChannel.sendMessage("myMessage", "foobar"); - compare(client.awaitRawMessage(), "myMessagePong:foobar"); + myObj.mySignal(0); + compare(signalArg, 42); } } |