From: Thiago Macieira Date: Sun, 11 Jun 2006 12:18:23 +0000 (+0000) Subject: * test/qt/*: Update the testcases, including testing the new X-Git-Tag: dbus-0.62~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fd5ac15ebc643635e436b64cf1e656284380b1a5;p=thirdparty%2Fdbus.git * 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. --- diff --git a/ChangeLog b/ChangeLog index 2f1f1a6ab..8f48ca5ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-06-11 Thiago Macieira + + * 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. + 2006-06-11 Thiago Macieira * qt/tools/dbuscpp2xml.cpp: Compile on Windows. diff --git a/test/qt/Makefile.am b/test/qt/Makefile.am index f7a8efa99..8ebd33234 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 943d3d95f..58beae4e2 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/qpong.cpp b/test/qt/qpong.cpp index 4a3e97634..cad04eb67 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 f98eb98a9..a69daf2f7 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 000000000..eb90c5550 --- /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 ec3f0470e..d47c54365 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 224a02c62..a887cd93e 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 46dde97a3..a63b8e0bf 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/ping.cpp b/test/qt/tst_qdbusmarshall.cpp similarity index 85% rename from test/qt/ping.cpp rename to test/qt/tst_qdbusmarshall.cpp index 1cdbfca5b..306f7b6a4 100644 --- a/test/qt/ping.cpp +++ b/test/qt/tst_qdbusmarshall.cpp @@ -3,8 +3,9 @@ #include #include "common.h" +#include -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("value"); QTest::addColumn("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("value"); QTest::addColumn("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 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 000000000..bf1ddec5d --- /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"