3cea6b22a6
When a virtual object is registered with the SubPath option it will handle all dbus calls to itself and all child paths. It needs to reimplement handleMessage for that purpose. Introspection needs to be implemented manually in the introspect function. Reviewed-by: Thiago Macieira <thiago.macieira@nokia.com> (cherry picked from commit b07919b3de8cff3e44b7271062372b14bcda5b83) (cherry picked from commit 997c2dfed7a04da2fac577f1c29b89bda4939e2d) (cherry picked from commit c676b7095d826dc2d006f52a4b234546af5e2137) Change-Id: I003007604b286af8000959756ce9d25c17306f5b Reviewed-on: http://codereview.qt.nokia.com/3051 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
1140 lines
38 KiB
C++
1140 lines
38 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|
** All rights reserved.
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
**
|
|
** This file is part of the test suite of the Qt 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.
|
|
**
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
|
** rights. These rights are described in the Nokia Qt 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.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms and
|
|
** conditions contained in a signed written agreement between you and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
/* -*- C++ -*-
|
|
*/
|
|
|
|
#include <qcoreapplication.h>
|
|
#include <qmetatype.h>
|
|
#include <QtTest/QtTest>
|
|
#include <QtCore/qvariant.h>
|
|
#include <QtDBus/QtDBus>
|
|
|
|
#include "../qdbusmarshall/common.h"
|
|
#include "myobject.h"
|
|
|
|
#define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject"
|
|
#define TEST_SIGNAL_NAME "somethingHappened"
|
|
|
|
static const char serviceName[] = "com.trolltech.autotests.qmyserver";
|
|
static const char objectPath[] = "/com/trolltech/qmyserver";
|
|
static const char *interfaceName = serviceName;
|
|
|
|
int MyObject::callCount = 0;
|
|
QVariantList MyObject::callArgs;
|
|
|
|
class MyObjectUnknownType: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject")
|
|
Q_CLASSINFO("D-Bus Introspection", ""
|
|
" <interface name=\"com.trolltech.QtDBus.MyObjectUnknownTypes\" >\n"
|
|
" <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n"
|
|
" <signal name=\"somethingHappened\" >\n"
|
|
" <arg direction=\"out\" type=\"~\" />\n"
|
|
" </signal>\n"
|
|
" <method name=\"ping\" >\n"
|
|
" <arg direction=\"in\" type=\"~\" name=\"ping\" />\n"
|
|
" <arg direction=\"out\" type=\"~\" name=\"ping\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"regularMethod\" />\n"
|
|
" </interface>\n"
|
|
"")
|
|
};
|
|
|
|
class Spy: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
QString received;
|
|
int count;
|
|
|
|
Spy() : count(0)
|
|
{ }
|
|
|
|
public slots:
|
|
void spySlot(const QString& arg)
|
|
{
|
|
received = arg;
|
|
++count;
|
|
}
|
|
};
|
|
|
|
class DerivedFromQDBusInterface: public QDBusInterface
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
DerivedFromQDBusInterface()
|
|
: QDBusInterface("com.example.Test", "/")
|
|
{}
|
|
|
|
public slots:
|
|
void method() {}
|
|
};
|
|
|
|
// helper function
|
|
void emitSignal(const QString &interface, const QString &name, const QString &arg)
|
|
{
|
|
QDBusMessage msg = QDBusMessage::createSignal("/", interface, name);
|
|
msg << arg;
|
|
QDBusConnection::sessionBus().send(msg);
|
|
|
|
QTest::qWait(1000);
|
|
}
|
|
|
|
void emitSignalPeer(const QString &interface, const QString &name, const QString &arg)
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
|
|
req << interface;
|
|
req << name;
|
|
req << arg;
|
|
QDBusConnection::sessionBus().send(req);
|
|
|
|
QTest::qWait(1000);
|
|
}
|
|
|
|
int callCountPeer()
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callCount");
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
return reply.arguments().at(0).toInt();
|
|
}
|
|
|
|
QVariantList callArgsPeer()
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callArgs");
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
return qdbus_cast<QVariantList>(reply.arguments().at(0));
|
|
}
|
|
|
|
void setProp1Peer(int val)
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setProp1");
|
|
req << val;
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
}
|
|
|
|
int prop1Peer()
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "prop1");
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
return reply.arguments().at(0).toInt();
|
|
}
|
|
|
|
void setComplexPropPeer(QList<int> val)
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setComplexProp");
|
|
req << qVariantFromValue(val);
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
}
|
|
|
|
QList<int> complexPropPeer()
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexProp");
|
|
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
|
return qdbus_cast<QList<int> >(reply.arguments().at(0));
|
|
}
|
|
|
|
void resetPeer()
|
|
{
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset");
|
|
QDBusConnection::sessionBus().call(req);
|
|
}
|
|
|
|
class tst_QDBusInterface: public QObject
|
|
{
|
|
Q_OBJECT
|
|
MyObject obj;
|
|
|
|
public slots:
|
|
void testServiceOwnerChanged(const QString &service)
|
|
{
|
|
if (service == "com.example.Test")
|
|
QTestEventLoop::instance().exitLoop();
|
|
}
|
|
|
|
private slots:
|
|
void initTestCase();
|
|
void cleanupTestCase();
|
|
|
|
void notConnected();
|
|
void notValid();
|
|
void notValidDerived();
|
|
void invalidAfterServiceOwnerChanged();
|
|
void introspect();
|
|
void introspectUnknownTypes();
|
|
void introspectVirtualObject();
|
|
void callMethod();
|
|
void invokeMethod();
|
|
void invokeMethodWithReturn();
|
|
void invokeMethodWithMultiReturn();
|
|
void invokeMethodWithComplexReturn();
|
|
|
|
void introspectPeer();
|
|
void callMethodPeer();
|
|
void invokeMethodPeer();
|
|
void invokeMethodWithReturnPeer();
|
|
void invokeMethodWithMultiReturnPeer();
|
|
void invokeMethodWithComplexReturnPeer();
|
|
|
|
void signal();
|
|
void signalPeer();
|
|
|
|
void propertyRead();
|
|
void propertyWrite();
|
|
void complexPropertyRead();
|
|
void complexPropertyWrite();
|
|
|
|
void propertyReadPeer();
|
|
void propertyWritePeer();
|
|
void complexPropertyReadPeer();
|
|
void complexPropertyWritePeer();
|
|
private:
|
|
QProcess proc;
|
|
};
|
|
|
|
class WaitForQMyServer: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
WaitForQMyServer();
|
|
bool ok();
|
|
public Q_SLOTS:
|
|
void ownerChange(const QString &name)
|
|
{
|
|
if (name == serviceName)
|
|
loop.quit();
|
|
}
|
|
|
|
private:
|
|
QEventLoop loop;
|
|
};
|
|
|
|
WaitForQMyServer::WaitForQMyServer()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
if (!ok()) {
|
|
connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
|
|
SLOT(ownerChange(QString)));
|
|
QTimer::singleShot(2000, &loop, SLOT(quit()));
|
|
loop.exec();
|
|
}
|
|
}
|
|
|
|
bool WaitForQMyServer::ok()
|
|
{
|
|
return QDBusConnection::sessionBus().isConnected() &&
|
|
QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
|
|
}
|
|
|
|
void tst_QDBusInterface::initTestCase()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QVERIFY(con.isConnected());
|
|
QTest::qWait(500);
|
|
|
|
con.registerObject("/", &obj, QDBusConnection::ExportAllProperties
|
|
| QDBusConnection::ExportAllSlots
|
|
| QDBusConnection::ExportAllInvokables);
|
|
|
|
// start peer server
|
|
#ifdef Q_OS_WIN
|
|
proc.start("qmyserver");
|
|
#else
|
|
proc.start("./qmyserver/qmyserver");
|
|
#endif
|
|
QVERIFY(proc.waitForStarted());
|
|
|
|
WaitForQMyServer w;
|
|
QVERIFY(w.ok());
|
|
//QTest::qWait(2000);
|
|
|
|
// get peer server address
|
|
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address");
|
|
QDBusMessage rpl = con.call(req);
|
|
QVERIFY(rpl.type() == QDBusMessage::ReplyMessage);
|
|
QString address = rpl.arguments().at(0).toString();
|
|
|
|
// connect to peer server
|
|
QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
|
|
QVERIFY(peercon.isConnected());
|
|
|
|
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
|
|
QDBusMessage rpl2 = con.call(req2);
|
|
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
|
|
QVERIFY(rpl2.arguments().at(0).toBool());
|
|
}
|
|
|
|
void tst_QDBusInterface::cleanupTestCase()
|
|
{
|
|
proc.close();
|
|
proc.kill();
|
|
}
|
|
|
|
void tst_QDBusInterface::notConnected()
|
|
{
|
|
QDBusConnection connection("");
|
|
QVERIFY(!connection.isConnected());
|
|
|
|
QDBusInterface interface("org.freedesktop.DBus", "/", "org.freedesktop.DBus",
|
|
connection);
|
|
|
|
QVERIFY(!interface.isValid());
|
|
QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
|
|
}
|
|
|
|
void tst_QDBusInterface::notValid()
|
|
{
|
|
QDBusConnection connection("");
|
|
QVERIFY(!connection.isConnected());
|
|
|
|
QDBusInterface interface("com.example.Test", QString(), "org.example.Test",
|
|
connection);
|
|
|
|
QVERIFY(!interface.isValid());
|
|
QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
|
|
}
|
|
|
|
void tst_QDBusInterface::notValidDerived()
|
|
{
|
|
DerivedFromQDBusInterface c;
|
|
QVERIFY(!c.isValid());
|
|
QMetaObject::invokeMethod(&c, "method", Qt::DirectConnection);
|
|
}
|
|
|
|
void tst_QDBusInterface::invalidAfterServiceOwnerChanged()
|
|
{
|
|
// this test is technically the same as tst_QDBusAbstractInterface::followSignal
|
|
QDBusConnection conn = QDBusConnection::sessionBus();
|
|
QDBusConnectionInterface *connIface = conn.interface();
|
|
|
|
QDBusInterface validInterface(conn.baseService(), "/");
|
|
QVERIFY(validInterface.isValid());
|
|
QDBusInterface invalidInterface("com.example.Test", "/");
|
|
QVERIFY(!invalidInterface.isValid());
|
|
|
|
QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString)),
|
|
SLOT(exitLoop()));
|
|
QVERIFY(connIface->registerService("com.example.Test") == QDBusConnectionInterface::ServiceRegistered);
|
|
|
|
QTestEventLoop::instance().enterLoop(5);
|
|
|
|
QVERIFY(!QTestEventLoop::instance().timeout());
|
|
QVERIFY(invalidInterface.isValid());
|
|
}
|
|
|
|
void tst_QDBusInterface::introspect()
|
|
{
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
const QMetaObject *mo = iface.metaObject();
|
|
|
|
QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
|
|
QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
|
|
|
|
QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
|
|
QVERIFY(mo->indexOfProperty("prop1") != -1);
|
|
QVERIFY(mo->indexOfProperty("complexProp") != -1);
|
|
}
|
|
|
|
void tst_QDBusInterface::introspectUnknownTypes()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
MyObjectUnknownType obj;
|
|
con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents);
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"),
|
|
"com.trolltech.QtDBus.MyObjectUnknownTypes");
|
|
|
|
const QMetaObject *mo = iface.metaObject();
|
|
QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control
|
|
QVERIFY(mo->indexOfMethod("somethingHappened(QDBusRawType<0x7e>*)") != -1);
|
|
|
|
QVERIFY(mo->indexOfMethod("ping(QDBusRawType<0x7e>*)") != -1);
|
|
int midx = mo->indexOfMethod("ping(QDBusRawType<0x7e>*)");
|
|
QCOMPARE(mo->method(midx).typeName(), "QDBusRawType<0x7e>*");
|
|
|
|
QVERIFY(mo->indexOfProperty("prop1") != -1);
|
|
int pidx = mo->indexOfProperty("prop1");
|
|
QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*");
|
|
|
|
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), "/unknownTypes", "org.freedesktop.DBus.Introspectable", "Introspect");
|
|
QDBusMessage reply = con.call(message, QDBus::Block, 5000);
|
|
qDebug() << "REPL: " << reply.arguments();
|
|
|
|
}
|
|
|
|
|
|
class VirtualObject: public QDBusVirtualObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
VirtualObject() :success(true) {}
|
|
|
|
QString introspect(const QString &path) const {
|
|
if (path == "/some/path/superNode")
|
|
return "zitroneneis";
|
|
if (path == "/some/path/superNode/foo")
|
|
return " <interface name=\"com.trolltech.QtDBus.VirtualObject\">\n"
|
|
" <method name=\"klingeling\" />\n"
|
|
" </interface>\n" ;
|
|
return QString();
|
|
}
|
|
|
|
bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
|
|
++callCount;
|
|
lastMessage = message;
|
|
|
|
if (success) {
|
|
QDBusMessage reply = message.createReply(replyArguments);
|
|
connection.send(reply);
|
|
}
|
|
emit messageReceived(message);
|
|
return success;
|
|
}
|
|
signals:
|
|
void messageReceived(const QDBusMessage &message) const;
|
|
|
|
public:
|
|
mutable QDBusMessage lastMessage;
|
|
QVariantList replyArguments;
|
|
mutable int callCount;
|
|
bool success;
|
|
};
|
|
|
|
void tst_QDBusInterface::introspectVirtualObject()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QVERIFY(con.isConnected());
|
|
VirtualObject obj;
|
|
|
|
obj.success = false;
|
|
|
|
QString path = "/some/path/superNode";
|
|
QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, "org.freedesktop.DBus.Introspectable", "Introspect");
|
|
QDBusMessage reply = con.call(message, QDBus::Block, 5000);
|
|
QVERIFY(reply.arguments().at(0).toString().contains(
|
|
QRegExp("<node>.*zitroneneis.*<interface name=") ));
|
|
|
|
QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect");
|
|
QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000);
|
|
QVERIFY(reply2.arguments().at(0).toString().contains(
|
|
QRegExp("<node>.*<interface name=\"com.trolltech.QtDBus.VirtualObject\">"
|
|
".*<method name=\"klingeling\" />\n"
|
|
".*</interface>.*<interface name=") ));
|
|
}
|
|
|
|
void tst_QDBusInterface::callMethod()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
MyObject::callCount = 0;
|
|
|
|
// call a SLOT method
|
|
QDBusMessage reply = iface.call("ping", qVariantFromValue(QDBusVariant("foo")));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
QVariant v = MyObject::callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// verify reply
|
|
QCOMPARE(reply.arguments().count(), 1);
|
|
v = reply.arguments().at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// call an INVOKABLE method
|
|
reply = iface.call("ping_invokable", qVariantFromValue(QDBusVariant("bar")));
|
|
QCOMPARE(MyObject::callCount, 2);
|
|
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
v = MyObject::callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
|
|
// verify reply
|
|
QCOMPARE(reply.arguments().count(), 1);
|
|
v = reply.arguments().at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethod()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
MyObject::callCount = 0;
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
QVariant v = MyObject::callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
|
|
QCOMPARE(MyObject::callCount, 2);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
v = MyObject::callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithReturn()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
MyObject::callCount = 0;
|
|
QDBusVariant retArg;
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
QVariant v = MyObject::callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg.variant().toString());
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg.variant(), arg.variant());
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
|
|
QCOMPARE(MyObject::callCount, 2);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
v = MyObject::callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg.variant(), arg2.variant());
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithMultiReturn()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
MyObject::callCount = 0;
|
|
QDBusVariant retArg, retArg2;
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo"), arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
|
|
Q_RETURN_ARG(QDBusVariant, retArg),
|
|
Q_ARG(QDBusVariant, arg),
|
|
Q_ARG(QDBusVariant, arg2),
|
|
Q_ARG(QDBusVariant&, retArg2)));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 2);
|
|
QVariant v = MyObject::callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg.variant().toString());
|
|
|
|
v = MyObject::callArgs.at(1);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
|
|
|
|
// verify that we got the replies as expected
|
|
QCOMPARE(retArg.variant(), arg.variant());
|
|
QCOMPARE(retArg2.variant(), arg2.variant());
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg3("hello"), arg4("world");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
|
|
Q_RETURN_ARG(QDBusVariant, retArg),
|
|
Q_ARG(QDBusVariant, arg3),
|
|
Q_ARG(QDBusVariant, arg4),
|
|
Q_ARG(QDBusVariant&, retArg2)));
|
|
QCOMPARE(MyObject::callCount, 2);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 2);
|
|
v = MyObject::callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg3.variant().toString());
|
|
|
|
v = MyObject::callArgs.at(1);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg4.variant().toString());
|
|
|
|
// verify that we got the replies as expected
|
|
QCOMPARE(retArg.variant(), arg3.variant());
|
|
QCOMPARE(retArg2.variant(), arg4.variant());
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithComplexReturn()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
MyObject::callCount = 0;
|
|
QList<int> retArg;
|
|
|
|
// make the SLOT call without a return type
|
|
QList<int> arg = QList<int>() << 42 << -47;
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
QVariant v = MyObject::callArgs.at(0);
|
|
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
|
|
QCOMPARE(qdbus_cast<QList<int> >(v), arg);
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg, arg);
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QList<int> arg2 = QList<int>() << 24 << -74;
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
|
|
QCOMPARE(MyObject::callCount, 2);
|
|
|
|
// verify what the callee received
|
|
QCOMPARE(MyObject::callArgs.count(), 1);
|
|
v = MyObject::callArgs.at(0);
|
|
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
|
|
QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg, arg2);
|
|
}
|
|
|
|
void tst_QDBusInterface::introspectPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
const QMetaObject *mo = iface.metaObject();
|
|
|
|
QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
|
|
QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
|
|
|
|
QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
|
|
QVERIFY(mo->indexOfProperty("prop1") != -1);
|
|
QVERIFY(mo->indexOfProperty("complexProp") != -1);
|
|
}
|
|
|
|
void tst_QDBusInterface::callMethodPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
|
|
// call a SLOT method
|
|
QDBusMessage reply = iface.call("ping", qVariantFromValue(QDBusVariant("foo")));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
|
|
|
// verify what the callee received
|
|
QVariantList callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
QVariant v = callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// verify reply
|
|
QCOMPARE(reply.arguments().count(), 1);
|
|
v = reply.arguments().at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// call an INVOKABLE method
|
|
reply = iface.call("ping_invokable", qVariantFromValue(QDBusVariant("bar")));
|
|
QCOMPARE(callCountPeer(), 2);
|
|
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
|
|
|
// verify what the callee received
|
|
callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
v = callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
|
|
// verify reply
|
|
QCOMPARE(reply.arguments().count(), 1);
|
|
v = reply.arguments().at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
|
|
// verify what the callee received
|
|
QVariantList callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
QVariant v = callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("foo"));
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
|
|
QCOMPARE(callCountPeer(), 2);
|
|
|
|
// verify what the callee received
|
|
callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
v = callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), QString("bar"));
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithReturnPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
QDBusVariant retArg;
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
|
|
// verify what the callee received
|
|
QVariantList callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
QVariant v = callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg.variant().toString());
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg.variant(), arg.variant());
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
|
|
QCOMPARE(callCountPeer(), 2);
|
|
|
|
// verify what the callee received
|
|
callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
v = callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg.variant(), arg2.variant());
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithMultiReturnPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
QDBusVariant retArg, retArg2;
|
|
|
|
// make the SLOT call without a return type
|
|
QDBusVariant arg("foo"), arg2("bar");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
|
|
Q_RETURN_ARG(QDBusVariant, retArg),
|
|
Q_ARG(QDBusVariant, arg),
|
|
Q_ARG(QDBusVariant, arg2),
|
|
Q_ARG(QDBusVariant&, retArg2)));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
|
|
// verify what the callee received
|
|
QVariantList callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 2);
|
|
QVariant v = callArgs.at(0);
|
|
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg.variant().toString());
|
|
|
|
v = callArgs.at(1);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
|
|
|
|
// verify that we got the replies as expected
|
|
QCOMPARE(retArg.variant(), arg.variant());
|
|
QCOMPARE(retArg2.variant(), arg2.variant());
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QDBusVariant arg3("hello"), arg4("world");
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
|
|
Q_RETURN_ARG(QDBusVariant, retArg),
|
|
Q_ARG(QDBusVariant, arg3),
|
|
Q_ARG(QDBusVariant, arg4),
|
|
Q_ARG(QDBusVariant&, retArg2)));
|
|
QCOMPARE(callCountPeer(), 2);
|
|
|
|
// verify what the callee received
|
|
callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 2);
|
|
v = callArgs.at(0);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg3.variant().toString());
|
|
|
|
v = callArgs.at(1);
|
|
dv = qdbus_cast<QDBusVariant>(v);
|
|
QCOMPARE(dv.variant().type(), QVariant::String);
|
|
QCOMPARE(dv.variant().toString(), arg4.variant().toString());
|
|
|
|
// verify that we got the replies as expected
|
|
QCOMPARE(retArg.variant(), arg3.variant());
|
|
QCOMPARE(retArg2.variant(), arg4.variant());
|
|
}
|
|
|
|
void tst_QDBusInterface::invokeMethodWithComplexReturnPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
QList<int> retArg;
|
|
|
|
// make the SLOT call without a return type
|
|
QList<int> arg = QList<int>() << 42 << -47;
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
|
|
// verify what the callee received
|
|
QVariantList callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
QVariant v = callArgs.at(0);
|
|
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
|
|
QCOMPARE(qdbus_cast<QList<int> >(v), arg);
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg, arg);
|
|
|
|
// make the INVOKABLE call without a return type
|
|
QList<int> arg2 = QList<int>() << 24 << -74;
|
|
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
|
|
QCOMPARE(callCountPeer(), 2);
|
|
|
|
// verify what the callee received
|
|
callArgs = callArgsPeer();
|
|
QCOMPARE(callArgs.count(), 1);
|
|
v = callArgs.at(0);
|
|
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
|
|
QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
|
|
|
|
// verify that we got the reply as expected
|
|
QCOMPARE(retArg, arg2);
|
|
}
|
|
|
|
void tst_QDBusInterface::signal()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
QString arg = "So long and thanks for all the fish";
|
|
{
|
|
Spy spy;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 1);
|
|
QCOMPARE(spy.received, arg);
|
|
}
|
|
|
|
QDBusInterface iface2(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
{
|
|
Spy spy;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 2);
|
|
QCOMPARE(spy.received, arg);
|
|
}
|
|
|
|
{
|
|
Spy spy, spy2;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 1);
|
|
QCOMPARE(spy.received, arg);
|
|
QCOMPARE(spy2.count, 1);
|
|
QCOMPARE(spy2.received, arg);
|
|
}
|
|
}
|
|
|
|
void tst_QDBusInterface::signalPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
QString arg = "So long and thanks for all the fish";
|
|
{
|
|
Spy spy;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 1);
|
|
QCOMPARE(spy.received, arg);
|
|
}
|
|
|
|
QDBusInterface iface2(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
{
|
|
Spy spy;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 2);
|
|
QCOMPARE(spy.received, arg);
|
|
}
|
|
|
|
{
|
|
Spy spy, spy2;
|
|
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
|
|
|
|
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
|
|
QCOMPARE(spy.count, 1);
|
|
QCOMPARE(spy.received, arg);
|
|
QCOMPARE(spy2.count, 1);
|
|
QCOMPARE(spy2.received, arg);
|
|
}
|
|
}
|
|
|
|
void tst_QDBusInterface::propertyRead()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
int arg = obj.m_prop1 = 42;
|
|
MyObject::callCount = 0;
|
|
|
|
QVariant v = iface.property("prop1");
|
|
QVERIFY(v.isValid());
|
|
QCOMPARE(v.userType(), int(QVariant::Int));
|
|
QCOMPARE(v.toInt(), arg);
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
}
|
|
|
|
void tst_QDBusInterface::propertyWrite()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
int arg = 42;
|
|
obj.m_prop1 = 0;
|
|
MyObject::callCount = 0;
|
|
|
|
QVERIFY(iface.setProperty("prop1", arg));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
QCOMPARE(obj.m_prop1, arg);
|
|
}
|
|
|
|
void tst_QDBusInterface::complexPropertyRead()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
QList<int> arg = obj.m_complexProp = QList<int>() << 42 << -47;
|
|
MyObject::callCount = 0;
|
|
|
|
QVariant v = iface.property("complexProp");
|
|
QVERIFY(v.isValid());
|
|
QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
|
|
QCOMPARE(v.value<QList<int> >(), arg);
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
}
|
|
|
|
void tst_QDBusInterface::complexPropertyWrite()
|
|
{
|
|
QDBusConnection con = QDBusConnection::sessionBus();
|
|
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME);
|
|
|
|
QList<int> arg = QList<int>() << -47 << 42;
|
|
obj.m_complexProp.clear();
|
|
MyObject::callCount = 0;
|
|
|
|
QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg)));
|
|
QCOMPARE(MyObject::callCount, 1);
|
|
QCOMPARE(obj.m_complexProp, arg);
|
|
}
|
|
|
|
void tst_QDBusInterface::propertyReadPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
int arg = 42;
|
|
setProp1Peer(42);
|
|
|
|
QVariant v = iface.property("prop1");
|
|
QVERIFY(v.isValid());
|
|
QCOMPARE(v.userType(), int(QVariant::Int));
|
|
QCOMPARE(v.toInt(), arg);
|
|
QCOMPARE(callCountPeer(), 1);
|
|
}
|
|
|
|
void tst_QDBusInterface::propertyWritePeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
int arg = 42;
|
|
setProp1Peer(0);
|
|
|
|
QVERIFY(iface.setProperty("prop1", arg));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
QCOMPARE(prop1Peer(), arg);
|
|
}
|
|
|
|
void tst_QDBusInterface::complexPropertyReadPeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
QList<int> arg = QList<int>() << 42 << -47;
|
|
setComplexPropPeer(arg);
|
|
|
|
QVariant v = iface.property("complexProp");
|
|
QVERIFY(v.isValid());
|
|
QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
|
|
QCOMPARE(v.value<QList<int> >(), arg);
|
|
QCOMPARE(callCountPeer(), 1);
|
|
}
|
|
|
|
void tst_QDBusInterface::complexPropertyWritePeer()
|
|
{
|
|
QDBusConnection con("peer");
|
|
QDBusInterface iface(QString(), QLatin1String("/"),
|
|
TEST_INTERFACE_NAME, con);
|
|
|
|
resetPeer();
|
|
QList<int> arg = QList<int>() << -47 << 42;
|
|
|
|
QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg)));
|
|
QCOMPARE(callCountPeer(), 1);
|
|
QCOMPARE(complexPropPeer(), arg);
|
|
}
|
|
|
|
QTEST_MAIN(tst_QDBusInterface)
|
|
|
|
#include "tst_qdbusinterface.moc"
|