summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDave Andrews <jetdog330@hotmail.com>2016-08-22 22:34:06 -0400
committerMilian Wolff <milian.wolff@kdab.com>2016-09-29 15:03:56 +0000
commite354bdc5cbe33621def2b200f01d6376291570fc (patch)
tree7e16e831f0a2ec9e90909ee3db522a03daa16db6 /tests
parent3b28a6956cb3cab087481312dc82a907b118e0de (diff)
downloadqtwebchannel-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')
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp45
-rw-r--r--tests/auto/webchannel/tst_webchannel.h11
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();