OSDN Git Service

add QDBusLocalCalls test
authorIvailo Monev <xakepa10@laimg.moc>
Wed, 29 Jan 2020 01:47:55 +0000 (01:47 +0000)
committerIvailo Monev <xakepa10@laimg.moc>
Wed, 29 Jan 2020 01:47:55 +0000 (01:47 +0000)
tests/auto/qdbuslocalcalls/CMakeLists.txt [new file with mode: 0644]
tests/auto/qdbuslocalcalls/tst_qdbuslocalcalls.cpp [new file with mode: 0644]

diff --git a/tests/auto/qdbuslocalcalls/CMakeLists.txt b/tests/auto/qdbuslocalcalls/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1af0c18
--- /dev/null
@@ -0,0 +1,7 @@
+if(WITH_DBUS AND DBUS_FOUND)
+    katie_test(tst_qdbuslocalcalls
+        ${CMAKE_CURRENT_SOURCE_DIR}/tst_qdbuslocalcalls.cpp
+    )
+
+    target_link_libraries(tst_qdbuslocalcalls KtDBus)
+endif()
\ No newline at end of file
diff --git a/tests/auto/qdbuslocalcalls/tst_qdbuslocalcalls.cpp b/tests/auto/qdbuslocalcalls/tst_qdbuslocalcalls.cpp
new file mode 100644 (file)
index 0000000..9e4e919
--- /dev/null
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016-2020 Ivailo Monev
+**
+** This file is part of the test suite of the Katie Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company 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$
+**
+****************************************************************************/
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QList>
+#include <QtCore/QVector>
+#include <QtTest/QtTest>
+#include <QtDBus>
+
+Q_DECLARE_METATYPE(QVariant)
+Q_DECLARE_METATYPE(QList<int>)
+Q_DECLARE_METATYPE(QVector<int>)
+
+class tst_QDBusLocalCalls: public QObject
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "local.tst_QDBusLocalCalls")
+
+    QDBusConnection conn;
+public:
+    tst_QDBusLocalCalls();
+
+public Q_SLOTS:
+    Q_SCRIPTABLE int echo(int value)
+    { return value; }
+
+    Q_SCRIPTABLE QString echo(const QString &value)
+    { return value; }
+
+    Q_SCRIPTABLE QDBusVariant echo(const QDBusVariant &value)
+    { return value; }
+
+    Q_SCRIPTABLE QVector<int> echo(const QVector<int> &value)
+    { return value; }
+
+    Q_SCRIPTABLE QString echo2(const QStringList &list, QString &out)
+    { out = list[1]; return list[0]; }
+
+    Q_SCRIPTABLE void delayed(QDBusMessage msg)
+    { msg.setDelayedReply(true); }
+
+protected Q_SLOTS:
+    void replyReceived(QDBusPendingCallWatcher *watcher);
+
+private Q_SLOTS:
+    void initTestCase();
+    void makeInvalidCalls();
+    void makeCalls_data();
+    void makeCalls();
+    void makeCallsVariant_data();
+    void makeCallsVariant();
+    void makeCallsTwoRets();
+    void makeCallsComplex();
+    void makeDelayedCalls();
+    void asyncReplySignal();
+
+private:
+    QVariantList asyncReplyArgs;
+    QDBusMessage doCall(const QDBusMessage &call);
+};
+
+tst_QDBusLocalCalls::tst_QDBusLocalCalls()
+    : conn(QDBusConnection::sessionBus())
+{
+}
+
+QDBusMessage tst_QDBusLocalCalls::doCall(const QDBusMessage &call)
+{
+    QFETCH_GLOBAL(bool, useAsync);
+    if (useAsync) {
+        QDBusPendingCall ac = conn.asyncCall(call);
+        ac.waitForFinished();
+        return ac.reply();
+    } else {
+        return conn.call(call);
+    }
+}
+
+void tst_QDBusLocalCalls::replyReceived(QDBusPendingCallWatcher *watcher)
+{
+    asyncReplyArgs = watcher->reply().arguments();
+    QTestEventLoop::instance().exitLoop();
+}
+
+void tst_QDBusLocalCalls::initTestCase()
+{
+    QVERIFY(conn.isConnected());
+    QVERIFY(conn.registerObject("/", this, QDBusConnection::ExportScriptableSlots));
+
+    QTest::addColumn<bool>("useAsync");
+    QTest::newRow("sync") << false;
+    QTest::newRow("async") << true;
+}
+
+void tst_QDBusLocalCalls::makeCalls_data()
+{
+    QTest::addColumn<QVariant>("value");
+    QTest::newRow("int") << QVariant(42);
+    QTest::newRow("string") << QVariant("Hello, world");
+}
+
+void tst_QDBusLocalCalls::makeCallsVariant_data()
+{
+    makeCalls_data();
+}
+
+void tst_QDBusLocalCalls::makeInvalidCalls()
+{
+    {
+        QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                              "/", QString(), "echo");
+        QDBusMessage replyMsg = doCall(callMsg);
+        QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ErrorMessage));
+
+        QDBusError error(replyMsg);
+        QCOMPARE(int(error.type()), int(QDBusError::UnknownMethod));
+    }
+
+    {
+        QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                              "/no_object", QString(), "echo");
+        QDBusMessage replyMsg = doCall(callMsg);
+        QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ErrorMessage));
+
+        QDBusError error(replyMsg);
+        QCOMPARE(int(error.type()), int(QDBusError::UnknownObject));
+    }
+}
+
+void tst_QDBusLocalCalls::makeCalls()
+{
+    QFETCH(QVariant, value);
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "echo");
+    callMsg << value;
+    QDBusMessage replyMsg = doCall(callMsg);
+
+    QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ReplyMessage));
+
+    QVariantList replyArgs = replyMsg.arguments();
+    QCOMPARE(replyArgs.count(), 1);
+    QCOMPARE(replyArgs.at(0), value);
+}
+
+void tst_QDBusLocalCalls::makeCallsVariant()
+{
+    QFETCH(QVariant, value);
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "echo");
+    callMsg << qVariantFromValue(QDBusVariant(value));
+    QDBusMessage replyMsg = doCall(callMsg);
+
+    QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ReplyMessage));
+
+    QVariantList replyArgs = replyMsg.arguments();
+    QCOMPARE(replyArgs.count(), 1);
+
+    const QVariant &reply = replyArgs.at(0);
+    QCOMPARE(reply.userType(), qMetaTypeId<QDBusVariant>());
+    QCOMPARE(qvariant_cast<QDBusVariant>(reply).variant(), value);
+}
+
+void tst_QDBusLocalCalls::makeCallsTwoRets()
+{
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "echo2");
+    callMsg << (QStringList() << "One" << "Two");
+    QDBusMessage replyMsg = doCall(callMsg);
+
+    QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ReplyMessage));
+
+    QVariantList replyArgs = replyMsg.arguments();
+    QCOMPARE(replyArgs.count(), 2);
+    QCOMPARE(replyArgs.at(0).toString(), QString::fromLatin1("One"));
+    QCOMPARE(replyArgs.at(1).toString(), QString::fromLatin1("Two"));
+}
+
+void tst_QDBusLocalCalls::makeCallsComplex()
+{
+    qDBusRegisterMetaType<QList<int> >();
+    qDBusRegisterMetaType<QVector<int> >();
+
+    QList<int> value;
+    value << 1 << -42 << 47;
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "echo");
+    callMsg << qVariantFromValue(value);
+    QDBusMessage replyMsg = doCall(callMsg);
+
+    QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ReplyMessage));
+
+    QVariantList replyArgs = replyMsg.arguments();
+    QCOMPARE(replyArgs.count(), 1);
+    const QVariant &reply = replyArgs.at(0);
+    QCOMPARE(reply.userType(), qMetaTypeId<QDBusArgument>());
+    QCOMPARE(qdbus_cast<QList<int> >(reply), value);
+}
+
+void tst_QDBusLocalCalls::makeDelayedCalls()
+{
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "delayed");
+    QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: cannot call local method 'delayed' at object / (with signature '') on blocking mode");
+    QDBusMessage replyMsg = doCall(callMsg);
+    QCOMPARE(int(replyMsg.type()), int(QDBusMessage::ErrorMessage));
+
+    QDBusError error(replyMsg);
+    QCOMPARE(int(error.type()), int(QDBusError::InternalError));
+}
+
+void tst_QDBusLocalCalls::asyncReplySignal()
+{
+    QFETCH_GLOBAL(bool, useAsync);
+    if (!useAsync)
+        return;                 // this test only works in async mode
+
+    QDBusMessage callMsg = QDBusMessage::createMethodCall(conn.baseService(),
+                                                          "/", QString(), "echo");
+    callMsg << "Hello World";
+    QDBusPendingCall ac = conn.asyncCall(callMsg);
+    if (ac.isFinished())
+        QSKIP("Test ignored: the local-loop async call is already finished", SkipAll);
+
+    QDBusPendingCallWatcher watch(ac);
+    connect(&watch, SIGNAL(finished(QDBusPendingCallWatcher*)),
+            SLOT(replyReceived(QDBusPendingCallWatcher*)));
+
+    QTestEventLoop::instance().enterLoop(2);
+    QVERIFY(!QTestEventLoop::instance().timeout());
+
+    QVERIFY(ac.isFinished());
+    QVERIFY(!ac.isError());
+
+    QVERIFY(!asyncReplyArgs.isEmpty());
+    QCOMPARE(asyncReplyArgs.at(0).toString(), QString("Hello World"));
+}
+
+QTEST_MAIN(tst_QDBusLocalCalls)
+
+#include "moc_tst_qdbuslocalcalls.cpp"