summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorThiago Macieira <thiago@kde.org>2006-06-11 12:18:23 +0000
committerThiago Macieira <thiago@kde.org>2006-06-11 12:18:23 +0000
commitfd5ac15ebc643635e436b64cf1e656284380b1a5 (patch)
treef1630dd4f97b5f56c61150ee2a0186831d81c256 /test
parent3b50a8c9fe65839b79f8df988aee6124abd4f0c4 (diff)
* test/qt/*: Update the testcases, including testing the new
functionality of sending null QByteArray and QString over the bus. Add new headertest test and restore the old qdbusxmlparser test.
Diffstat (limited to 'test')
-rw-r--r--test/qt/Makefile.am19
-rw-r--r--test/qt/common.h24
-rw-r--r--test/qt/qpong.cpp12
-rw-r--r--test/qt/tst_hal.cpp1
-rw-r--r--test/qt/tst_headertest.cpp16
-rw-r--r--test/qt/tst_qdbusabstractadaptor.cpp78
-rw-r--r--test/qt/tst_qdbusconnection.cpp2
-rw-r--r--test/qt/tst_qdbusinterface.cpp87
-rw-r--r--test/qt/tst_qdbusmarshall.cpp (renamed from test/qt/ping.cpp)54
-rw-r--r--test/qt/tst_qdbusxmlparser.cpp578
10 files changed, 738 insertions, 133 deletions
diff --git a/test/qt/Makefile.am b/test/qt/Makefile.am
index f7a8efa9..8ebd3323 100644
--- a/test/qt/Makefile.am
+++ b/test/qt/Makefile.am
@@ -1,7 +1,7 @@
INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/qt $(DBUS_CLIENT_CFLAGS) $(DBUS_QT_CFLAGS) $(DBUS_QTESTLIB_CFLAGS) -DDBUS_COMPILATION
if DBUS_BUILD_TESTS
-TEST_BINARIES=qdbusconnection qpong ping qdbusinterface qdbusabstractadaptor hal
+TEST_BINARIES = tst_headertest tst_qdbusxmlparser tst_qdbusconnection qpong tst_qdbusmarshall tst_qdbusinterface tst_qdbusabstractadaptor tst_hal
TESTS=
else
TEST_BINARIES=
@@ -11,14 +11,17 @@ endif
noinst_PROGRAMS= $(TEST_BINARIES)
qpong_SOURCES= qpong.cpp
-ping_SOURCES= ping.cpp
-qdbusconnection_SOURCES= tst_qdbusconnection.cpp
-qdbusinterface_SOURCES= tst_qdbusinterface.cpp
-qdbusabstractadaptor_SOURCES= tst_qdbusabstractadaptor.cpp common.h
-hal_SOURCES = tst_hal.cpp
+tst_headertest_SOURCES = tst_headertest.cpp
+tst_qdbusconnection_SOURCES = tst_qdbusconnection.cpp
+tst_qdbusxmlparser_SOURCES = tst_qdbusxmlparser.cpp
+tst_qdbusmarshall_SOURCES = tst_qdbusmarshall.cpp
+tst_qdbusinterface_SOURCES = tst_qdbusinterface.cpp
+tst_qdbusabstractadaptor_SOURCES = tst_qdbusabstractadaptor.cpp common.h
+tst_hal_SOURCES = tst_hal.cpp
qpong.o: qpong.moc
-ping.o: ping.moc
+tst_qdbusxmlparser.o: tst_qdbusxmlparser.moc
+tst_qdbusmarshall.o: tst_qdbusmarshall.moc
tst_qdbusconnection.o: tst_qdbusconnection.moc
tst_qdbusinterface.o: tst_qdbusinterface.moc
tst_qdbusabstractadaptor.o: tst_qdbusabstractadaptor.moc
@@ -27,7 +30,7 @@ tst_hal.o: tst_hal.moc
%.moc: %.cpp
$(QT_MOC) $< > $@
-TEST_LIBS=$(DBUS_QTESTLIB_LIBS) $(top_builddir)/qt/libdbus-qt4-1.la
+TEST_LIBS=$(DBUS_QTESTLIB_LIBS) $(top_builddir)/qt/src/libdbus-qt4-1.la
LDADD=$(TEST_LIBS)
diff --git a/test/qt/common.h b/test/qt/common.h
index 943d3d95..58beae4e 100644
--- a/test/qt/common.h
+++ b/test/qt/common.h
@@ -9,8 +9,8 @@ Q_DECLARE_METATYPE(QList<uint>)
Q_DECLARE_METATYPE(QList<qlonglong>)
Q_DECLARE_METATYPE(QList<qulonglong>)
Q_DECLARE_METATYPE(QList<double>)
-#if 0
-#include "../qdbusintrospection_p.h"
+#ifdef USE_PRIVATE_CODE
+#include "../../qt/src/qdbusintrospection_p.h"
// just to make it easier:
typedef QDBusIntrospection::Interfaces InterfaceMap;
@@ -157,6 +157,20 @@ bool compare(const QList<double> &l1, const QList<double> &l2)
return true;
}
+bool compare(const QString &s1, const QString &s2)
+{
+ if (s1.isEmpty() && s2.isEmpty())
+ return true; // regardless of whether one of them is null
+ return s1 == s2;
+}
+
+bool compare(const QByteArray &ba1, const QByteArray &ba2)
+{
+ if (ba1.isEmpty() && ba2.isEmpty())
+ return true; // regardless of whether one of them is null
+ return ba1 == ba2;
+}
+
bool compare(const QVariant &v1, const QVariant &v2)
{
if (v1.userType() != v2.userType())
@@ -169,6 +183,12 @@ bool compare(const QVariant &v1, const QVariant &v2)
else if (id == QVariant::Map)
return compare(v1.toMap(), v2.toMap());
+ else if (id == QVariant::String)
+ return compare(v1.toString(), v2.toString());
+
+ else if (id == QVariant::ByteArray)
+ return compare(v1.toByteArray(), v2.toByteArray());
+
else if (id < int(QVariant::UserType)) // yes, v1.type()
// QVariant can compare
return v1 == v2;
diff --git a/test/qt/qpong.cpp b/test/qt/qpong.cpp
index 4a3e9763..cad04eb6 100644
--- a/test/qt/qpong.cpp
+++ b/test/qt/qpong.cpp
@@ -1,6 +1,5 @@
#include <QtCore/QtCore>
#include <dbus/qdbus.h>
-#include <dbus/dbus.h>
class Pong: public QObject
{
@@ -22,13 +21,10 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
QDBusConnection &con = QDBus::sessionBus();
- QDBusMessage msg = QDBusMessage::methodCall(DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- "RequestName");
- msg << "org.kde.selftest" << 0U;
- msg = con.sendWithReply(msg);
- if (msg.type() != QDBusMessage::ReplyMessage)
+ if (!con.isConnected())
+ exit(1);
+
+ if (con.busService()->requestName("org.kde.selftest", QDBusBusService::DoNotQueueName).isError())
exit(2);
Pong pong;
diff --git a/test/qt/tst_hal.cpp b/test/qt/tst_hal.cpp
index f98eb98a..a69daf2f 100644
--- a/test/qt/tst_hal.cpp
+++ b/test/qt/tst_hal.cpp
@@ -2,7 +2,6 @@
#include <qdebug.h>
#include <QtTest/QtTest>
-#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/qdbus.h>
class tst_Hal: public QObject
diff --git a/test/qt/tst_headertest.cpp b/test/qt/tst_headertest.cpp
new file mode 100644
index 00000000..eb90c555
--- /dev/null
+++ b/test/qt/tst_headertest.cpp
@@ -0,0 +1,16 @@
+#define QT_NO_KEYWORDS
+#define signals Choke!
+#define slots Choke!
+#define emit Choke!
+#define foreach Choke!
+#define forever Choke!
+
+#define QT_NO_CAST_FROM_ASCII
+#define QT_NO_CAST_TO_ASCII
+
+#include <dbus/qdbus.h>
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/test/qt/tst_qdbusabstractadaptor.cpp b/test/qt/tst_qdbusabstractadaptor.cpp
index ec3f0470..d47c5436 100644
--- a/test/qt/tst_qdbusabstractadaptor.cpp
+++ b/test/qt/tst_qdbusabstractadaptor.cpp
@@ -7,6 +7,10 @@
#include "common.h"
+#ifdef Q_CC_MSVC
+#define __PRETTY_FUNCTION__ __FUNCDNAME__
+#endif
+
const char *slotSpy;
QString valueSpy;
@@ -79,7 +83,7 @@ public:
class Interface1: public QDBusAbstractAdaptor
{
Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.Interface1");
+ Q_CLASSINFO("D-Bus Interface", "local.Interface1")
public:
Interface1(QObject *parent) : QDBusAbstractAdaptor(parent)
{ }
@@ -88,9 +92,9 @@ public:
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);
+ 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); }
@@ -117,9 +121,9 @@ signals:
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_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); }
@@ -157,9 +161,9 @@ signals:
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_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); }
@@ -452,51 +456,51 @@ void tst_QDBusAbstractAdaptor::methodCalls()
// must fail: no object
//QCOMPARE(empty->call("method").type(), QDBusMessage::ErrorMessage);
- QCOMPARE(if1->call("method").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if1->call(QDBusInterface::UseEventLoop, "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);
+ QCOMPARE(if1->call(QDBusInterface::UseEventLoop, "method").type(), QDBusMessage::ErrorMessage);
if (!nInterfaces--)
return;
if (!nInterfaces--)
return;
// simple call: one such method exists
- QCOMPARE(if2->call("method").type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(if2->call(QDBusInterface::UseEventLoop, "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(if1->call(QDBusInterface::UseEventLoop, "methodVoid").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if1->call(QDBusInterface::UseEventLoop, "methodInt").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if1->call(QDBusInterface::UseEventLoop, "methodString").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2->call(QDBusInterface::UseEventLoop, "methodVoid").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2->call(QDBusInterface::UseEventLoop, "methodInt").type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(if2->call(QDBusInterface::UseEventLoop, "methodString").type(), QDBusMessage::ErrorMessage);
+
+ QCOMPARE(if3->call(QDBusInterface::UseEventLoop, "methodVoid").type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface3::methodVoid()");
- QCOMPARE(if3->call("methodInt", 42).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(if3->call(QDBusInterface::UseEventLoop, "methodInt", 42).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface3::methodInt(int)");
- QCOMPARE(if3->call("methodString", QString("")).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(if3->call(QDBusInterface::UseEventLoop, "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(if4->call(QDBusInterface::UseEventLoop, "method").type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method()");
// method overloading: different parameters
- QCOMPARE(if4->call("method.i", 42).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(if4->call(QDBusInterface::UseEventLoop, "method.i", 42).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method(int)");
- QCOMPARE(if4->call("method.s", QString()).type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(if4->call(QDBusInterface::UseEventLoop, "method.s", QString()).type(), QDBusMessage::ReplyMessage);
QCOMPARE(slotSpy, "void Interface4::method(QString)");
}
@@ -679,18 +683,19 @@ void tst_QDBusAbstractAdaptor::readProperties()
MyObject obj;
con.registerObject("/", &obj);
+ QDBusInterfacePtr properties(con, con.baseService(), "/", "org.freedesktop.DBus.Properties");
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());
+ QDBusReply<QVariant> reply =
+ properties->call(QDBusInterface::UseEventLoop, "Get", "local." + name, propname);
+ QVariant value = reply;
QCOMPARE(value.userType(), int(QVariant::String));
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
}
- iface->deleteLater();
}
}
@@ -702,21 +707,21 @@ void tst_QDBusAbstractAdaptor::writeProperties()
MyObject obj;
con.registerObject("/", &obj);
+ QDBusInterfacePtr properties(con, con.baseService(), "/", "org.freedesktop.DBus.Properties");
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);
+ properties->call(QDBusInterface::UseEventLoop, "Set", "local." + name, QString("prop1"),
+ value);
QVERIFY(valueSpy.isEmpty()); // call mustn't have succeeded
- iface->setProperty("prop2", value);
+ properties->call(QDBusInterface::UseEventLoop, "Set", "local." + name, QString("prop2"),
+ value);
QCOMPARE(valueSpy, name);
QCOMPARE(QString(slotSpy), QString("void %1::setProp2(const QString&)").arg(name));
-
- iface->deleteLater();
}
}
@@ -964,10 +969,11 @@ void tst_QDBusAbstractAdaptor::typeMatching()
QDBusMessage reply;
QDBusInterface *iface = con.findInterface(con.baseService(), "/types", "local.TypesInterface");
- reply = iface->callWithArgs("method" + basename + '.' + signature, QVariantList() << value);
+ reply = iface->callWithArgs("method" + basename + '.' + signature, QVariantList() << value,
+ QDBusInterface::UseEventLoop);
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
- reply = iface->call("retrieve" + basename);
+ reply = iface->call(QDBusInterface::UseEventLoop, "retrieve" + basename);
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
QCOMPARE(reply.count(), 1);
diff --git a/test/qt/tst_qdbusconnection.cpp b/test/qt/tst_qdbusconnection.cpp
index 224a02c6..a887cd93 100644
--- a/test/qt/tst_qdbusconnection.cpp
+++ b/test/qt/tst_qdbusconnection.cpp
@@ -246,7 +246,7 @@ void tst_QDBusConnection::registerObject()
bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString &path)
{
QDBusMessage msg = QDBusMessage::methodCall(conn.baseService(), path, "local.any", "method");
- QDBusMessage reply = conn.sendWithReply(msg);
+ QDBusMessage reply = conn.sendWithReply(msg, QDBusConnection::UseEventLoop);
return reply.type() == QDBusMessage::ReplyMessage;
}
diff --git a/test/qt/tst_qdbusinterface.cpp b/test/qt/tst_qdbusinterface.cpp
index 46dde97a..a63b8e0b 100644
--- a/test/qt/tst_qdbusinterface.cpp
+++ b/test/qt/tst_qdbusinterface.cpp
@@ -34,63 +34,33 @@ Q_DECLARE_METATYPE(QVariantList)
#define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject"
#define TEST_SIGNAL_NAME "somethingHappened"
-const char introspectionData[] =
- "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
- "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
- "<node>"
-
- "<interface name=\"org.freedesktop.DBus.Introspectable\">"
- "<method name=\"Introspect\">"
- "<arg name=\"data\" direction=\"out\" type=\"s\"/>"
- "</method>"
- "</interface>"
-
- "<interface name=\"" TEST_INTERFACE_NAME "\">"
- "<method name=\"ping\">"
- "<arg name=\"ping\" direction=\"in\" type=\"v\"/>"
- "<arg name=\"pong\" direction=\"out\" type=\"v\"/>"
- "</method>"
- "<method name=\"ping\">"
- "<arg name=\"ping1\" direction=\"in\" type=\"v\"/>"
- "<arg name=\"ping2\" direction=\"in\" type=\"v\"/>"
- "<arg name=\"pong1\" direction=\"out\" type=\"v\"/>"
- "<arg name=\"pong2\" direction=\"out\" type=\"v\"/>"
- "</method>"
- "<signal name=\"" TEST_SIGNAL_NAME "\">"
- "<arg type=\"s\"/>"
- "</signal>"
- "<property name=\"prop1\" access=\"readwrite\" type=\"i\" />"
- "</interface>"
- "<node name=\"subObject\"/>"
- "</node>";
-
-class IntrospectionAdaptor: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.DBus.Introspectable")
-public:
- IntrospectionAdaptor(QObject *parent)
- : QDBusAbstractAdaptor(parent)
- { }
-
-public slots:
-
- void Introspect(const QDBusMessage &msg)
- {
- QDBusMessage reply = QDBusMessage::methodReply(msg);
- reply << ::introspectionData;
- if (!msg.connection().send(reply))
- exit(1);
- }
-};
-
class MyObject: public QObject
{
Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject")
+ Q_CLASSINFO("D-Bus Introspection", ""
+" <interface name=\"com.trolltech.QtDBus.MyObject\" >\n"
+" <property access=\"readwrite\" type=\"i\" name=\"prop1\" />\n"
+" <signal name=\"somethingHappened\" >\n"
+" <arg direction=\"out\" type=\"s\" />\n"
+" </signal>\n"
+" <method name=\"ping\" >\n"
+" <arg direction=\"in\" type=\"v\" name=\"ping\" />\n"
+" <arg direction=\"out\" type=\"v\" name=\"ping\" />\n"
+" </method>\n"
+" <method name=\"ping\" >\n"
+" <arg direction=\"in\" type=\"v\" name=\"ping1\" />\n"
+" <arg direction=\"in\" type=\"v\" name=\"ping2\" />\n"
+" <arg direction=\"out\" type=\"v\" name=\"pong1\" />\n"
+" <arg direction=\"out\" type=\"v\" name=\"pong2\" />\n"
+" </method>\n"
+" </interface>\n"
+ "")
public:
MyObject()
{
- new IntrospectionAdaptor(this);
+ QObject *subObject = new QObject(this);
+ subObject->setObjectName("subObject");
}
public slots:
@@ -152,7 +122,8 @@ void tst_QDBusInterface::initTestCase()
QDBusConnection &con = QDBus::sessionBus();
QVERIFY(con.isConnected());
- con.registerObject("/", &obj, QDBusConnection::ExportAdaptors | QDBusConnection::ExportSlots);
+ con.registerObject("/", &obj, QDBusConnection::ExportAdaptors | QDBusConnection::ExportSlots |
+ QDBusConnection::ExportChildObjects);
}
void tst_QDBusInterface::call_data()
@@ -241,7 +212,7 @@ void tst_QDBusInterface::call()
QDBusMessage reply;
// try first callWithArgs:
- reply = iface->callWithArgs(method, input);
+ reply = iface->callWithArgs(method, input, QDBusInterface::UseEventLoop);
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
if (!output.isEmpty()) {
@@ -251,20 +222,20 @@ void tst_QDBusInterface::call()
// try the template methods
if (input.isEmpty())
- reply = iface->call(method);
+ reply = iface->call(QDBusInterface::UseEventLoop, method);
else if (input.count() == 1)
switch (input.at(0).type())
{
case QVariant::Int:
- reply = iface->call(method, input.at(0).toInt());
+ reply = iface->call(QDBusInterface::UseEventLoop, method, input.at(0).toInt());
break;
case QVariant::UInt:
- reply = iface->call(method, input.at(0).toUInt());
+ reply = iface->call(QDBusInterface::UseEventLoop, method, input.at(0).toUInt());
break;
case QVariant::String:
- reply = iface->call(method, input.at(0).toString());
+ reply = iface->call(QDBusInterface::UseEventLoop, method, input.at(0).toString());
break;
default:
@@ -272,7 +243,7 @@ void tst_QDBusInterface::call()
break;
}
else
- reply = iface->call(method, input.at(0).toString(), input.at(1).toString());
+ reply = iface->call(QDBusInterface::UseEventLoop, method, input.at(0).toString(), input.at(1).toString());
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
if (!output.isEmpty()) {
diff --git a/test/qt/ping.cpp b/test/qt/tst_qdbusmarshall.cpp
index 1cdbfca5..306f7b6a 100644
--- a/test/qt/ping.cpp
+++ b/test/qt/tst_qdbusmarshall.cpp
@@ -3,8 +3,9 @@
#include <dbus/qdbus.h>
#include "common.h"
+#include <limits>
-class Ping: public QObject
+class tst_QDBusMarshall: public QObject
{
Q_OBJECT
@@ -35,19 +36,20 @@ private:
QProcess proc;
};
-void Ping::initTestCase()
+void tst_QDBusMarshall::initTestCase()
{
proc.start("./qpong");
QVERIFY(proc.waitForStarted());
QTest::qWait(2000);
}
-void Ping::cleanupTestCase()
+void tst_QDBusMarshall::cleanupTestCase()
{
proc.close();
+ proc.kill();
}
-void Ping::sendBasic_data()
+void tst_QDBusMarshall::sendBasic_data()
{
QTest::addColumn<QVariant>("value");
QTest::addColumn<QString>("sig");
@@ -65,9 +67,10 @@ void Ping::sendBasic_data()
QTest::newRow("double") << QVariant(42.5) << "d";
QTest::newRow("string") << QVariant("ping") << "s";
QTest::newRow("emptystring") << QVariant("") << "s";
+ QTest::newRow("nullstring") << QVariant(QString()) << "s";
}
-void Ping::sendVariant_data()
+void tst_QDBusMarshall::sendVariant_data()
{
sendBasic_data();
@@ -80,7 +83,7 @@ void Ping::sendVariant_data()
QTest::newRow("variant-variant") << nested2 << "v";
}
-void Ping::sendArrays_data()
+void tst_QDBusMarshall::sendArrays_data()
{
QTest::addColumn<QVariant>("value");
QTest::addColumn<QString>("sig");
@@ -91,10 +94,24 @@ void Ping::sendArrays_data()
strings << "hello" << "world";
QTest::newRow("stringlist") << QVariant(strings) << "as";
- QByteArray bytearray(""); // empty, not null
+ strings.clear();
+ strings << "" << "" << "";
+ QTest::newRow("list-of-emptystrings") << QVariant(strings) << "as";
+
+ strings.clear();
+ strings << QString() << QString() << QString() << QString();
+ QTest::newRow("list-of-nullstrings") << QVariant(strings) << "as";
+
+ QByteArray bytearray;
+ QTest::newRow("nullbytearray") << QVariant(bytearray) << "ay";
+ bytearray = ""; // empty, not null
QTest::newRow("emptybytearray") << QVariant(bytearray) << "ay";
bytearray = "foo";
QTest::newRow("bytearray") << QVariant(bytearray) << "ay";
+ bytearray.clear();
+ for (int i = 0; i < 4096; ++i)
+ bytearray += QByteArray(1024, char(i));
+ QTest::newRow("hugebytearray") << QVariant(bytearray) << "ay";
QList<bool> bools;
QTest::newRow("emptyboollist") << qVariantFromValue(bools) << "ab";
@@ -152,12 +169,12 @@ void Ping::sendArrays_data()
QTest::newRow("variantlist") << QVariant(variants) << "av";
}
-void Ping::sendArrayOfArrays_data()
+void tst_QDBusMarshall::sendArrayOfArrays_data()
{
sendArrays_data();
}
-void Ping::sendStringMap_data()
+void tst_QDBusMarshall::sendStringMap_data()
{
sendBasic_data();
@@ -172,12 +189,12 @@ void Ping::sendStringMap_data()
sendArrays_data();
}
-void Ping::sendStringMapOfMap_data()
+void tst_QDBusMarshall::sendStringMapOfMap_data()
{
sendStringMap_data();
}
-void Ping::sendBasic()
+void tst_QDBusMarshall::sendBasic()
{
QFETCH(QVariant, value);
@@ -198,7 +215,7 @@ void Ping::sendBasic()
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-void Ping::sendVariant()
+void tst_QDBusMarshall::sendVariant()
{
QFETCH(QVariant, value);
QVariant tmp = value;
@@ -221,7 +238,7 @@ void Ping::sendVariant()
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-void Ping::sendArrays()
+void tst_QDBusMarshall::sendArrays()
{
QFETCH(QVariant, value);
@@ -242,7 +259,7 @@ void Ping::sendArrays()
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-void Ping::sendArrayOfArrays()
+void tst_QDBusMarshall::sendArrayOfArrays()
{
QFETCH(QVariant, value);
@@ -264,7 +281,7 @@ void Ping::sendArrayOfArrays()
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-void Ping::sendStringMap()
+void tst_QDBusMarshall::sendStringMap()
{
QFETCH(QVariant, value);
@@ -290,7 +307,7 @@ void Ping::sendStringMap()
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-void Ping::sendStringMapOfMap()
+void tst_QDBusMarshall::sendStringMapOfMap()
{
QFETCH(QVariant, value);
@@ -316,11 +333,10 @@ void Ping::sendStringMapOfMap()
QFETCH(QString, sig);
QCOMPARE(reply.signature(), "a{sa{s" + sig + "}}");
- QEXPECT_FAIL("", "libdbus returns an empty set for un unknown reason", Abort);
for (int i = 0; i < reply.count(); ++i)
QVERIFY(compare(reply.at(i), msg.at(i)));
}
-QTEST_MAIN(Ping)
-#include "ping.moc"
+QTEST_MAIN(tst_QDBusMarshall)
+#include "tst_qdbusmarshall.moc"
diff --git a/test/qt/tst_qdbusxmlparser.cpp b/test/qt/tst_qdbusxmlparser.cpp
new file mode 100644
index 00000000..bf1ddec5
--- /dev/null
+++ b/test/qt/tst_qdbusxmlparser.cpp
@@ -0,0 +1,578 @@
+/* -*- C++ -*-
+ *
+ * Copyright (C) 2006 Trolltech AS. All rights reserved.
+ * Author: Thiago Macieira <thiago.macieira@trolltech.com>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#include <qcoreapplication.h>
+#include <qmetatype.h>
+#include <QtTest/QtTest>
+
+#include <dbus/qdbus.h>
+
+#define USE_PRIVATE_CODE
+#include "common.h"
+
+class tst_QDBusXmlParser: public QObject
+{
+ Q_OBJECT
+
+private:
+ void parsing_common(const QString&);
+
+private slots:
+ void parsing_data();
+ void parsing();
+ void parsingWithDoctype_data();
+ void parsingWithDoctype();
+
+ void objectWithContent_data();
+ void objectWithContent();
+
+ void methods_data();
+ void methods();
+ void signals__data();
+ void signals_();
+ void properties_data();
+ void properties();
+};
+
+void tst_QDBusXmlParser::parsing_data()
+{
+ QTest::addColumn<QString>("xmlData");
+ QTest::addColumn<int>("interfaceCount");
+ QTest::addColumn<int>("objectCount");
+
+ QTest::newRow("null") << QString() << 0 << 0;
+ QTest::newRow("empty") << QString("") << 0 << 0;
+
+ QTest::newRow("junk") << "<junk/>" << 0 << 0;
+ QTest::newRow("interface-inside-junk") << "<junk><interface name=\"iface.iface1\" /></junk>"
+ << 0 << 0;
+ QTest::newRow("object-inside-junk") << "<junk><node name=\"obj1\" /></junk>"
+ << 0 << 0;
+
+ QTest::newRow("zero-interfaces") << "<node/>" << 0 << 0;
+ QTest::newRow("one-interface") << "<node><interface name=\"iface.iface1\" /></node>" << 1 << 0;
+
+
+ QTest::newRow("two-interfaces") << "<node><interface name=\"iface.iface1\" />"
+ "<interface name=\"iface.iface2\"></node>"
+ << 2 << 0;
+
+
+ QTest::newRow("one-object") << "<node><node name=\"obj1\"/></node>" << 0 << 1;
+ QTest::newRow("two-objects") << "<node><node name=\"obj1\"/><node name=\"obj2\"></node>" << 0 << 2;
+
+ QTest::newRow("i1o1") << "<node><interface name=\"iface.iface1\"><node name=\"obj1\"></node>" << 1 << 1;
+
+}
+
+void tst_QDBusXmlParser::parsing_common(const QString &xmlData)
+{
+ QDBusIntrospection::ObjectTree obj =
+ QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
+ QFETCH(int, interfaceCount);
+ QFETCH(int, objectCount);
+ QCOMPARE(obj.interfaces.count(), interfaceCount);
+ QCOMPARE(obj.childObjects.count(), objectCount);
+
+ // also verify the naming
+ int i = 0;
+ foreach (QString name, obj.interfaces)
+ QCOMPARE(name, QString("iface.iface%1").arg(++i));
+
+ i = 0;
+ foreach (QString name, obj.childObjects)
+ QCOMPARE(name, QString("obj%1").arg(++i));
+}
+
+void tst_QDBusXmlParser::parsing()
+{
+ QFETCH(QString, xmlData);
+
+ parsing_common(xmlData);
+}
+
+void tst_QDBusXmlParser::parsingWithDoctype_data()
+{
+ parsing_data();
+}
+
+void tst_QDBusXmlParser::parsingWithDoctype()
+{
+ QString docType = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";
+ QFETCH(QString, xmlData);
+
+ parsing_common(docType + xmlData);
+}
+
+void tst_QDBusXmlParser::objectWithContent_data()
+{
+ QTest::addColumn<QString>("xmlData");
+ QTest::addColumn<QString>("probedObject");
+ QTest::addColumn<int>("interfaceCount");
+ QTest::addColumn<int>("objectCount");
+
+ QTest::newRow("zero") << "<node><node name=\"obj\"/></node>" << "obj" << 0 << 0;
+
+ QString xmlData = "<node><node name=\"obj\">"
+ "<interface name=\"iface.iface1\" />"
+ "</node></node>";
+ QTest::newRow("one-interface") << xmlData << "obj" << 1 << 0;
+ QTest::newRow("one-interface2") << xmlData << "obj2" << 0 << 0;
+
+ xmlData = "<node><node name=\"obj\">"
+ "<interface name=\"iface.iface1\" />"
+ "<interface name=\"iface.iface2\" />"
+ "</node></node>";
+ QTest::newRow("two-interfaces") << xmlData << "obj" << 2 << 0;
+ QTest::newRow("two-interfaces2") << xmlData << "obj2" << 0 << 0;
+
+ xmlData = "<node><node name=\"obj\">"
+ "<interface name=\"iface.iface1\" />"
+ "<interface name=\"iface.iface2\" />"
+ "</node><node name=\"obj2\">"
+ "<interface name=\"iface.iface1\" />"
+ "</node></node>";
+ QTest::newRow("two-nodes-two-interfaces") << xmlData << "obj" << 2 << 0;
+ QTest::newRow("two-nodes-one-interface") << xmlData << "obj2" << 1 << 0;
+
+ xmlData = "<node><node name=\"obj\">"
+ "<node name=\"obj1\" />"
+ "</node></node>";
+ QTest::newRow("one-object") << xmlData << "obj" << 0 << 1;
+ QTest::newRow("one-object2") << xmlData << "obj2" << 0 << 0;
+
+ xmlData = "<node><node name=\"obj\">"
+ "<node name=\"obj1\" />"
+ "<node name=\"obj2\" />"
+ "</node></node>";
+ QTest::newRow("two-objects") << xmlData << "obj" << 0 << 2;
+ QTest::newRow("two-objects2") << xmlData << "obj2" << 0 << 0;
+
+ xmlData = "<node><node name=\"obj\">"
+ "<node name=\"obj1\" />"
+ "<node name=\"obj2\" />"
+ "</node><node name=\"obj2\">"
+ "<node name=\"obj1\" />"
+ "</node></node>";
+ QTest::newRow("two-nodes-two-objects") << xmlData << "obj" << 0 << 2;
+ QTest::newRow("two-nodes-one-object") << xmlData << "obj2" << 0 << 1;
+}
+
+void tst_QDBusXmlParser::objectWithContent()
+{
+ QFETCH(QString, xmlData);
+ QFETCH(QString, probedObject);
+
+ QDBusIntrospection::ObjectTree tree =
+ QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
+
+ const ObjectMap &om = tree.childObjectData;
+
+ if (om.contains(probedObject)) {
+ const QSharedDataPointer<QDBusIntrospection::ObjectTree>& obj = om.value(probedObject);
+ QVERIFY(obj != 0);
+
+ QFETCH(int, interfaceCount);
+ QFETCH(int, objectCount);
+
+ QCOMPARE(obj->interfaces.count(), interfaceCount);
+ QCOMPARE(obj->childObjects.count(), objectCount);
+
+ // verify the object names
+ int i = 0;
+ foreach (QString name, obj->interfaces)
+ QCOMPARE(name, QString("iface.iface%1").arg(++i));
+
+ i = 0;
+ foreach (QString name, obj->childObjects)
+ QCOMPARE(name, QString("obj%1").arg(++i));
+ }
+}
+
+void tst_QDBusXmlParser::methods_data()
+{
+ QTest::addColumn<QString>("xmlDataFragment");
+ QTest::addColumn<MethodMap>("methodMap");
+
+ MethodMap map;
+ QTest::newRow("no-methods") << QString() << map;
+
+ // one method without arguments
+ QDBusIntrospection::Method method;
+ method.name = "Foo";
+ map << method;
+ QTest::newRow("one-method") << "<method name=\"Foo\"/>" << map;
+
+ // add another method without arguments
+ method.name = "Bar";
+ map << method;
+ QTest::newRow("two-methods") << "<method name=\"Foo\"/>"
+ "<method name=\"Bar\"/>"
+ << map;
+
+ // invert the order of the XML declaration
+ QTest::newRow("two-methods-inverse") << "<method name=\"Bar\"/>"
+ "<method name=\"Foo\"/>"
+ << map;
+
+ // add a third, with annotations
+ method.name = "Baz";
+ method.annotations.insert("foo.testing", "nothing to see here");
+ map << method;
+ QTest::newRow("method-with-annotation") <<
+ "<method name=\"Foo\"/>"
+ "<method name=\"Bar\"/>"
+ "<method name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></method>"
+ << map;
+
+ // arguments
+ map.clear();
+ method.annotations.clear();
+
+ method.name = "Method";
+ method.inputArgs << arg("s");
+ map << method;
+ QTest::newRow("one-in") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" direction=\"in\"/>"
+ "</method>" << map;
+
+ // two arguments
+ method.inputArgs << arg("v");
+ map.clear();
+ map << method;
+ QTest::newRow("two-in") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" direction=\"in\"/>"
+ "<arg type=\"v\" direction=\"in\"/>"
+ "</method>" << map;
+
+ // one invalid arg
+ QTest::newRow("two-in-one-invalid") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" direction=\"in\"/>"
+ "<arg type=\"~\" name=\"invalid\" direction=\"in\"/>" // this line should be ignored
+ "<arg type=\"v\" direction=\"in\"/>"
+ "</method>" << map;
+
+ // one out argument
+ method.inputArgs.clear();
+ method.outputArgs << arg("s");
+ map.clear();
+ map << method;
+ QTest::newRow("one-out") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" direction=\"out\"/>"
+ "</method>" << map;
+
+ // two in and one out
+ method.inputArgs << arg("s") << arg("v");
+ map.clear();
+ map << method;
+ QTest::newRow("two-in-one-out") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" direction=\"in\"/>"
+ "<arg type=\"v\" direction=\"in\"/>"
+ "<arg type=\"s\" direction=\"out\"/>"
+ "</method>" << map;
+
+ // let's try an arg with name
+ method.outputArgs.clear();
+ method.inputArgs.clear();
+ method.inputArgs << arg("s", "foo");
+ map.clear();
+ map << method;
+ QTest::newRow("one-in-with-name") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" name=\"foo\" direction=\"in\"/>"
+ "</method>" << map;
+
+ // two args with name
+ method.inputArgs << arg("i", "bar");
+ map.clear();
+ map << method;
+ QTest::newRow("two-in-with-name") <<
+ "<method name=\"Method\">"
+ "<arg type=\"s\" name=\"foo\" direction=\"in\"/>"
+ "<arg type=\"i\" name=\"bar\" direction=\"in\"/>"
+ "</method>" << map;
+
+ // one complex
+ map.clear();
+ method = QDBusIntrospection::Method();
+
+ // Method1(in STRING arg1, in BYTE arg2, out ARRAY of STRING)
+ method.inputArgs << arg("s", "arg1") << arg("y", "arg2");
+ method.outputArgs << arg("as");
+ method.name = "Method1";
+ map << method;
+
+ // Method2(in ARRAY of DICT_ENTRY of (STRING,VARIANT) variantMap, in UINT32 index,
+ // out STRING key, out VARIANT value)
+ // with annotation "foo.equivalent":"QVariantMap"
+ method = QDBusIntrospection::Method();
+ method.inputArgs << arg("a{sv}", "variantMap") << arg("u", "index");
+ method.outputArgs << arg("s", "key") << arg("v", "value");
+ method.annotations.insert("foo.equivalent", "QVariantMap");
+ method.name = "Method2";
+ map << method;
+
+ QTest::newRow("complex") <<
+ "<method name=\"Method1\">"
+ "<arg name=\"arg1\" type=\"s\" direction=\"in\"/>"
+ "<arg name=\"arg2\" type=\"y\" direction=\"in\"/>"
+ "<arg type=\"as\" direction=\"out\"/>"
+ "</method>"
+ "<method name=\"Method2\">"
+ "<arg name=\"variantMap\" type=\"a{sv}\" direction=\"in\"/>"
+ "<arg name=\"index\" type=\"u\" direction=\"in\"/>"
+ "<arg name=\"key\" type=\"s\" direction=\"out\"/>"
+ "<arg name=\"value\" type=\"v\" direction=\"out\"/>"
+ "<annotation name=\"foo.equivalent\" value=\"QVariantMap\"/>"
+ "</method>" << map;
+}
+
+void tst_QDBusXmlParser::methods()
+{
+ QString xmlHeader = "<node>"
+ "<interface name=\"iface.iface1\">",
+ xmlFooter = "</interface>"
+ "</node>";
+
+ QFETCH(QString, xmlDataFragment);
+
+ QDBusIntrospection::Interface iface =
+ QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
+
+ QCOMPARE(iface.name, QString("iface.iface1"));
+
+ QFETCH(MethodMap, methodMap);
+ MethodMap parsedMap = iface.methods;
+
+ QCOMPARE(methodMap.count(), parsedMap.count());
+ QCOMPARE(methodMap, parsedMap);
+}
+
+void tst_QDBusXmlParser::signals__data()
+{
+ QTest::addColumn<QString>("xmlDataFragment");
+ QTest::addColumn<SignalMap>("signalMap");
+
+ SignalMap map;
+ QTest::newRow("no-signals") << QString() << map;
+
+ // one signal without arguments
+ QDBusIntrospection::Signal signal;
+ signal.name = "Foo";
+ map << signal;
+ QTest::newRow("one-signal") << "<signal name=\"Foo\"/>" << map;
+
+ // add another signal without arguments
+ signal.name = "Bar";
+ map << signal;
+ QTest::newRow("two-signals") << "<signal name=\"Foo\"/>"
+ "<signal name=\"Bar\"/>"
+ << map;
+
+ // invert the order of the XML declaration
+ QTest::newRow("two-signals-inverse") << "<signal name=\"Bar\"/>"
+ "<signal name=\"Foo\"/>"
+ << map;
+
+ // add a third, with annotations
+ signal.name = "Baz";
+ signal.annotations.insert("foo.testing", "nothing to see here");
+ map << signal;
+ QTest::newRow("signal-with-annotation") <<
+ "<signal name=\"Foo\"/>"
+ "<signal name=\"Bar\"/>"
+ "<signal name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></signal>"
+ << map;
+
+ // one out argument
+ map.clear();
+ signal.annotations.clear();
+ signal.outputArgs << arg("s");
+ signal.name = "Signal";
+ map.clear();
+ map << signal;
+ QTest::newRow("one-out") <<
+ "<signal name=\"Signal\">"
+ "<arg type=\"s\" direction=\"out\"/>"
+ "</signal>" << map;
+
+ // without saying which direction it is
+ QTest::newRow("one-out-no-direction") <<
+ "<signal name=\"Signal\">"
+ "<arg type=\"s\"/>"
+ "</signal>" << map;
+
+ // two args with name
+ signal.outputArgs << arg("i", "bar");
+ map.clear();
+ map << signal;
+ QTest::newRow("two-out-with-name") <<
+ "<signal name=\"Signal\">"
+ "<arg type=\"s\" direction=\"out\"/>"
+ "<arg type=\"i\" name=\"bar\"/>"
+ "</signal>" << map;
+
+ // one complex
+ map.clear();
+ signal = QDBusIntrospection::Signal();
+
+ // Signal1(out ARRAY of STRING)
+ signal.outputArgs << arg("as");
+ signal.name = "Signal1";
+ map << signal;
+
+ // Signal2(out STRING key, out VARIANT value)
+ // with annotation "foo.equivalent":"QVariantMap"
+ signal = QDBusIntrospection::Signal();
+ signal.outputArgs << arg("s", "key") << arg("v", "value");
+ signal.annotations.insert("foo.equivalent", "QVariantMap");
+ signal.name = "Signal2";
+ map << signal;
+
+ QTest::newRow("complex") <<
+ "<signal name=\"Signal1\">"
+ "<arg type=\"as\" direction=\"out\"/>"
+ "</signal>"
+ "<signal name=\"Signal2\">"
+ "<arg name=\"key\" type=\"s\" direction=\"out\"/>"
+ "<arg name=\"value\" type=\"v\" direction=\"out\"/>"
+ "<annotation name=\"foo.equivalent\" value=\"QVariantMap\"/>"
+ "</signal>" << map;
+}
+
+void tst_QDBusXmlParser::signals_()
+{
+ QString xmlHeader = "<node>"
+ "<interface name=\"iface.iface1\">",
+ xmlFooter = "</interface>"
+ "</node>";
+
+ QFETCH(QString, xmlDataFragment);
+
+ QDBusIntrospection::Interface iface =
+ QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
+
+ QCOMPARE(iface.name, QString("iface.iface1"));
+
+ QFETCH(SignalMap, signalMap);
+ SignalMap parsedMap = iface.signals_;
+
+ QCOMPARE(signalMap.count(), parsedMap.count());
+ QCOMPARE(signalMap, parsedMap);
+}
+
+void tst_QDBusXmlParser::properties_data()
+{
+ QTest::addColumn<QString>("xmlDataFragment");
+ QTest::addColumn<PropertyMap>("propertyMap");
+
+ PropertyMap map;
+ QTest::newRow("no-signals") << QString() << map;
+
+ // one readable signal
+ QDBusIntrospection::Property prop;
+ prop.name = "foo";
+ prop.type = "s";
+ prop.access = QDBusIntrospection::Property::Read;
+ map << prop;
+ QTest::newRow("one-readable") << "<property name=\"foo\" type=\"s\" access=\"read\"/>" << map;
+
+ // one writable signal
+ prop.access = QDBusIntrospection::Property::Write;
+ map.clear();
+ map << prop;
+ QTest::newRow("one-writable") << "<property name=\"foo\" type=\"s\" access=\"write\"/>" << map;
+
+ // one read- & writable signal
+ prop.access = QDBusIntrospection::Property::ReadWrite;
+ map.clear();
+ map << prop;
+ QTest::newRow("one-read-writable") << "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>"
+ << map;
+
+ // two, mixed properties
+ prop.name = "bar";
+ prop.type = "i";
+ prop.access = QDBusIntrospection::Property::Read;
+ map << prop;
+ QTest::newRow("two") <<
+ "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>"
+ "<property name=\"bar\" type=\"i\" access=\"read\"/>" << map;
+
+ // invert the order of the declaration
+ QTest::newRow("two") <<
+ "<property name=\"bar\" type=\"i\" access=\"read\"/>"
+ "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
+
+ // add a third with annotations
+ prop.name = "baz";
+ prop.type = "as";
+ prop.access = QDBusIntrospection::Property::Write;
+ prop.annotations.insert("foo.annotation", "Hello, World");
+ prop.annotations.insert("foo.annotation2", "Goodbye, World");
+ map << prop;
+ QTest::newRow("complex") <<
+ "<property name=\"bar\" type=\"i\" access=\"read\"/>"
+ "<property name=\"baz\" type=\"as\" access=\"write\">"
+ "<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
+ "<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
+ "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
+
+ // and now change the order
+ QTest::newRow("complex2") <<
+ "<property name=\"baz\" type=\"as\" access=\"write\">"
+ "<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
+ "<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
+ "<property name=\"bar\" type=\"i\" access=\"read\"/>"
+ "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
+}
+
+void tst_QDBusXmlParser::properties()
+{
+ QString xmlHeader = "<node>"
+ "<interface name=\"iface.iface1\">",
+ xmlFooter = "</interface>"
+ "</node>";
+
+ QFETCH(QString, xmlDataFragment);
+
+ QDBusIntrospection::Interface iface =
+ QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
+
+ QCOMPARE(iface.name, QString("iface.iface1"));
+
+ QFETCH(PropertyMap, propertyMap);
+ PropertyMap parsedMap = iface.properties;
+
+ QCOMPARE(propertyMap.count(), parsedMap.count());
+ QCOMPARE(propertyMap, parsedMap);
+}
+
+QTEST_MAIN(tst_QDBusXmlParser)
+
+#include "tst_qdbusxmlparser.moc"