diff options
author | Dave Andrews <jetdog330@hotmail.com> | 2016-08-22 22:34:06 -0400 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2016-09-29 15:03:56 +0000 |
commit | e354bdc5cbe33621def2b200f01d6376291570fc (patch) | |
tree | 7e16e831f0a2ec9e90909ee3db522a03daa16db6 /tests/auto | |
parent | 3b28a6956cb3cab087481312dc82a907b118e0de (diff) | |
download | qtwebchannel-e354bdc5cbe33621def2b200f01d6376291570fc.tar.gz |
Fix asynchronous method calls on QObjects in different threads
Use QMetaMethod::invoke without a return for void method calls,
which allows making asynchronous method calls onto QObjects in
different affinities than the QWebChannel that's emitting them.
Also adds a unit test called testAsyncObject that intentionally
places a QObject in a different affinity and then tests calls
into it from the QWebChannel's synchronous publisher.
Task-number: QTBUG-47678
Change-Id: I6c35ee54f764c0fc1b0431fb0774aa7e75039abf
Reviewed-by: Dave Andrews <jetdog330@hotmail.com>
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/webchannel/tst_webchannel.cpp | 45 | ||||
-rw-r--r-- | tests/auto/webchannel/tst_webchannel.h | 11 |
2 files changed, 56 insertions, 0 deletions
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp index 5ee26ec..55723ea 100644 --- a/tests/auto/webchannel/tst_webchannel.cpp +++ b/tests/auto/webchannel/tst_webchannel.cpp @@ -370,6 +370,12 @@ void TestWebChannel::testInfoForObject() } { QJsonArray method; + method.append(QStringLiteral("setProp")); + method.append(obj.metaObject()->indexOfMethod("setProp(QString)")); + expected.append(method); + } + { + QJsonArray method; method.append(QStringLiteral("method1")); method.append(obj.metaObject()->indexOfMethod("method1()")); expected.append(method); @@ -478,6 +484,19 @@ void TestWebChannel::testInfoForObject() property.append(QJsonValue::fromVariant(QVariant::fromValue(obj.returnedObject()))); expected.append(property); } + { + QJsonArray property; + property.append(obj.metaObject()->indexOfProperty("prop")); + property.append(QStringLiteral("prop")); + { + QJsonArray signal; + signal.append(1); + signal.append(obj.metaObject()->indexOfMethod("propChanged(QString)")); + property.append(signal); + } + property.append(QJsonValue::fromVariant(QVariant::fromValue(obj.prop()))); + expected.append(property); + } QCOMPARE(info["properties"].toArray(), expected); } } @@ -699,6 +718,32 @@ void TestWebChannel::testInfiniteRecursion() QJsonObject objectInfo = channel.d_func()->publisher->wrapResult(QVariant::fromValue(&obj), m_dummyTransport).toObject(); } +void TestWebChannel::testAsyncObject() +{ + QWebChannel channel; + channel.connectTo(m_dummyTransport); + + QThread thread; + thread.start(); + + TestObject obj; + obj.moveToThread(&thread); + + QJsonArray args; + args.append(QJsonValue("message")); + + int method = obj.metaObject()->indexOfMethod("setProp(QString)"); + QVERIFY(method != -1); + + QSignalSpy spy(&obj, &TestObject::propChanged); + channel.d_func()->publisher->invokeMethod(&obj, method, args); + QVERIFY(spy.wait()); + QCOMPARE(spy.at(0).at(0).toString(), args.at(0).toString()); + + thread.quit(); + thread.wait(); +} + static QHash<QString, QObject*> createObjects(QObject *parent) { const int num = 100; diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h index 0f5cf1c..70a368c 100644 --- a/tests/auto/webchannel/tst_webchannel.h +++ b/tests/auto/webchannel/tst_webchannel.h @@ -74,6 +74,7 @@ class TestObject : public QObject Q_PROPERTY(QString bar READ bar NOTIFY theBarHasChanged) Q_PROPERTY(QObject * objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectPropertyChanged) Q_PROPERTY(TestObject * returnedObject READ returnedObject WRITE setReturnedObject NOTIFY returnedObjectChanged) + Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged) public: explicit TestObject(QObject *parent = 0) @@ -101,6 +102,11 @@ public: return mReturnedObject; } + QString prop() const + { + return mProp; + } + Q_INVOKABLE void method1() {} protected: @@ -116,6 +122,7 @@ signals: void theBarHasChanged(); void objectPropertyChanged(); void returnedObjectChanged(); + void propChanged(const QString&); public slots: void slot1() {} @@ -133,6 +140,8 @@ public slots: emit objectPropertyChanged(); } + void setProp(const QString&prop) {emit propChanged(mProp=prop);} + protected slots: void slot3() {} @@ -142,6 +151,7 @@ private slots: public: QObject *mObjectProperty; TestObject *mReturnedObject; + QString mProp; }; class BenchObject : public QObject @@ -286,6 +296,7 @@ private slots: void testRemoveUnusedTransports(); void testPassWrappedObjectBack(); void testInfiniteRecursion(); + void testAsyncObject(); void benchClassInfo(); void benchInitializeClients(); |