dbus/test/qt/tst_qdbusabstractadaptor.cpp
Thiago Macieira d54ababd5f * test/qt/*: Sync with KDE Subversion revision 523647.
Update the testcases to the new API. Remove testcases for
        classes that are no longer public or have been removed.
2006-03-28 18:58:58 +00:00

983 lines
28 KiB
C++

#include <qcoreapplication.h>
#include <qdebug.h>
#include <QtTest/QtTest>
#include <dbus/qdbus.h>
#include "common.h"
const char *slotSpy;
QString valueSpy;
namespace QTest {
char *toString(QDBusMessage::MessageType t)
{
switch (t)
{
case QDBusMessage::InvalidMessage:
return qstrdup("InvalidMessage");
case QDBusMessage::MethodCallMessage:
return qstrdup("MethodCallMessage");
case QDBusMessage::ReplyMessage:
return qstrdup("ReplyMessage");
case QDBusMessage::ErrorMessage:
return qstrdup("ErrorMessage");
case QDBusMessage::SignalMessage:
return qstrdup("SignalMessage");
default:
return 0;
}
}
}
class tst_QDBusAbstractAdaptor: public QObject
{
Q_OBJECT
private slots:
void methodCalls_data();
void methodCalls();
void signalEmissions_data();
void signalEmissions();
void sameSignalDifferentPaths();
void overloadedSignalEmission_data();
void overloadedSignalEmission();
void readProperties();
void writeProperties();
void typeMatching_data();
void typeMatching();
};
class QDBusSignalSpy: public QObject
{
Q_OBJECT
public slots:
void slot(const QDBusMessage &msg)
{
++count;
interface = msg.interface();
name = msg.name();
signature = msg.signature();
value.clear();
if (msg.count())
value = msg.at(0);
}
public:
QDBusSignalSpy() : count(0) { }
int count;
QString interface;
QString name;
QString signature;
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);
public:
Interface2(QObject *parent) : QDBusAbstractAdaptor(parent)
{ setAutoRelaySignals(true); }
QString prop1() const
{ return __PRETTY_FUNCTION__; }
QString prop2() const
{ return __PRETTY_FUNCTION__; }
void setProp2(const QString &value)
{ slotSpy = __PRETTY_FUNCTION__; valueSpy = value; }
void emitSignal(const QString &, const QVariant &)
{ emit signal(); }
public slots:
void method() { slotSpy = __PRETTY_FUNCTION__; }
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);
public:
Interface3(QObject *parent) : QDBusAbstractAdaptor(parent)
{ setAutoRelaySignals(true); }
QString prop1() const
{ return __PRETTY_FUNCTION__; }
QString prop2() const
{ return __PRETTY_FUNCTION__; }
void setProp2(const QString &value)
{ slotSpy = __PRETTY_FUNCTION__; valueSpy = value; }
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 = __PRETTY_FUNCTION__; }
void methodInt(int) { slotSpy = __PRETTY_FUNCTION__; }
void methodString(QString) { slotSpy = __PRETTY_FUNCTION__; }
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);
public:
Interface4(QObject *parent) : QDBusAbstractAdaptor(parent)
{ setAutoRelaySignals(true); }
QString prop1() const
{ return __PRETTY_FUNCTION__; }
QString prop2() const
{ return __PRETTY_FUNCTION__; }
void setProp2(const QString &value)
{ slotSpy = __PRETTY_FUNCTION__; 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 = __PRETTY_FUNCTION__; }
void method(int) { slotSpy = __PRETTY_FUNCTION__; }
void method(QString) { slotSpy = __PRETTY_FUNCTION__; }
signals:
void signal();
void signal(int);
void signal(const QString &);
};
class MyObject: public QObject
{
Q_OBJECT
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);
}
}
};
class TypesInterface: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "local.TypesInterface")
public:
TypesInterface(QObject *parent)
: QDBusAbstractAdaptor(parent)
{ }
union
{
bool b;
uchar uc;
short s;
ushort us;
int i;
uint ui;
qlonglong ll;
qulonglong ull;
double d;
} dataSpy;
QVariant variantSpy;
QString stringSpy;
QVariantList listSpy;
QStringList stringlistSpy;
QByteArray bytearraySpy;
QVariantMap mapSpy;
public slots:
void methodBool(bool b)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.b = b;
}
void methodUChar(uchar uc)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.uc = uc;
}
void methodShort(short s)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.s = s;
}
void methodUShort(ushort us)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.us = us;
}
void methodInt(int i)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.i = i;
}
void methodUInt(uint ui)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.ui = ui;
}
void methodLongLong(qlonglong ll)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.ll = ll;
}
void methodULongLong(qulonglong ull)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.ull = ull;
}
void methodDouble(double d)
{
slotSpy = __PRETTY_FUNCTION__;
dataSpy.d = d;
}
void methodString(const QString &s)
{
slotSpy = __PRETTY_FUNCTION__;
stringSpy = s;
}
void methodVariant(const QVariant &v)
{
slotSpy = __PRETTY_FUNCTION__;
variantSpy = v;
}
void methodList(const QVariantList &l)
{
slotSpy = __PRETTY_FUNCTION__;
listSpy = l;
}
void methodStringList(const QStringList &sl)
{
slotSpy = __PRETTY_FUNCTION__;
stringlistSpy = sl;
}
void methodByteArray(const QByteArray &ba)
{
slotSpy = __PRETTY_FUNCTION__;
bytearraySpy = ba;
}
void methodMap(const QVariantMap &m)
{
slotSpy = __PRETTY_FUNCTION__;
mapSpy = m;
}
bool retrieveBool()
{
return dataSpy.b;
}
uchar retrieveUChar()
{
return dataSpy.uc;
}
short retrieveShort()
{
return dataSpy.s;
}
ushort retrieveUShort()
{
return dataSpy.us;
}
int retrieveInt()
{
return dataSpy.i;
}
uint retrieveUInt()
{
return dataSpy.ui;
}
qlonglong retrieveLongLong()
{
return dataSpy.ll;
}
qulonglong retrieveULongLong()
{
return dataSpy.ull;
}
double retrieveDouble()
{
return dataSpy.d;
}
QString retrieveString()
{
return stringSpy;
}
QVariant retrieveVariant()
{
return variantSpy;
}
QVariantList retrieveList()
{
return listSpy;
}
QStringList retrieveStringList()
{
return stringlistSpy;
}
QByteArray retrieveByteArray()
{
return bytearraySpy;
}
QVariantMap retrieveMap()
{
return mapSpy;
}
};
void tst_QDBusAbstractAdaptor::methodCalls_data()
{
QTest::addColumn<int>("nInterfaces");
QTest::newRow("0") << 0;
QTest::newRow("1") << 1;
QTest::newRow("2") << 2;
QTest::newRow("3") << 3;
QTest::newRow("4") << 4;
}
void tst_QDBusAbstractAdaptor::methodCalls()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
//QDBusInterface *empty = con.findInterface(con.baseService(), "/", QString());
QDBusInterface *if1 = con.findInterface(con.baseService(), "/", "local.Interface1");
QDBusInterface *if2 = con.findInterface(con.baseService(), "/", "local.Interface2");
QDBusInterface *if3 = con.findInterface(con.baseService(), "/", "local.Interface3");
QDBusInterface *if4 = con.findInterface(con.baseService(), "/", "local.Interface4");
QObject deleter;
if1->setParent(&deleter);
if2->setParent(&deleter);
if3->setParent(&deleter);
if4->setParent(&deleter);
// must fail: no object
//QCOMPARE(empty->call("method").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if1->call("method").type(), QDBusMessage::ErrorMessage);
QFETCH(int, nInterfaces);
MyObject obj(nInterfaces);
con.registerObject("/", &obj);
// must fail: no such method
QCOMPARE(if1->call("method").type(), QDBusMessage::ErrorMessage);
if (!nInterfaces--)
return;
if (!nInterfaces--)
return;
// simple call: one such method exists
QCOMPARE(if2->call("method").type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface2::method()");
if (!nInterfaces--)
return;
// multiple methods in multiple interfaces, no name overlap
QCOMPARE(if1->call("methodVoid").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if1->call("methodInt").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if1->call("methodString").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if2->call("methodVoid").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if2->call("methodInt").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if2->call("methodString").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if3->call("methodVoid").type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface3::methodVoid()");
QCOMPARE(if3->call("methodInt", 42).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface3::methodInt(int)");
QCOMPARE(if3->call("methodString", QString("")).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface3::methodString(QString)");
if (!nInterfaces--)
return;
// method overloading: different interfaces
QCOMPARE(if4->call("method").type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method()");
// method overloading: different parameters
QCOMPARE(if4->call("method.i", 42).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method(int)");
QCOMPARE(if4->call("method.s", QString()).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method(QString)");
}
static void emitSignal(MyObject *obj, const QString &iface, const QString &name,
const QVariant &parameter)
{
if (iface.endsWith('2'))
obj->if2->emitSignal(name, parameter);
else if (iface.endsWith('3'))
obj->if3->emitSignal(name, parameter);
else if (iface.endsWith('4'))
obj->if4->emitSignal(name, parameter);
QTest::qWait(200);
}
void tst_QDBusAbstractAdaptor::signalEmissions_data()
{
QTest::addColumn<QString>("interface");
QTest::addColumn<QString>("name");
QTest::addColumn<QString>("signature");
QTest::addColumn<QVariant>("parameter");
QTest::newRow("Interface2.signal") << "local.Interface2" << "signal" << QString() << QVariant();
QTest::newRow("Interface3.signalVoid") << "local.Interface3" << "signalVoid" << QString() << QVariant();
QTest::newRow("Interface3.signalInt") << "local.Interface3" << "signalInt" << "i" << QVariant(1);
QTest::newRow("Interface3.signalString") << "local.Interface3" << "signalString" << "s" << QVariant("foo");
}
void tst_QDBusAbstractAdaptor::signalEmissions()
{
QFETCH(QString, interface);
QFETCH(QString, name);
QFETCH(QVariant, parameter);
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
MyObject obj(3);
con.registerObject("/", &obj);
//QDBusInterface empty = con.findInterface(con.baseService(), "/", QString());
QDBusInterface *if2 = con.findInterface(con.baseService(), "/", "local.Interface2");
QDBusInterface *if3 = con.findInterface(con.baseService(), "/", "local.Interface3");
QObject deleter;
if2->setParent(&deleter);
if3->setParent(&deleter);
// connect all signals and emit only one
{
QDBusSignalSpy spy;
con.connect(con.baseService(), "/", "local.Interface2", "signal",
&spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/", "local.Interface3", "signalVoid",
&spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/", "local.Interface3", "signalInt",
&spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/", "local.Interface3", "signalString",
&spy, SLOT(slot(QDBusMessage)));
emitSignal(&obj, 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(con.baseService(), "/", interface, name, &spy, SLOT(slot(QDBusMessage)));
emitSignal(&obj, "local.Interface2", "signal", QVariant());
emitSignal(&obj, "local.Interface3", "signalVoid", QVariant());
emitSignal(&obj, "local.Interface3", "signalInt", QVariant(1));
emitSignal(&obj, "local.Interface3", "signalString", 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::sameSignalDifferentPaths()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
MyObject obj(2);
con.registerObject("/p1",&obj);
con.registerObject("/p2",&obj);
QDBusSignalSpy spy;
con.connect(con.baseService(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
obj.if2->emitSignal(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(con.baseService(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
obj.if2->emitSignal(QString(), QVariant());
QTest::qWait(200);
QCOMPARE(spy.count, 2);
}
void tst_QDBusAbstractAdaptor::overloadedSignalEmission_data()
{
QTest::addColumn<QString>("signature");
QTest::addColumn<QVariant>("parameter");
QTest::newRow("void") << QString("") << QVariant();
QTest::newRow("int") << "i" << QVariant(1);
QTest::newRow("string") << "s" << QVariant("foo");
}
void tst_QDBusAbstractAdaptor::overloadedSignalEmission()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
MyObject obj;
con.registerObject("/", &obj);
QString interface = "local.Interface4";
QString name = "signal";
QFETCH(QVariant, parameter);
//QDBusInterface *if4 = con.findInterface(con.baseService(), "/", interface);
// connect all signals and emit only one
{
QDBusSignalSpy spy;
con.connect(con.baseService(), "/", "local.Interface4", "signal", "",
&spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/", "local.Interface4", "signal", "i",
&spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/", "local.Interface4", "signal", "s",
&spy, SLOT(slot(QDBusMessage)));
emitSignal(&obj, 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(con.baseService(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage)));
emitSignal(&obj, "local.Interface4", "signal", QVariant());
emitSignal(&obj, "local.Interface4", "signal", QVariant(1));
emitSignal(&obj, "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::readProperties()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
MyObject obj;
con.registerObject("/", &obj);
for (int i = 2; i <= 4; ++i) {
QString name = QString("Interface%1").arg(i);
QDBusInterface *iface = con.findInterface(con.baseService(), "/", "local." + name);
for (int j = 1; j <= 2; ++j) {
QString propname = QString("prop%1").arg(j);
QVariant value = iface->property(propname.toLatin1());
QCOMPARE(value.userType(), int(QVariant::String));
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
}
iface->deleteLater();
}
}
void tst_QDBusAbstractAdaptor::writeProperties()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
MyObject obj;
con.registerObject("/", &obj);
for (int i = 2; i <= 4; ++i) {
QString name = QString("Interface%1").arg(i);
QDBusInterface *iface = con.findInterface(con.baseService(), "/", "local." + name);
QVariant value(name);
valueSpy.clear();
iface->setProperty("prop1", value);
QVERIFY(valueSpy.isEmpty()); // call mustn't have succeeded
iface->setProperty("prop2", value);
QCOMPARE(valueSpy, name);
QCOMPARE(QString(slotSpy), QString("void %1::setProp2(const QString&)").arg(name));
iface->deleteLater();
}
}
#if 0
void tst_QDBusAbstractAdaptor::adaptorIntrospection_data()
{
methodCalls_data();
}
void tst_QDBusAbstractAdaptor::adaptorIntrospection()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
QObject obj;
con.registerObject("/", &obj);
QFETCH(int, nInterfaces);
switch (nInterfaces)
{
case 4:
new Interface4(&obj);
case 3:
new Interface3(&obj);
case 2:
new Interface2(&obj);
case 1:
new Interface1(&obj);
}
QDBusObject dobj = con.findObject(con.baseService(), "/");
QVERIFY(dobj.isValid());
QString xml = dobj.introspect();
QVERIFY(!xml.isEmpty());
QStringList interfaces = dobj.interfaces();
QCOMPARE(interfaces.count(), nInterfaces + 2);
switch (nInterfaces)
{
case 4: {
QVERIFY(interfaces.contains("local.Interface4"));
QDBusInterface iface(dobj, "local.Interface4");
QCOMPARE(iface.methodData(), Interface4::methodData);
QCOMPARE(iface.signalData(), Interface4::signalData);
QCOMPARE(iface.propertyData(), Interface4::propertyData);
}
case 3: {
QVERIFY(interfaces.contains("local.Interface3"));
QDBusInterface iface(dobj, "local.Interface3");
QCOMPARE(iface.methodData(), Interface3::methodData);
QCOMPARE(iface.signalData(), Interface3::signalData);
QCOMPARE(iface.propertyData(), Interface3::propertyData);
}
case 2: {
QVERIFY(interfaces.contains("local.Interface2"));
QDBusInterface iface(dobj, "local.Interface2");
QCOMPARE(iface.methodData(), Interface2::methodData);
QCOMPARE(iface.signalData(), Interface2::signalData);
QCOMPARE(iface.propertyData(), Interface2::propertyData);
}
case 1: {
QVERIFY(interfaces.contains("local.Interface1"));
QDBusInterface iface(dobj, "local.Interface1");
QCOMPARE(iface.methodData(), Interface1::methodData);
QCOMPARE(iface.signalData(), Interface1::signalData);
QCOMPARE(iface.propertyData(), Interface1::propertyData);
}
}
}
void tst_QDBusAbstractAdaptor::objectTreeIntrospection()
{
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.isEmpty());
}
QObject root;
con.registerObject("/", &root);
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.isEmpty());
}
QObject p1;
con.registerObject("/p1", &p1);
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.contains("p1"));
}
con.unregisterObject("/");
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.contains("p1"));
}
con.registerObject("/p1/q/r", &root);
{
QDBusObject dobj = con.findObject(con.baseService(), "/p1");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.contains("q"));
}
{
QDBusObject dobj = con.findObject(con.baseService(), "/p1/q");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.contains("r"));
}
con.unregisterObject("/p1", QDBusConnection::UnregisterTree);
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.isEmpty());
}
QObject p2;
con.registerObject("/p2", &p2, QDBusConnection::ExportChildObjects);
{
QDBusObject dobj = con.findObject(con.baseService(), "/");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(!tree.childObjects.contains("p1"));
QVERIFY(tree.childObjects.contains("p2"));
}
QObject q;
q.setParent(&p2);
{
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(!tree.childObjects.contains("q"));
}
q.setObjectName("q");
{
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(tree.childObjects.contains("q"));
}
q.setParent(0);
{
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
QString xml = dobj.introspect();
QDBusIntrospection::Object tree =
QDBusIntrospection::parseObject(xml);
QVERIFY(!tree.childObjects.contains("q"));
}
}
#endif
static inline QVariant nest(const QVariant& v)
{
QVariant ret;
qVariantSetValue(ret, v);
return ret;
}
void tst_QDBusAbstractAdaptor::typeMatching_data()
{
QTest::addColumn<QString>("basename");
QTest::addColumn<QString>("signature");
QTest::addColumn<QVariant>("value");
QTest::newRow("bool") << "Bool" << "b" << QVariant(true);
QTest::newRow("byte") << "UChar" << "y" << qVariantFromValue(uchar(42));
QTest::newRow("short") << "Short" << "n" << qVariantFromValue(short(-43));
QTest::newRow("ushort") << "UShort" << "q" << qVariantFromValue(ushort(44));
QTest::newRow("int") << "Int" << "i" << QVariant(42);
QTest::newRow("uint") << "UInt" << "u" << QVariant(42U);
QTest::newRow("qlonglong") << "LongLong" << "x" << QVariant(Q_INT64_C(42));
QTest::newRow("qulonglong") << "ULongLong" << "t" << QVariant(Q_UINT64_C(42));
QTest::newRow("double") << "Double" << "d" << QVariant(2.5);
QTest::newRow("string") << "String" << "s" << QVariant("Hello, World!");
QTest::newRow("variant") << "Variant" << "v" << nest(QVariant("Hello again!"));
QTest::newRow("list") << "List" << "av" << QVariant(QVariantList()
<< nest(42)
<< nest(QString("foo"))
<< nest(QByteArray("bar"))
<< nest(nest(QString("baz"))));
QTest::newRow("stringlist") << "StringList" << "as" << QVariant(QStringList() << "Hello" << "world");
QTest::newRow("bytearray") << "ByteArray" << "ay" << QVariant(QByteArray("foo"));
QVariantMap map;
map["one"] = nest(1); // int
map["The answer to life, the Universe and everything"] = nest(42u); // uint
map["In the beginning..."] = nest(QString("There was nothing")); // string
map["but Unix came and said"] = nest(QByteArray("\"Hello, World\"")); // bytearray
map["two"] = nest(qVariantFromValue(short(2))); // short
QTest::newRow("map") << "Map" << "a{sv}" << QVariant(map);
}
void tst_QDBusAbstractAdaptor::typeMatching()
{
QObject obj;
new TypesInterface(&obj);
QDBusConnection &con = QDBus::sessionBus();
con.registerObject("/types", &obj);
QFETCH(QString, basename);
QFETCH(QString, signature);
QFETCH(QVariant, value);
QDBusMessage reply;
QDBusInterface *iface = con.findInterface(con.baseService(), "/types", "local.TypesInterface");
reply = iface->callWithArgs("method" + basename + '.' + signature, QVariantList() << value);
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
reply = iface->call("retrieve" + basename);
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
QCOMPARE(reply.count(), 1);
const QVariant &retval = reply.at(0);
QCOMPARE(retval.userType(), value.userType());
QVERIFY(compare(retval, value));
iface->deleteLater();
}
QTEST_MAIN(tst_QDBusAbstractAdaptor)
#include "tst_qdbusabstractadaptor.moc"