From fd5ac15ebc643635e436b64cf1e656284380b1a5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 11 Jun 2006 12:18:23 +0000 Subject: * 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. --- test/qt/Makefile.am | 19 +- test/qt/common.h | 24 +- test/qt/ping.cpp | 326 -------------------- test/qt/qpong.cpp | 12 +- test/qt/tst_hal.cpp | 1 - test/qt/tst_headertest.cpp | 16 + test/qt/tst_qdbusabstractadaptor.cpp | 78 ++--- test/qt/tst_qdbusconnection.cpp | 2 +- test/qt/tst_qdbusinterface.cpp | 87 ++---- test/qt/tst_qdbusmarshall.cpp | 342 +++++++++++++++++++++ test/qt/tst_qdbusxmlparser.cpp | 578 +++++++++++++++++++++++++++++++++++ 11 files changed, 1045 insertions(+), 440 deletions(-) delete mode 100644 test/qt/ping.cpp create mode 100644 test/qt/tst_headertest.cpp create mode 100644 test/qt/tst_qdbusmarshall.cpp create mode 100644 test/qt/tst_qdbusxmlparser.cpp (limited to 'test') 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) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) -#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 &l1, const QList &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/ping.cpp b/test/qt/ping.cpp deleted file mode 100644 index 1cdbfca5..00000000 --- a/test/qt/ping.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include -#include -#include - -#include "common.h" - -class Ping: public QObject -{ - Q_OBJECT - -public slots: - void initTestCase(); - void cleanupTestCase(); - -private slots: - void sendBasic_data(); - void sendBasic(); - - void sendVariant_data(); - void sendVariant(); - - void sendArrays_data(); - void sendArrays(); - - void sendArrayOfArrays_data(); - void sendArrayOfArrays(); - - void sendStringMap_data(); - void sendStringMap(); - - void sendStringMapOfMap_data(); - void sendStringMapOfMap(); - -private: - QProcess proc; -}; - -void Ping::initTestCase() -{ - proc.start("./qpong"); - QVERIFY(proc.waitForStarted()); - QTest::qWait(2000); -} - -void Ping::cleanupTestCase() -{ - proc.close(); -} - -void Ping::sendBasic_data() -{ - QTest::addColumn("value"); - QTest::addColumn("sig"); - - // basic types: - QTest::newRow("bool") << QVariant(false) << "b"; - QTest::newRow("bool2") << QVariant(true) << "b"; - QTest::newRow("byte") << qVariantFromValue(uchar(1)) << "y"; - QTest::newRow("int16") << qVariantFromValue(short(2)) << "n"; - QTest::newRow("uint16") << qVariantFromValue(ushort(3)) << "q"; - QTest::newRow("int") << QVariant(1) << "i"; - QTest::newRow("uint") << QVariant(2U) << "u"; - QTest::newRow("int64") << QVariant(Q_INT64_C(3)) << "x"; - QTest::newRow("uint64") << QVariant(Q_UINT64_C(4)) << "t"; - QTest::newRow("double") << QVariant(42.5) << "d"; - QTest::newRow("string") << QVariant("ping") << "s"; - QTest::newRow("emptystring") << QVariant("") << "s"; -} - -void Ping::sendVariant_data() -{ - sendBasic_data(); - - // add a few more: - QVariant nested(1); - QTest::newRow("variant") << nested << "v"; - - QVariant nested2; - qVariantSetValue(nested2, nested); - QTest::newRow("variant-variant") << nested2 << "v"; -} - -void Ping::sendArrays_data() -{ - QTest::addColumn("value"); - QTest::addColumn("sig"); - - // arrays: - QStringList strings; - QTest::newRow("emptystringlist") << QVariant(strings) << "as"; - strings << "hello" << "world"; - QTest::newRow("stringlist") << QVariant(strings) << "as"; - - QByteArray bytearray(""); // empty, not null - QTest::newRow("emptybytearray") << QVariant(bytearray) << "ay"; - bytearray = "foo"; - QTest::newRow("bytearray") << QVariant(bytearray) << "ay"; - - QList bools; - QTest::newRow("emptyboollist") << qVariantFromValue(bools) << "ab"; - bools << false << true << false; - QTest::newRow("boollist") << qVariantFromValue(bools) << "ab"; - - QList shorts; - QTest::newRow("emptyshortlist") << qVariantFromValue(shorts) << "an"; - shorts << 42 << -43 << 44 << 45 << -32768 << 32767; - QTest::newRow("shortlist") << qVariantFromValue(shorts) << "an"; - - QList ushorts; - QTest::newRow("emptyushortlist") << qVariantFromValue(ushorts) << "aq"; - ushorts << 12u << 13u << 14u << 15 << 65535; - QTest::newRow("ushortlist") << qVariantFromValue(ushorts) << "aq"; - - QList ints; - QTest::newRow("emptyintlist") << qVariantFromValue(ints) << "ai"; - ints << 42 << -43 << 44 << 45 << 2147483647 << -2147483647-1; - QTest::newRow("intlist") << qVariantFromValue(ints) << "ai"; - - QList uints; - QTest::newRow("emptyuintlist") << qVariantFromValue(uints) << "au"; - uints << uint(12) << uint(13) << uint(14) << 4294967295U; - QTest::newRow("uintlist") << qVariantFromValue(uints) << "au"; - - QList llints; - QTest::newRow("emptyllintlist") << qVariantFromValue(llints) << "ax"; - llints << Q_INT64_C(99) << Q_INT64_C(-100) - << Q_INT64_C(-9223372036854775807)-1 << Q_INT64_C(9223372036854775807); - QTest::newRow("llintlist") << qVariantFromValue(llints) << "ax"; - - QList ullints; - QTest::newRow("emptyullintlist") << qVariantFromValue(ullints) << "at"; - ullints << Q_UINT64_C(66) << Q_UINT64_C(67) - << Q_UINT64_C(18446744073709551615); - QTest::newRow("ullintlist") << qVariantFromValue(ullints) << "at"; - - QList doubles; - QTest::newRow("emptydoublelist") << qVariantFromValue(doubles) << "ad"; - doubles << 1.2 << 2.2 << 4.4 - << -std::numeric_limits::infinity() - << std::numeric_limits::infinity() - << std::numeric_limits::quiet_NaN(); - QTest::newRow("doublelist") << qVariantFromValue(doubles) << "ad"; - - QVariantList variants; - QTest::newRow("emptyvariantlist") << QVariant(variants) << "av"; - variants << QString("Hello") << QByteArray("World") << 42 << -43.0 << 44U << Q_INT64_C(-45) - << Q_UINT64_C(46) << true << qVariantFromValue(short(-47)); - for (int i = 0; i < variants.count(); ++i) { - QVariant tmp = variants.at(i); - qVariantSetValue(variants[i], tmp); - } - QTest::newRow("variantlist") << QVariant(variants) << "av"; -} - -void Ping::sendArrayOfArrays_data() -{ - sendArrays_data(); -} - -void Ping::sendStringMap_data() -{ - sendBasic_data(); - - QVariant nested; - qVariantSetValue(nested, QVariant(1)); - QTest::newRow("variant") << nested << "v"; - - QVariant nested2; - qVariantSetValue(nested2, nested); - QTest::newRow("variant-variant") << nested2 << "v"; - - sendArrays_data(); -} - -void Ping::sendStringMapOfMap_data() -{ - sendStringMap_data(); -} - -void Ping::sendBasic() -{ - QFETCH(QVariant, value); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - msg << value; - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - QTEST(reply.signature(), "sig"); - for (int i = 0; i < reply.count(); ++i) - QVERIFY(compare(reply.at(i), msg.at(i))); -} - -void Ping::sendVariant() -{ - QFETCH(QVariant, value); - QVariant tmp = value; - qVariantSetValue(value, tmp); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - msg << value; - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - QCOMPARE(reply.signature(), QString("v")); - for (int i = 0; i < reply.count(); ++i) - QVERIFY(compare(reply.at(i), msg.at(i))); -} - -void Ping::sendArrays() -{ - QFETCH(QVariant, value); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - msg << value; - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - QTEST(reply.signature(), "sig"); - for (int i = 0; i < reply.count(); ++i) - QVERIFY(compare(reply.at(i), msg.at(i))); -} - -void Ping::sendArrayOfArrays() -{ - QFETCH(QVariant, value); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - msg << QVariant(QVariantList() << value << value); - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - QFETCH(QString, sig); - QCOMPARE(reply.signature(), "a" + sig); - for (int i = 0; i < reply.count(); ++i) - QVERIFY(compare(reply.at(i), msg.at(i))); -} - -void Ping::sendStringMap() -{ - QFETCH(QVariant, value); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - - QVariantMap map; - map["foo"] = value; - map["bar"] = value; - msg << QVariant(map); - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - QFETCH(QString, sig); - QCOMPARE(reply.signature(), "a{s" + sig + "}"); - for (int i = 0; i < reply.count(); ++i) - QVERIFY(compare(reply.at(i), msg.at(i))); -} - -void Ping::sendStringMapOfMap() -{ - QFETCH(QVariant, value); - - QDBusConnection &con = QDBus::sessionBus(); - - QVERIFY(con.isConnected()); - - QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", - "/org/kde/selftest", "org.kde.selftest", "ping"); - - QVariantMap map; - map["foo"] = value; - map["bar"] = value; - - QVariantMap map2; - map2["foo"] = map; - msg << QVariant(map2); - - QDBusMessage reply = con.sendWithReply(msg); - // qDebug() << reply; - - QCOMPARE(reply.count(), msg.count()); - 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" 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 #include -#include 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 #include -#define DBUS_API_SUBJECT_TO_CHANGE #include 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 + +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 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[] = - "\n" - "" - - "" - "" - "" - "" - "" - - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - ""; - -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", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \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/tst_qdbusmarshall.cpp b/test/qt/tst_qdbusmarshall.cpp new file mode 100644 index 00000000..306f7b6a --- /dev/null +++ b/test/qt/tst_qdbusmarshall.cpp @@ -0,0 +1,342 @@ +#include +#include +#include + +#include "common.h" +#include + +class tst_QDBusMarshall: public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + +private slots: + void sendBasic_data(); + void sendBasic(); + + void sendVariant_data(); + void sendVariant(); + + void sendArrays_data(); + void sendArrays(); + + void sendArrayOfArrays_data(); + void sendArrayOfArrays(); + + void sendStringMap_data(); + void sendStringMap(); + + void sendStringMapOfMap_data(); + void sendStringMapOfMap(); + +private: + QProcess proc; +}; + +void tst_QDBusMarshall::initTestCase() +{ + proc.start("./qpong"); + QVERIFY(proc.waitForStarted()); + QTest::qWait(2000); +} + +void tst_QDBusMarshall::cleanupTestCase() +{ + proc.close(); + proc.kill(); +} + +void tst_QDBusMarshall::sendBasic_data() +{ + QTest::addColumn("value"); + QTest::addColumn("sig"); + + // basic types: + QTest::newRow("bool") << QVariant(false) << "b"; + QTest::newRow("bool2") << QVariant(true) << "b"; + QTest::newRow("byte") << qVariantFromValue(uchar(1)) << "y"; + QTest::newRow("int16") << qVariantFromValue(short(2)) << "n"; + QTest::newRow("uint16") << qVariantFromValue(ushort(3)) << "q"; + QTest::newRow("int") << QVariant(1) << "i"; + QTest::newRow("uint") << QVariant(2U) << "u"; + QTest::newRow("int64") << QVariant(Q_INT64_C(3)) << "x"; + QTest::newRow("uint64") << QVariant(Q_UINT64_C(4)) << "t"; + 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 tst_QDBusMarshall::sendVariant_data() +{ + sendBasic_data(); + + // add a few more: + QVariant nested(1); + QTest::newRow("variant") << nested << "v"; + + QVariant nested2; + qVariantSetValue(nested2, nested); + QTest::newRow("variant-variant") << nested2 << "v"; +} + +void tst_QDBusMarshall::sendArrays_data() +{ + QTest::addColumn("value"); + QTest::addColumn("sig"); + + // arrays: + QStringList strings; + QTest::newRow("emptystringlist") << QVariant(strings) << "as"; + strings << "hello" << "world"; + QTest::newRow("stringlist") << QVariant(strings) << "as"; + + 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 bools; + QTest::newRow("emptyboollist") << qVariantFromValue(bools) << "ab"; + bools << false << true << false; + QTest::newRow("boollist") << qVariantFromValue(bools) << "ab"; + + QList shorts; + QTest::newRow("emptyshortlist") << qVariantFromValue(shorts) << "an"; + shorts << 42 << -43 << 44 << 45 << -32768 << 32767; + QTest::newRow("shortlist") << qVariantFromValue(shorts) << "an"; + + QList ushorts; + QTest::newRow("emptyushortlist") << qVariantFromValue(ushorts) << "aq"; + ushorts << 12u << 13u << 14u << 15 << 65535; + QTest::newRow("ushortlist") << qVariantFromValue(ushorts) << "aq"; + + QList ints; + QTest::newRow("emptyintlist") << qVariantFromValue(ints) << "ai"; + ints << 42 << -43 << 44 << 45 << 2147483647 << -2147483647-1; + QTest::newRow("intlist") << qVariantFromValue(ints) << "ai"; + + QList uints; + QTest::newRow("emptyuintlist") << qVariantFromValue(uints) << "au"; + uints << uint(12) << uint(13) << uint(14) << 4294967295U; + QTest::newRow("uintlist") << qVariantFromValue(uints) << "au"; + + QList llints; + QTest::newRow("emptyllintlist") << qVariantFromValue(llints) << "ax"; + llints << Q_INT64_C(99) << Q_INT64_C(-100) + << Q_INT64_C(-9223372036854775807)-1 << Q_INT64_C(9223372036854775807); + QTest::newRow("llintlist") << qVariantFromValue(llints) << "ax"; + + QList ullints; + QTest::newRow("emptyullintlist") << qVariantFromValue(ullints) << "at"; + ullints << Q_UINT64_C(66) << Q_UINT64_C(67) + << Q_UINT64_C(18446744073709551615); + QTest::newRow("ullintlist") << qVariantFromValue(ullints) << "at"; + + QList doubles; + QTest::newRow("emptydoublelist") << qVariantFromValue(doubles) << "ad"; + doubles << 1.2 << 2.2 << 4.4 + << -std::numeric_limits::infinity() + << std::numeric_limits::infinity() + << std::numeric_limits::quiet_NaN(); + QTest::newRow("doublelist") << qVariantFromValue(doubles) << "ad"; + + QVariantList variants; + QTest::newRow("emptyvariantlist") << QVariant(variants) << "av"; + variants << QString("Hello") << QByteArray("World") << 42 << -43.0 << 44U << Q_INT64_C(-45) + << Q_UINT64_C(46) << true << qVariantFromValue(short(-47)); + for (int i = 0; i < variants.count(); ++i) { + QVariant tmp = variants.at(i); + qVariantSetValue(variants[i], tmp); + } + QTest::newRow("variantlist") << QVariant(variants) << "av"; +} + +void tst_QDBusMarshall::sendArrayOfArrays_data() +{ + sendArrays_data(); +} + +void tst_QDBusMarshall::sendStringMap_data() +{ + sendBasic_data(); + + QVariant nested; + qVariantSetValue(nested, QVariant(1)); + QTest::newRow("variant") << nested << "v"; + + QVariant nested2; + qVariantSetValue(nested2, nested); + QTest::newRow("variant-variant") << nested2 << "v"; + + sendArrays_data(); +} + +void tst_QDBusMarshall::sendStringMapOfMap_data() +{ + sendStringMap_data(); +} + +void tst_QDBusMarshall::sendBasic() +{ + QFETCH(QVariant, value); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + msg << value; + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QTEST(reply.signature(), "sig"); + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + +void tst_QDBusMarshall::sendVariant() +{ + QFETCH(QVariant, value); + QVariant tmp = value; + qVariantSetValue(value, tmp); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + msg << value; + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QCOMPARE(reply.signature(), QString("v")); + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + +void tst_QDBusMarshall::sendArrays() +{ + QFETCH(QVariant, value); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + msg << value; + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QTEST(reply.signature(), "sig"); + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + +void tst_QDBusMarshall::sendArrayOfArrays() +{ + QFETCH(QVariant, value); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + msg << QVariant(QVariantList() << value << value); + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QFETCH(QString, sig); + QCOMPARE(reply.signature(), "a" + sig); + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + +void tst_QDBusMarshall::sendStringMap() +{ + QFETCH(QVariant, value); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + + QVariantMap map; + map["foo"] = value; + map["bar"] = value; + msg << QVariant(map); + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QFETCH(QString, sig); + QCOMPARE(reply.signature(), "a{s" + sig + "}"); + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + +void tst_QDBusMarshall::sendStringMapOfMap() +{ + QFETCH(QVariant, value); + + QDBusConnection &con = QDBus::sessionBus(); + + QVERIFY(con.isConnected()); + + QDBusMessage msg = QDBusMessage::methodCall("org.kde.selftest", + "/org/kde/selftest", "org.kde.selftest", "ping"); + + QVariantMap map; + map["foo"] = value; + map["bar"] = value; + + QVariantMap map2; + map2["foo"] = map; + msg << QVariant(map2); + + QDBusMessage reply = con.sendWithReply(msg); + // qDebug() << reply; + + QCOMPARE(reply.count(), msg.count()); + QFETCH(QString, sig); + QCOMPARE(reply.signature(), "a{sa{s" + sig + "}}"); + + for (int i = 0; i < reply.count(); ++i) + QVERIFY(compare(reply.at(i), msg.at(i))); +} + + +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 + * + * 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 +#include +#include + +#include + +#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("xmlData"); + QTest::addColumn("interfaceCount"); + QTest::addColumn("objectCount"); + + QTest::newRow("null") << QString() << 0 << 0; + QTest::newRow("empty") << QString("") << 0 << 0; + + QTest::newRow("junk") << "" << 0 << 0; + QTest::newRow("interface-inside-junk") << "" + << 0 << 0; + QTest::newRow("object-inside-junk") << "" + << 0 << 0; + + QTest::newRow("zero-interfaces") << "" << 0 << 0; + QTest::newRow("one-interface") << "" << 1 << 0; + + + QTest::newRow("two-interfaces") << "" + "" + << 2 << 0; + + + QTest::newRow("one-object") << "" << 0 << 1; + QTest::newRow("two-objects") << "" << 0 << 2; + + QTest::newRow("i1o1") << "" << 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 = "\n"; + QFETCH(QString, xmlData); + + parsing_common(docType + xmlData); +} + +void tst_QDBusXmlParser::objectWithContent_data() +{ + QTest::addColumn("xmlData"); + QTest::addColumn("probedObject"); + QTest::addColumn("interfaceCount"); + QTest::addColumn("objectCount"); + + QTest::newRow("zero") << "" << "obj" << 0 << 0; + + QString xmlData = "" + "" + ""; + QTest::newRow("one-interface") << xmlData << "obj" << 1 << 0; + QTest::newRow("one-interface2") << xmlData << "obj2" << 0 << 0; + + xmlData = "" + "" + "" + ""; + QTest::newRow("two-interfaces") << xmlData << "obj" << 2 << 0; + QTest::newRow("two-interfaces2") << xmlData << "obj2" << 0 << 0; + + xmlData = "" + "" + "" + "" + "" + ""; + QTest::newRow("two-nodes-two-interfaces") << xmlData << "obj" << 2 << 0; + QTest::newRow("two-nodes-one-interface") << xmlData << "obj2" << 1 << 0; + + xmlData = "" + "" + ""; + QTest::newRow("one-object") << xmlData << "obj" << 0 << 1; + QTest::newRow("one-object2") << xmlData << "obj2" << 0 << 0; + + xmlData = "" + "" + "" + ""; + QTest::newRow("two-objects") << xmlData << "obj" << 0 << 2; + QTest::newRow("two-objects2") << xmlData << "obj2" << 0 << 0; + + xmlData = "" + "" + "" + "" + "" + ""; + 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& 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("xmlDataFragment"); + QTest::addColumn("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") << "" << map; + + // add another method without arguments + method.name = "Bar"; + map << method; + QTest::newRow("two-methods") << "" + "" + << map; + + // invert the order of the XML declaration + QTest::newRow("two-methods-inverse") << "" + "" + << 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") << + "" + "" + "" + << map; + + // arguments + map.clear(); + method.annotations.clear(); + + method.name = "Method"; + method.inputArgs << arg("s"); + map << method; + QTest::newRow("one-in") << + "" + "" + "" << map; + + // two arguments + method.inputArgs << arg("v"); + map.clear(); + map << method; + QTest::newRow("two-in") << + "" + "" + "" + "" << map; + + // one invalid arg + QTest::newRow("two-in-one-invalid") << + "" + "" + "" // this line should be ignored + "" + "" << map; + + // one out argument + method.inputArgs.clear(); + method.outputArgs << arg("s"); + map.clear(); + map << method; + QTest::newRow("one-out") << + "" + "" + "" << map; + + // two in and one out + method.inputArgs << arg("s") << arg("v"); + map.clear(); + map << method; + QTest::newRow("two-in-one-out") << + "" + "" + "" + "" + "" << 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") << + "" + "" + "" << map; + + // two args with name + method.inputArgs << arg("i", "bar"); + map.clear(); + map << method; + QTest::newRow("two-in-with-name") << + "" + "" + "" + "" << 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") << + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" << map; +} + +void tst_QDBusXmlParser::methods() +{ + QString xmlHeader = "" + "", + xmlFooter = "" + ""; + + 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("xmlDataFragment"); + QTest::addColumn("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") << "" << map; + + // add another signal without arguments + signal.name = "Bar"; + map << signal; + QTest::newRow("two-signals") << "" + "" + << map; + + // invert the order of the XML declaration + QTest::newRow("two-signals-inverse") << "" + "" + << 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") << + "" + "" + "" + << map; + + // one out argument + map.clear(); + signal.annotations.clear(); + signal.outputArgs << arg("s"); + signal.name = "Signal"; + map.clear(); + map << signal; + QTest::newRow("one-out") << + "" + "" + "" << map; + + // without saying which direction it is + QTest::newRow("one-out-no-direction") << + "" + "" + "" << map; + + // two args with name + signal.outputArgs << arg("i", "bar"); + map.clear(); + map << signal; + QTest::newRow("two-out-with-name") << + "" + "" + "" + "" << 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") << + "" + "" + "" + "" + "" + "" + "" + "" << map; +} + +void tst_QDBusXmlParser::signals_() +{ + QString xmlHeader = "" + "", + xmlFooter = "" + ""; + + 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("xmlDataFragment"); + QTest::addColumn("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") << "" << map; + + // one writable signal + prop.access = QDBusIntrospection::Property::Write; + map.clear(); + map << prop; + QTest::newRow("one-writable") << "" << map; + + // one read- & writable signal + prop.access = QDBusIntrospection::Property::ReadWrite; + map.clear(); + map << prop; + QTest::newRow("one-read-writable") << "" + << map; + + // two, mixed properties + prop.name = "bar"; + prop.type = "i"; + prop.access = QDBusIntrospection::Property::Read; + map << prop; + QTest::newRow("two") << + "" + "" << map; + + // invert the order of the declaration + QTest::newRow("two") << + "" + "" << 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") << + "" + "" + "" + "" + "" << map; + + // and now change the order + QTest::newRow("complex2") << + "" + "" + "" + "" + "" << map; +} + +void tst_QDBusXmlParser::properties() +{ + QString xmlHeader = "" + "", + xmlFooter = "" + ""; + + 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" -- cgit