summaryrefslogtreecommitdiffstats
path: root/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp')
-rw-r--r--tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp985
1 files changed, 718 insertions, 267 deletions
diff --git a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
index a64b3d2..9250350 100644
--- a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
+++ b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
@@ -46,6 +46,11 @@
#include <QtDBus>
#include "../qdbusmarshall/common.h"
+#include "myobject.h"
+
+static const char serviceName[] = "com.trolltech.autotests.qmyserver";
+static const char objectPath[] = "/com/trolltech/qmyserver";
+static const char *interfaceName = serviceName;
const char *slotSpy;
QString valueSpy;
@@ -73,273 +78,6 @@ namespace QTest {
}
QT_END_NAMESPACE
-class tst_QDBusAbstractAdaptor: public QObject
-{
- Q_OBJECT
-
-private slots:
- void initTestCase() { commonInit(); }
- void methodCalls_data();
- void methodCalls();
- void methodCallScriptable();
- void signalEmissions_data();
- void signalEmissions();
- void sameSignalDifferentPaths();
- void sameObjectDifferentPaths();
- void scriptableSignalOrNot();
- void overloadedSignalEmission_data();
- void overloadedSignalEmission();
- void readProperties();
- void readPropertiesInvalidInterface();
- void readPropertiesEmptyInterface_data();
- void readPropertiesEmptyInterface();
- void readAllProperties();
- void readAllPropertiesInvalidInterface();
- void readAllPropertiesEmptyInterface_data();
- void readAllPropertiesEmptyInterface();
- void writeProperties();
-
- void typeMatching_data();
- void typeMatching();
-
- void methodWithMoreThanOneReturnValue();
-};
-
-class QDBusSignalSpy: public QObject
-{
- Q_OBJECT
-
-public slots:
- void slot(const QDBusMessage &msg)
- {
- ++count;
- interface = msg.interface();
- name = msg.member();
- signature = msg.signature();
- path = msg.path();
- value.clear();
- if (msg.arguments().count())
- value = msg.arguments().at(0);
- }
-
-public:
- QDBusSignalSpy() : count(0) { }
-
- int count;
- QString interface;
- QString name;
- QString signature;
- QString path;
- QVariant value;
-};
-
-class Interface1: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.Interface1")
-public:
- Interface1(QObject *parent) : QDBusAbstractAdaptor(parent)
- { }
-};
-
-class Interface2: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.Interface2")
- Q_PROPERTY(QString prop1 READ prop1)
- Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2 SCRIPTABLE true)
- Q_PROPERTY(QUrl nonDBusProperty READ nonDBusProperty)
-public:
- Interface2(QObject *parent) : QDBusAbstractAdaptor(parent)
- { setAutoRelaySignals(true); }
-
- QString prop1() const
- { return QLatin1String("QString Interface2::prop1() const"); }
-
- QString prop2() const
- { return QLatin1String("QString Interface2::prop2() const"); }
-
- void setProp2(const QString &value)
- {
- slotSpy = "void Interface2::setProp2(const QString &)";
- valueSpy = value;
- }
-
- QUrl nonDBusProperty() const
- { return QUrl(); }
-
- void emitSignal(const QString &, const QVariant &)
- { emit signal(); }
-
-public slots:
- void method()
- {
- slotSpy = "void Interface2::method()";
- }
-
- Q_SCRIPTABLE void scriptableMethod()
- {
- slotSpy = "void Interface2::scriptableMethod()";
- }
-
-signals:
- void signal();
-};
-
-class Interface3: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.Interface3")
- Q_PROPERTY(QString prop1 READ prop1)
- Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2)
- Q_PROPERTY(QString interface3prop READ interface3prop)
-public:
- Interface3(QObject *parent) : QDBusAbstractAdaptor(parent)
- { setAutoRelaySignals(true); }
-
- QString prop1() const
- { return QLatin1String("QString Interface3::prop1() const"); }
-
- QString prop2() const
- { return QLatin1String("QString Interface3::prop2() const"); }
-
- void setProp2(const QString &value)
- {
- slotSpy = "void Interface3::setProp2(const QString &)";
- valueSpy = value;
- }
-
- QString interface3prop() const
- { return QLatin1String("QString Interface3::interface3prop() const"); }
-
- void emitSignal(const QString &name, const QVariant &value)
- {
- if (name == "signalVoid")
- emit signalVoid();
- else if (name == "signalInt")
- emit signalInt(value.toInt());
- else if (name == "signalString")
- emit signalString(value.toString());
- }
-
-public slots:
- void methodVoid() { slotSpy = "void Interface3::methodVoid()"; }
- void methodInt(int) { slotSpy = "void Interface3::methodInt(int)"; }
- void methodString(QString) { slotSpy = "void Interface3::methodString(QString)"; }
-
- int methodStringString(const QString &s, QString &out)
- {
- slotSpy = "int Interface3::methodStringString(const QString &, QString &)";
- out = s;
- return 42;
- }
-
-signals:
- void signalVoid();
- void signalInt(int);
- void signalString(const QString &);
-};
-
-class Interface4: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.Interface4")
- Q_PROPERTY(QString prop1 READ prop1)
- Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2)
- Q_PROPERTY(QString interface4prop READ interface4prop)
-public:
- Interface4(QObject *parent) : QDBusAbstractAdaptor(parent)
- { setAutoRelaySignals(true); }
-
- QString prop1() const
- { return QLatin1String("QString Interface4::prop1() const"); }
-
- QString prop2() const
- { return QLatin1String("QString Interface4::prop2() const"); }
-
- QString interface4prop() const
- { return QLatin1String("QString Interface4::interface4prop() const"); }
-
- void setProp2(const QString &value)
- {
- slotSpy = "void Interface4::setProp2(const QString &)";
- valueSpy = value;
- }
-
- void emitSignal(const QString &, const QVariant &value)
- {
- switch (value.type())
- {
- case QVariant::Invalid:
- emit signal();
- break;
- case QVariant::Int:
- emit signal(value.toInt());
- break;
- case QVariant::String:
- emit signal(value.toString());
- break;
- default:
- break;
- }
- }
-
-public slots:
- void method() { slotSpy = "void Interface4::method()"; }
- void method(int) { slotSpy = "void Interface4::method(int)"; }
- void method(QString) { slotSpy = "void Interface4::method(QString)"; }
-
-signals:
- void signal();
- void signal(int);
- void signal(const QString &);
-};
-
-class MyObject: public QObject
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.MyObject")
-public:
- Interface1 *if1;
- Interface2 *if2;
- Interface3 *if3;
- Interface4 *if4;
-
- MyObject(int n = 4)
- : if1(0), if2(0), if3(0), if4(0)
- {
- switch (n)
- {
- case 4:
- if4 = new Interface4(this);
- case 3:
- if3 = new Interface3(this);
- case 2:
- if2 = new Interface2(this);
- case 1:
- if1 = new Interface1(this);
- }
- }
-
- void emitSignal(const QString &name, const QVariant &value)
- {
- if (name == "scriptableSignalVoid")
- emit scriptableSignalVoid();
- else if (name == "scriptableSignalInt")
- emit scriptableSignalInt(value.toInt());
- else if (name == "scriptableSignalString")
- emit scriptableSignalString(value.toString());
- else if (name == "nonScriptableSignalVoid")
- emit nonScriptableSignalVoid();
- }
-
-signals:
- Q_SCRIPTABLE void scriptableSignalVoid();
- Q_SCRIPTABLE void scriptableSignalInt(int);
- Q_SCRIPTABLE void scriptableSignalString(QString);
- void nonScriptableSignalVoid();
-};
-
class TypesInterface: public QDBusAbstractAdaptor
{
Q_OBJECT
@@ -593,6 +331,191 @@ public slots:
}
};
+void newMyObjectPeer(int nInterfaces = 4)
+{
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "newMyObject");
+ req << nInterfaces;
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+}
+
+void registerMyObjectPeer(const QString & path, QDBusConnection::RegisterOptions options = QDBusConnection::ExportAdaptors)
+{
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "registerMyObject");
+ req << path;
+ req << (int)options;
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+}
+
+void emitSignalPeer(const QString &interface, const QString &name, const QVariant &parameter)
+{
+ if (parameter.isValid())
+ {
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
+ req << interface;
+ req << name;
+ req << QVariant::fromValue(QDBusVariant(parameter));
+ QDBusConnection::sessionBus().send(req);
+ }
+ else
+ {
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal2");
+ req << interface;
+ req << name;
+ QDBusConnection::sessionBus().send(req);
+ }
+
+ QTest::qWait(1000);
+}
+
+const char* slotSpyPeer()
+{
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "slotSpyServer");
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+ return reply.arguments().at(0).toString().toLatin1().data();
+}
+
+QString valueSpyPeer()
+{
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "valueSpyServer");
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+ return reply.arguments().at(0).toString();
+}
+
+void clearValueSpyPeer()
+{
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "clearValueSpy");
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+}
+
+class tst_QDBusAbstractAdaptor: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void methodCalls_data();
+ void methodCalls();
+ void methodCallScriptable();
+ void signalEmissions_data();
+ void signalEmissions();
+ void sameSignalDifferentPaths();
+ void sameObjectDifferentPaths();
+ void scriptableSignalOrNot();
+ void overloadedSignalEmission_data();
+ void overloadedSignalEmission();
+ void readProperties();
+ void readPropertiesInvalidInterface();
+ void readPropertiesEmptyInterface_data();
+ void readPropertiesEmptyInterface();
+ void readAllProperties();
+ void readAllPropertiesInvalidInterface();
+ void readAllPropertiesEmptyInterface_data();
+ void readAllPropertiesEmptyInterface();
+ void writeProperties();
+
+ void methodCallsPeer_data();
+ void methodCallsPeer();
+ void methodCallScriptablePeer();
+ void signalEmissionsPeer_data();
+ void signalEmissionsPeer();
+ void sameSignalDifferentPathsPeer();
+ void sameObjectDifferentPathsPeer();
+ void scriptableSignalOrNotPeer();
+ void overloadedSignalEmissionPeer_data();
+ void overloadedSignalEmissionPeer();
+ void readPropertiesPeer();
+ void readPropertiesInvalidInterfacePeer();
+ void readPropertiesEmptyInterfacePeer_data();
+ void readPropertiesEmptyInterfacePeer();
+ void readAllPropertiesPeer();
+ void readAllPropertiesInvalidInterfacePeer();
+ void readAllPropertiesEmptyInterfacePeer_data();
+ void readAllPropertiesEmptyInterfacePeer();
+ void writePropertiesPeer();
+
+ void typeMatching_data();
+ void typeMatching();
+
+ void methodWithMoreThanOneReturnValue();
+ void methodWithMoreThanOneReturnValuePeer();
+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_QDBusAbstractAdaptor::initTestCase()
+{
+ commonInit();
+
+ // 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 = QDBusConnection::sessionBus().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 = QDBusConnection::sessionBus().call(req2);
+ QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
+ QVERIFY(rpl2.arguments().at(0).toBool());
+}
+
+void tst_QDBusAbstractAdaptor::cleanupTestCase()
+{
+ proc.close();
+ proc.kill();
+}
+
void tst_QDBusAbstractAdaptor::methodCalls_data()
{
QTest::addColumn<int>("nInterfaces");
@@ -1151,6 +1074,512 @@ void tst_QDBusAbstractAdaptor::writeProperties()
}
}
+void tst_QDBusAbstractAdaptor::methodCallsPeer_data()
+{
+ methodCalls_data();
+}
+
+void tst_QDBusAbstractAdaptor::methodCallsPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ {
+ // must fail: no object
+ QDBusInterface if1(QString(), "/", "local.Interface1", con);
+ QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
+ }
+
+ QFETCH(int, nInterfaces);
+ newMyObjectPeer(nInterfaces);
+ registerMyObjectPeer("/");
+
+ QDBusInterface if1(QString(), "/", "local.Interface1", con);
+ QDBusInterface if2(QString(), "/", "local.Interface2", con);
+ QDBusInterface if3(QString(), "/", "local.Interface3", con);
+ QDBusInterface if4(QString(), "/", "local.Interface4", con);
+
+ // must fail: no such method
+ QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
+ if (!nInterfaces--)
+ return;
+ if (!nInterfaces--)
+ return;
+
+ // simple call: one such method exists
+ QCOMPARE(if2.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface2::method()");
+ if (!nInterfaces--)
+ return;
+
+ // multiple methods in multiple interfaces, no name overlap
+ QCOMPARE(if1.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if1.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if1.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
+
+ QCOMPARE(if3.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface3::methodVoid()");
+ QCOMPARE(if3.call(QDBus::BlockWithGui, "methodInt", 42).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface3::methodInt(int)");
+ QCOMPARE(if3.call(QDBus::BlockWithGui, "methodString", QString("")).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface3::methodString(QString)");
+
+ if (!nInterfaces--)
+ return;
+
+ // method overloading: different interfaces
+ QCOMPARE(if4.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface4::method()");
+
+ // method overloading: different parameters
+ QCOMPARE(if4.call(QDBus::BlockWithGui, "method.i", 42).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface4::method(int)");
+ QCOMPARE(if4.call(QDBus::BlockWithGui, "method.s", QString()).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface4::method(QString)");
+}
+
+void tst_QDBusAbstractAdaptor::methodCallScriptablePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer(2);
+ registerMyObjectPeer("/");
+
+ QDBusInterface if2(QString(), "/", "local.Interface2", con);
+
+ QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(slotSpyPeer(), "void Interface2::scriptableMethod()");
+}
+
+void tst_QDBusAbstractAdaptor::signalEmissionsPeer_data()
+{
+ signalEmissions_data();
+}
+
+void tst_QDBusAbstractAdaptor::signalEmissionsPeer()
+{
+ QFETCH(QString, interface);
+ QFETCH(QString, name);
+ QFETCH(QVariant, parameter);
+
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer(3);
+ registerMyObjectPeer("/", QDBusConnection::ExportAdaptors
+ | QDBusConnection::ExportScriptableSignals);
+
+ // connect all signals and emit only one
+ {
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/", "local.Interface2", "signal",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.Interface3", "signalVoid",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.Interface3", "signalInt",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.Interface3", "signalString",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.MyObject", "scriptableSignalVoid",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.MyObject", "scriptableSignalInt",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.MyObject", "scriptableSignalString",
+ &spy, SLOT(slot(QDBusMessage)));
+
+ emitSignalPeer(interface, name, parameter);
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, interface);
+ QCOMPARE(spy.name, name);
+ QTEST(spy.signature, "signature");
+ QCOMPARE(spy.value, parameter);
+ }
+
+ // connect one signal and emit them all
+ {
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/", interface, name, &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.Interface2", "signal", QVariant());
+ emitSignalPeer("local.Interface3", "signalVoid", QVariant());
+ emitSignalPeer("local.Interface3", "signalInt", QVariant(1));
+ emitSignalPeer("local.Interface3", "signalString", QVariant("foo"));
+ emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant());
+ emitSignalPeer("local.MyObject", "scriptableSignalInt", QVariant(1));
+ emitSignalPeer("local.MyObject", "scriptableSignalString", QVariant("foo"));
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, interface);
+ QCOMPARE(spy.name, name);
+ QTEST(spy.signature, "signature");
+ QCOMPARE(spy.value, parameter);
+ }
+}
+
+void tst_QDBusAbstractAdaptor::sameSignalDifferentPathsPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer(2);
+
+ registerMyObjectPeer("/p1");
+ registerMyObjectPeer("/p2");
+
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.Interface2", QString(), QVariant());
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, QString("local.Interface2"));
+ QCOMPARE(spy.name, QString("signal"));
+ QVERIFY(spy.signature.isEmpty());
+
+ // now connect the other one
+ spy.count = 0;
+ con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.Interface2", QString(), QVariant());
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 2);
+}
+
+void tst_QDBusAbstractAdaptor::sameObjectDifferentPathsPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer(2);
+
+ registerMyObjectPeer("/p1");
+ registerMyObjectPeer("/p2", 0); // don't export anything
+
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.Interface2", QString(), QVariant());
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, QString("local.Interface2"));
+ QCOMPARE(spy.name, QString("signal"));
+ QVERIFY(spy.signature.isEmpty());
+}
+
+void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
+{
+ QDBusConnection con("peer");;
+ QVERIFY(con.isConnected());
+
+ {
+ newMyObjectPeer(0);
+
+ registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
+ registerMyObjectPeer("/p2", 0); // don't export anything
+
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/p1", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p2", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant());
+ emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 1); // only /p1 must have emitted
+ QCOMPARE(spy.interface, QString("local.MyObject"));
+ QCOMPARE(spy.name, QString("scriptableSignalVoid"));
+ QCOMPARE(spy.path, QString("/p1"));
+ QVERIFY(spy.signature.isEmpty());
+ }
+
+ {
+ newMyObjectPeer(0);
+
+ registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
+ registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals
+ | QDBusConnection::ExportNonScriptableSignals);
+
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 1); // only /p2 must have emitted now
+ QCOMPARE(spy.interface, QString("local.MyObject"));
+ QCOMPARE(spy.name, QString("nonScriptableSignalVoid"));
+ QCOMPARE(spy.path, QString("/p2"));
+ QVERIFY(spy.signature.isEmpty());
+ }
+
+ {
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/p1", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/p2", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
+
+ {
+ newMyObjectPeer(0);
+
+ registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
+ registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals
+ | QDBusConnection::ExportNonScriptableSignals);
+ } // <--- QObject emits the destroyed(QObject*) signal at this point
+
+ QTest::qWait(200);
+
+ QCOMPARE(spy.count, 0);
+ }
+}
+
+void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer_data()
+{
+ overloadedSignalEmission_data();
+}
+
+void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QString interface = "local.Interface4";
+ QString name = "signal";
+ QFETCH(QVariant, parameter);
+ //QDBusInterface *if4 = new QDBusInterface(QString(), "/", interface, con);
+
+ // connect all signals and emit only one
+ {
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/", "local.Interface4", "signal", "",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.Interface4", "signal", "i",
+ &spy, SLOT(slot(QDBusMessage)));
+ con.connect(QString(), "/", "local.Interface4", "signal", "s",
+ &spy, SLOT(slot(QDBusMessage)));
+
+ emitSignalPeer(interface, name, parameter);
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, interface);
+ QCOMPARE(spy.name, name);
+ QTEST(spy.signature, "signature");
+ QCOMPARE(spy.value, parameter);
+ }
+
+ QFETCH(QString, signature);
+ // connect one signal and emit them all
+ {
+ QDBusSignalSpy spy;
+ con.connect(QString(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage)));
+ emitSignalPeer("local.Interface4", "signal", QVariant());
+ emitSignalPeer("local.Interface4", "signal", QVariant(1));
+ emitSignalPeer("local.Interface4", "signal", QVariant("foo"));
+
+ QCOMPARE(spy.count, 1);
+ QCOMPARE(spy.interface, interface);
+ QCOMPARE(spy.name, name);
+ QTEST(spy.signature, "signature");
+ QCOMPARE(spy.value, parameter);
+ }
+}
+
+void tst_QDBusAbstractAdaptor::readPropertiesPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+ for (int i = 2; i <= 4; ++i) {
+ QString name = QString("Interface%1").arg(i);
+
+ for (int j = 1; j <= 2; ++j) {
+ QString propname = QString("prop%1").arg(j);
+ QDBusReply<QVariant> reply =
+ properties.call(QDBus::BlockWithGui, "Get", "local." + name, propname);
+ QVariant value = reply;
+
+ QCOMPARE(value.userType(), int(QVariant::String));
+ QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
+ }
+ }
+}
+
+void tst_QDBusAbstractAdaptor::readPropertiesInvalidInterfacePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+
+ // test an invalid interface:
+ QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "local.DoesntExist", "prop1");
+ QVERIFY(!reply.isValid());
+}
+
+void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer_data()
+{
+ readPropertiesEmptyInterface_data();
+}
+
+void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+
+ QFETCH(QVariantMap, expectedProperties);
+ QFETCH(bool, existing);
+
+ QVariantMap::ConstIterator it = expectedProperties.constBegin();
+ for ( ; it != expectedProperties.constEnd(); ++it) {
+ QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "", it.key());
+
+ if (existing) {
+ QVERIFY2(reply.isValid(), qPrintable(it.key()));
+ } else {
+ QVERIFY2(!reply.isValid(), qPrintable(it.key()));
+ continue;
+ }
+
+ QCOMPARE(int(reply.value().type()), int(QVariant::String));
+ if (it.value().isValid())
+ QCOMPARE(reply.value().toString(), it.value().toString());
+ }
+}
+
+void tst_QDBusAbstractAdaptor::readAllPropertiesPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+ for (int i = 2; i <= 4; ++i) {
+ QString name = QString("Interface%1").arg(i);
+ QDBusReply<QVariantMap> reply =
+ properties.call(QDBus::BlockWithGui, "GetAll", "local." + name);
+
+ for (int j = 1; j <= 2; ++j) {
+ QString propname = QString("prop%1").arg(j);
+ QVERIFY2(reply.value().contains(propname),
+ qPrintable(propname + " on " + name));
+ QVariant value = reply.value().value(propname);
+
+ QCOMPARE(value.userType(), int(QVariant::String));
+ QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
+ }
+ }
+}
+
+void tst_QDBusAbstractAdaptor::readAllPropertiesInvalidInterfacePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+
+ // test an invalid interface:
+ QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "local.DoesntExist");
+ QVERIFY(!reply.isValid());
+}
+
+void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer_data()
+{
+ readAllPropertiesEmptyInterface_data();
+}
+
+void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+
+ QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "");
+ QVERIFY(reply.isValid());
+
+ QVariantMap allprops = reply;
+
+ QFETCH(QVariantMap, expectedProperties);
+ QFETCH(bool, existing);
+
+ QVariantMap::ConstIterator it = expectedProperties.constBegin();
+ if (existing) {
+ for ( ; it != expectedProperties.constEnd(); ++it) {
+ QVERIFY2(allprops.contains(it.key()), qPrintable(it.key()));
+
+ QVariant propvalue = allprops.value(it.key());
+ QVERIFY2(!propvalue.isNull(), qPrintable(it.key()));
+ QVERIFY2(propvalue.isValid(), qPrintable(it.key()));
+
+ QString stringvalue = propvalue.toString();
+ QVERIFY2(!stringvalue.isEmpty(), qPrintable(it.key()));
+
+ if (it.value().isValid())
+ QCOMPARE(stringvalue, it.value().toString());
+
+ // remove this property from the map
+ allprops.remove(it.key());
+ }
+
+ QVERIFY2(allprops.isEmpty(),
+ qPrintable(QStringList(allprops.keys()).join(" ")));
+ } else {
+ for ( ; it != expectedProperties.constEnd(); ++it)
+ QVERIFY2(!allprops.contains(it.key()), qPrintable(it.key()));
+ }
+}
+
+void tst_QDBusAbstractAdaptor::writePropertiesPeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
+ for (int i = 2; i <= 4; ++i) {
+ QString name = QString("Interface%1").arg(i);
+
+ clearValueSpyPeer();
+ properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop1"),
+ qVariantFromValue(QDBusVariant(name)));
+ QVERIFY(valueSpyPeer().isEmpty()); // call mustn't have succeeded
+
+ properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop2"),
+ qVariantFromValue(QDBusVariant(name)));
+ QCOMPARE(valueSpyPeer(), name);
+ QCOMPARE(QString(slotSpyPeer()), QString("void %1::setProp2(const QString &)").arg(name));
+ }
+}
+
#if 0
void tst_QDBusAbstractAdaptor::adaptorIntrospection_data()
{
@@ -1438,6 +1867,28 @@ void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValue()
QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString);
}
+void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValuePeer()
+{
+ QDBusConnection con("peer");
+ QVERIFY(con.isConnected());
+
+ newMyObjectPeer();
+ registerMyObjectPeer("/");
+
+ QString testString = "This is a test string.";
+
+ QDBusInterface remote(QString(), "/", "local.Interface3", con);
+ QDBusMessage reply = remote.call(QDBus::BlockWithGui, "methodStringString", testString);
+ QVERIFY(reply.arguments().count() == 2);
+
+ QDBusReply<int> intreply = reply;
+ QVERIFY(intreply.isValid());
+ QCOMPARE(intreply.value(), 42);
+
+ QCOMPARE(reply.arguments().at(1).userType(), int(QVariant::String));
+ QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString);
+}
+
QTEST_MAIN(tst_QDBusAbstractAdaptor)
#include "tst_qdbusabstractadaptor.moc"