summaryrefslogtreecommitdiff
path: root/tests/auto/webchannel/tst_webchannel.cpp
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2017-12-15 13:04:02 +0100
committerJüri Valdmann <juri.valdmann@qt.io>2018-01-08 13:53:50 +0000
commit6701ff310933ec33f9199b53d78299764f646387 (patch)
tree5ef941383eb8021acb81ed00a65cc25ff43906e8 /tests/auto/webchannel/tst_webchannel.cpp
parentb90fbebbb5e257f771e96980109fb543647b1844 (diff)
downloadqtwebchannel-6701ff310933ec33f9199b53d78299764f646387.tar.gz
Allow deleting a channel during method invocation
A real-life use case is the session restore page in KDE Falkon or, more generally, any kind of closeTab() method exposed to JS in a QWebEnginePage. The approach taken in this patch will only work if the transport can also deal with deletion during a messageReceived signal emission. Alternatively, method invocation could be delayed via the event loop, but this would come with an obvious performance penalty. Change-Id: I2940f61e07c77365f6e3e7cd29463d4cb5b525a6 Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'tests/auto/webchannel/tst_webchannel.cpp')
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index f214b7e..602a101 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -814,6 +814,58 @@ void TestWebChannel::testAsyncObject()
thread.wait();
}
+class FunctionWrapper : public QObject
+{
+ Q_OBJECT
+ std::function<void()> m_fun;
+public:
+ FunctionWrapper(std::function<void()> fun) : m_fun(std::move(fun)) {}
+public slots:
+ void invoke()
+ {
+ m_fun();
+ }
+};
+
+void TestWebChannel::testDeletionDuringMethodInvocation_data()
+{
+ QTest::addColumn<bool>("deleteChannel");
+ QTest::addColumn<bool>("deleteTransport");
+ QTest::newRow("delete neither") << false << false;
+ QTest::newRow("delete channel") << true << false;
+ QTest::newRow("delete transport") << false << true;
+ QTest::newRow("delete both") << true << true;
+}
+
+void TestWebChannel::testDeletionDuringMethodInvocation()
+{
+ QFETCH(bool, deleteChannel);
+ QFETCH(bool, deleteTransport);
+
+ QScopedPointer<QWebChannel> channel(new QWebChannel);
+ QScopedPointer<DummyTransport> transport(new DummyTransport(nullptr));
+ FunctionWrapper deleter([&](){
+ if (deleteChannel)
+ channel.reset();
+ if (deleteTransport)
+ transport.reset();
+ });
+ channel->registerObject("deleter", &deleter);
+ channel->connectTo(transport.data());
+
+ transport->emitMessageReceived({
+ {"type", TypeInvokeMethod},
+ {"object", "deleter"},
+ {"method", deleter.metaObject()->indexOfMethod("invoke()")},
+ {"id", 42}
+ });
+
+ QCOMPARE(deleteChannel, !channel);
+ QCOMPARE(deleteTransport, !transport);
+ if (!deleteTransport)
+ QCOMPARE(transport->messagesSent().size(), deleteChannel ? 0 : 1);
+}
+
static QHash<QString, QObject*> createObjects(QObject *parent)
{
const int num = 100;