diff options
-rw-r--r-- | src/qobject.js | 6 | ||||
-rw-r--r-- | tests/qml/tst_metaobjectpublisher.qml | 77 | ||||
-rw-r--r-- | tests/qml/wrapper.html | 32 |
3 files changed, 114 insertions, 1 deletions
diff --git a/src/qobject.js b/src/qobject.js index cbff4f1..048295c 100644 --- a/src/qobject.js +++ b/src/qobject.js @@ -71,6 +71,12 @@ function QObject(name, data, webChannel) qObject.destroyed.connect(function() { if (webChannel.objectMap[objectId] === qObject) { delete webChannel.objectMap[objectId]; + // reset the now deleted QObject to an empty {} object + // just assigning {} though would not have the desired effect, but the + // below also ensures all external references will see the empty map + for (var prop in qObject) { + delete qObject[prop]; + } } }); return qObject; diff --git a/tests/qml/tst_metaobjectpublisher.qml b/tests/qml/tst_metaobjectpublisher.qml index 6f1d825..afbf624 100644 --- a/tests/qml/tst_metaobjectpublisher.qml +++ b/tests/qml/tst_metaobjectpublisher.qml @@ -57,6 +57,24 @@ WebChannelTest { property var foo: 1 property var bar: 1 } + QtObject { + id: myFactory + function create(id) + { + return component.createObject(myFactory, {objectName: id}); + } + } + + Component { + id: component + QtObject { + property var myProperty : 0 + function myMethod(arg) { + mySignal(arg, myProperty); + } + signal mySignal(var arg1, var arg2) + } + } MetaObjectPublisher { id: publisher @@ -76,7 +94,8 @@ WebChannelTest { { publisher.registerObjects({ "myObj": myObj, - "myOtherObj": myOtherObj + "myOtherObj": myOtherObj, + "myFactory": myFactory }); } @@ -188,4 +207,60 @@ WebChannelTest { awaitIdle(); } + function test_wrapper() + { + loadUrl("wrapper.html"); + awaitInit(); + + var msg = awaitMessage(); + compare(msg.data.type, "Qt.invokeMethod"); + compare(msg.data.object, "myFactory"); + compare(msg.data.method, "create"); + + awaitIdle(); + + msg = awaitMessage(); + compare(msg.data.type, "Qt.connectToSignal"); + compare(msg.data.signal, "destroyed"); + verify(msg.data.object); + var objId = msg.data.object; + var obj = publisher.unwrapObject(objId); + verify(obj); + compare(obj.objectName, "testObj"); + + msg = awaitMessage(); + compare(msg.data.type, "Qt.connectToSignal"); + compare(msg.data.object, objId); + compare(msg.data.signal, "mySignal"); + + msg = awaitMessage(); + compare(msg.data.type, "Qt.setProperty"); + compare(msg.data.object, objId); + compare(obj.myProperty, 42); + + msg = awaitMessage(); + compare(msg.data.type, "Qt.invokeMethod"); + compare(msg.data.object, objId); + compare(msg.data.method, "myMethod"); + compare(msg.data.args, ["foobar"]); + + msg = awaitMessage(); + 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"); + awaitIdle(); + + msg = awaitMessage(); + compare(msg.data.type, "Qt.invokeMethod"); + compare(msg.data.object, objId); + compare(msg.data.method, "deleteLater"); + verify(!publisher.unwrapObject(objId)); + + webChannel.sendMessage("report"); + msg = awaitMessage(); + compare(msg.data.label, "report"); + compare(msg.data.obj, {}); + } } diff --git a/tests/qml/wrapper.html b/tests/qml/wrapper.html new file mode 100644 index 0000000..a6c313b --- /dev/null +++ b/tests/qml/wrapper.html @@ -0,0 +1,32 @@ +<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() { + 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() { + console.log(testObj); + testObj.deleteLater(); + }); + channel.subscribe("report", function() { + channel.exec({label:"report", obj: testObj}) + }); + }); + }); + //END SETUP + </script> + </head> + <body> + </body> +</html> |