diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | test/qt/Makefile.am | 10 | ||||
-rw-r--r-- | test/qt/common.h | 127 | ||||
-rw-r--r-- | test/qt/ping.cpp | 123 | ||||
-rw-r--r-- | test/qt/qpong.cpp | 35 | ||||
-rw-r--r-- | test/qt/tst_hal.cpp | 11 | ||||
-rw-r--r-- | test/qt/tst_qdbusabstractadaptor.cpp | 792 | ||||
-rw-r--r-- | test/qt/tst_qdbusconnection.cpp | 173 | ||||
-rw-r--r-- | test/qt/tst_qdbusinterface.cpp | 69 | ||||
-rw-r--r-- | test/qt/tst_qdbusobject.cpp | 57 | ||||
-rw-r--r-- | test/qt/tst_qdbustype.cpp | 1 | ||||
-rw-r--r-- | test/qt/tst_qdbusxmlparser.cpp | 137 |
12 files changed, 1298 insertions, 241 deletions
@@ -1,5 +1,9 @@ 2006-03-06 Thiago Macieira <thiago.macieira@trolltech.com> + * test/qt/*: Update the self-tests. + +2006-03-06 Thiago Macieira <thiago.macieira@trolltech.com> + * qt/*: * dbus/qdbus.h: Sync with KDE Subversion revision 516237. This represents the first feature-complete version of the Qt4 diff --git a/test/qt/Makefile.am b/test/qt/Makefile.am index 77f86d85..94283eb4 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 qdbusobject qdbusinterface qdbustype qdbusxmlparser hal +TEST_BINARIES=qdbustype qdbusxmlparser qdbusconnection qpong ping qdbusobject qdbusinterface qdbusabstractadaptor hal TESTS= else TEST_BINARIES= @@ -11,18 +11,24 @@ endif noinst_PROGRAMS= $(TEST_BINARIES) +qpong_SOURCES= qpong.cpp +ping_SOURCES= ping.cpp qdbusconnection_SOURCES= tst_qdbusconnection.cpp qdbusobject_SOURCES= tst_qdbusobject.cpp qdbusinterface_SOURCES= tst_qdbusinterface.cpp qdbustype_SOURCES= tst_qdbustype.cpp -qdbusxmlparser_SOURCES= tst_qdbusxmlparser.cpp +qdbusxmlparser_SOURCES= tst_qdbusxmlparser.cpp common.h +qdbusabstractadaptor_SOURCES= tst_qdbusabstractadaptor.cpp common.h hal_SOURCES = tst_hal.cpp +qpong.o: qpong.moc +ping.o: ping.moc tst_qdbusconnection.o: tst_qdbusconnection.moc tst_qdbusobject.o: tst_qdbusobject.moc tst_qdbusinterface.o: tst_qdbusinterface.moc tst_qdbustype.o: tst_qdbustype.moc tst_qdbusxmlparser.o: tst_qdbusxmlparser.moc +tst_qdbusabstractadaptor.o: tst_qdbusabstractadaptor.moc tst_hal.o: tst_hal.moc %.moc: %.cpp diff --git a/test/qt/common.h b/test/qt/common.h new file mode 100644 index 00000000..e3c78bd6 --- /dev/null +++ b/test/qt/common.h @@ -0,0 +1,127 @@ +// just to make it easier: +typedef QDBusIntrospection::Interfaces InterfaceMap; +typedef QDBusIntrospection::Objects ObjectMap; +typedef QDBusIntrospection::Arguments ArgumentList; +typedef QDBusIntrospection::Annotations AnnotationsMap; +typedef QDBusIntrospection::Methods MethodMap; +typedef QDBusIntrospection::Signals SignalMap; +typedef QDBusIntrospection::Properties PropertyMap; + +Q_DECLARE_METATYPE(QDBusIntrospection::Method) +Q_DECLARE_METATYPE(QDBusIntrospection::Signal) +Q_DECLARE_METATYPE(QDBusIntrospection::Property) +Q_DECLARE_METATYPE(MethodMap) +Q_DECLARE_METATYPE(SignalMap) +Q_DECLARE_METATYPE(PropertyMap) + +inline QDBusIntrospection::Argument arg(const char* type, const char *name = 0) +{ + QDBusIntrospection::Argument retval; + retval.type = QDBusType(type); + retval.name = QLatin1String(name); + return retval; +} + +template<typename T> +inline QMap<QString, T>& operator<<(QMap<QString, T>& map, const T& m) +{ map.insertMulti(m.name, m); return map; } + +inline const char* mapName(const MethodMap&) +{ return "MethodMap"; } + +inline const char* mapName(const SignalMap&) +{ return "SignalMap"; } + +inline const char* mapName(const PropertyMap&) +{ return "PropertyMap"; } + +QString printable(const QDBusIntrospection::Method& m) +{ + QString result = "method " + m.name + "("; + foreach (QDBusIntrospection::Argument arg, m.inputArgs) + result += QString("in %1 %2, ") + .arg(arg.type.toString(QDBusType::ConventionalNames)) + .arg(arg.name); + foreach (QDBusIntrospection::Argument arg, m.outputArgs) + result += QString("out %1 %2, ") + .arg(arg.type.toString(QDBusType::ConventionalNames)) + .arg(arg.name); + AnnotationsMap::const_iterator it = m.annotations.begin(); + for ( ; it != m.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + result += ")"; + return result; +} + +QString printable(const QDBusIntrospection::Signal& s) +{ + QString result = "signal " + s.name + "("; + foreach (QDBusIntrospection::Argument arg, s.outputArgs) + result += QString("out %1 %2, ") + .arg(arg.type.toString(QDBusType::ConventionalNames)) + .arg(arg.name); + AnnotationsMap::const_iterator it = s.annotations.begin(); + for ( ; it != s.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + result += ")"; + return result; +} + +QString printable(const QDBusIntrospection::Property& p) +{ + QString result; + if (p.access == QDBusIntrospection::Property::Read) + result = "property read %1 %2, "; + else if (p.access == QDBusIntrospection::Property::Write) + result = "property write %1 %2, "; + else + result = "property readwrite %1 %2, "; + result = result.arg(p.type.toString(QDBusType::ConventionalNames)).arg(p.name); + + AnnotationsMap::const_iterator it = p.annotations.begin(); + for ( ; it != p.annotations.end(); ++it) + result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); + + return result; +} + +template<typename T> +char* printableMap(const QMap<QString, T>& map) +{ + QString contents = "\n"; + typename QMap<QString, T>::const_iterator it = map.begin(); + for ( ; it != map.end(); ++it) { + if (it.key() != it.value().name) + contents += it.value().name + ":"; + contents += printable(it.value()); + contents += ";\n"; + } + + QString result("%1(size = %2): {%3}"); + return qstrdup(qPrintable(result + .arg(mapName(map)) + .arg(map.size()) + .arg(contents))); +} + +namespace QTest { + template<> + inline char* toString(const MethodMap& map) + { + return printableMap(map); + } + + template<> + inline char* toString(const SignalMap& map) + { + return printableMap(map); + } + + template<> + inline char* toString(const PropertyMap& map) + { + return printableMap(map); + } +} diff --git a/test/qt/ping.cpp b/test/qt/ping.cpp new file mode 100644 index 00000000..1777a804 --- /dev/null +++ b/test/qt/ping.cpp @@ -0,0 +1,123 @@ +#define DBUS_API_SUBJECT_TO_CHANGE +#include <QtCore/QtCore> +#include <QtTest/QtTest> +#include <dbus/qdbus.h> + +class Ping: public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + +private slots: + void sendPing_data(); + void sendPing(); + +private: + QProcess proc; +}; + +void Ping::initTestCase() +{ + proc.start("./qpong"); + QVERIFY(proc.waitForStarted()); + QTest::qWait(2000); +} + +void Ping::cleanupTestCase() +{ + proc.close(); +} + +Q_DECLARE_METATYPE(QVariant) + +void Ping::sendPing_data() +{ + QTest::addColumn<QVariant>("value"); + + QTest::newRow("string") << QVariant("ping"); + QTest::newRow("int") << QVariant(1); + QTest::newRow("double") << QVariant(42.5); + + QStringList strings; + strings << "hello" << "world"; + QTest::newRow("stringlist") << QVariant(strings); + + QList<QVariant> ints; + ints << 42 << -43 << 44 << 45; + QTest::newRow("intlist") << QVariant(ints); + + QList<QVariant> uints; + uints << uint(12) << uint(13) << uint(14); + QTest::newRow("uintlist") << QVariant(uints); + + QList<QVariant> llints; + llints << Q_INT64_C(99) << Q_INT64_C(-100); + QTest::newRow("llintlist") << QVariant(llints); + + QList<QVariant> ullints; + ullints << Q_UINT64_C(66) << Q_UINT64_C(67); + QTest::newRow("ullintlist") << QVariant(ullints); + + QList<QVariant> doubles; + doubles << 1.2 << 2.2 << 4.4; + QTest::newRow("doublelist") << QVariant(doubles); + + QList<QVariant> stackedInts; + stackedInts << 4 << ints << 5; + QTest::newRow("stackedInts") << QVariant(stackedInts); + + QList<QVariant> stackedUInts; + stackedUInts << uint(3) << uints << uint(4); + QTest::newRow("stackedUInts") << QVariant(stackedUInts); + + QList<QVariant> stackedLlints; + stackedLlints << Q_INT64_C(49) << llints << Q_INT64_C(-160); + QTest::newRow("stackedLlintlist") << QVariant(stackedLlints); + + QList<QVariant> stackedUllints; + stackedUllints << Q_UINT64_C(56) << ullints << Q_UINT64_C(57); + QTest::newRow("stackedullintlist") << QVariant(stackedUllints); + + QList<QVariant> stackedDoubles; + stackedDoubles << 6.2 << doubles << 6.4; + QTest::newRow("stackedDoublelist") << QVariant(stackedDoubles); + + QMap<QString, QVariant> map; + map["foo"] = "bar"; + map["kde"] = "great"; + QTest::newRow("map") << QVariant(map); + + QList<QVariant> byteArrays; + byteArrays << QByteArray("test1") << QByteArray("t2"); + QTest::newRow("bytearray") << QVariant(byteArrays); + + QList<QVariant> lists; + lists << QVariant(byteArrays) << QVariant(byteArrays); + QTest::newRow("listoflists") << QVariant(lists); +} + +void Ping::sendPing() +{ + 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()); + for (int i = 0; i < reply.count(); ++i) + QCOMPARE(reply.at(i), msg.at(i)); +} + +QTEST_MAIN(Ping) +#include "ping.moc" diff --git a/test/qt/qpong.cpp b/test/qt/qpong.cpp new file mode 100644 index 00000000..38e5c78d --- /dev/null +++ b/test/qt/qpong.cpp @@ -0,0 +1,35 @@ +#define DBUS_API_SUBJECT_TO_CHANGE +#include <QtCore/QtCore> +#include <dbus/qdbus.h> + +class Pong: public QObject +{ + Q_OBJECT +public slots: + + void ping(const QDBusMessage &msg) + { + QDBusMessage reply = QDBusMessage::methodReply(msg); + reply << static_cast<QList<QVariant> >(msg); + if (!msg.connection().send(reply)) + exit(1); + } +}; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QDBusConnection &con = QDBus::sessionBus(); + if (!con.requestName("org.kde.selftest")) + exit(2); + + Pong pong; + con.registerObject("/org/kde/selftest", &pong, QDBusConnection::ExportSlots); + + printf("ready.\n"); + + return app.exec(); +} + +#include "qpong.moc" diff --git a/test/qt/tst_hal.cpp b/test/qt/tst_hal.cpp index 36389c26..57c9b46d 100644 --- a/test/qt/tst_hal.cpp +++ b/test/qt/tst_hal.cpp @@ -2,6 +2,7 @@ #include <qdebug.h> #include <QtTest/QtTest> +#define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/qdbus.h> class tst_Hal: public QObject @@ -18,9 +19,9 @@ class Spy: public QObject Q_OBJECT public: int count; - QDBusConnection conn; + QDBusConnection &conn; - Spy(QDBusConnection c) : count(0), conn(c) + Spy(QDBusConnection &c) : count(0), conn(c) { } public slots: @@ -40,7 +41,7 @@ public slots: void tst_Hal::getDevices() { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SystemBus); + QDBusConnection &con = QDBus::systemBus(); QVERIFY(con.isConnected()); QDBusMessage msg = QDBusMessage::methodCall("org.freedesktop.Hal", @@ -49,12 +50,13 @@ void tst_Hal::getDevices() QDBusMessage reply = con.sendWithReply(msg); QVERIFY(!reply.isEmpty()); + QVERIFY(reply.type() == QDBusMessage::ReplyMessage); qDebug() << reply; } void tst_Hal::lock() { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SystemBus); + QDBusConnection &con = QDBus::systemBus(); QVERIFY(con.isConnected()); Spy spy( con ); @@ -68,6 +70,7 @@ void tst_Hal::lock() msg << "No reason..."; QDBusMessage reply = con.sendWithReply(msg); + QTest::qWait(200); qDebug() << reply; QCOMPARE(spy.count, 3); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); diff --git a/test/qt/tst_qdbusabstractadaptor.cpp b/test/qt/tst_qdbusabstractadaptor.cpp new file mode 100644 index 00000000..5c1c609d --- /dev/null +++ b/test/qt/tst_qdbusabstractadaptor.cpp @@ -0,0 +1,792 @@ +#include <qcoreapplication.h> +#include <qdebug.h> + +#include <QtTest/QtTest> + +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/qdbus.h> + +#include "common.h" + +Q_DECLARE_METATYPE(QVariant) + +const char *slotSpy; +QString propSpy; + +namespace QTest { + char *toString(QDBusMessage::MessageType t) + { + switch (t) + { + case QDBusMessage::InvalidMessage: + return qstrdup("InvalidMessage"); + case QDBusMessage::MethodCallMessage: + return qstrdup("MethodCallMessage"); + case QDBusMessage::ReplyMessage: + return qstrdup("ReplyMessage"); + case QDBusMessage::ErrorMessage: + return qstrdup("ErrorMessage"); + case QDBusMessage::SignalMessage: + return qstrdup("SignalMessage"); + default: + return 0; + } + } +} + +class tst_QDBusAbstractAdaptor: public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void methodCalls_data(); + void methodCalls(); + void signalEmissions_data(); + void signalEmissions(); + void sameSignalDifferentPaths(); + void overloadedSignalEmission_data(); + void overloadedSignalEmission(); + void readProperties(); + void writeProperties(); + void adaptorIntrospection_data(); + void adaptorIntrospection(); + void objectTreeIntrospection(); +}; + +class QDBusSignalSpy: public QObject +{ + Q_OBJECT + +public slots: + void slot(const QDBusMessage &msg) + { + ++count; + interface = msg.interface(); + name = msg.name(); + signature = msg.signature(); + value.clear(); + if (msg.count()) + value = msg.at(0); + } + +public: + QDBusSignalSpy() : count(0) { } + + int count; + QString interface; + QString name; + QString signature; + QVariant value; +}; + +class Interface1: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface1"); +public: + Interface1(QObject *parent) : QDBusAbstractAdaptor(parent) + { } + + static QDBusIntrospection::Methods methodData; + static QDBusIntrospection::Signals signalData; + static QDBusIntrospection::Properties propertyData; +}; + +class Interface2: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface2"); + Q_PROPERTY(QString prop1 READ prop1); + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2); +public: + Interface2(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return __PRETTY_FUNCTION__; } + + QString prop2() const + { return __PRETTY_FUNCTION__; } + + void setProp2(const QString &value) + { slotSpy = __PRETTY_FUNCTION__; propSpy = value; } + + void emitSignal(const QString &, const QVariant &) + { emit signal(); } + +public slots: + void method() { slotSpy = __PRETTY_FUNCTION__; } + +signals: + void signal(); + +public: + static QDBusIntrospection::Methods methodData; + static QDBusIntrospection::Signals signalData; + static QDBusIntrospection::Properties propertyData; +}; + +class Interface3: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface3"); + Q_PROPERTY(QString prop1 READ prop1); + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2); +public: + Interface3(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return __PRETTY_FUNCTION__; } + + QString prop2() const + { return __PRETTY_FUNCTION__; } + + void setProp2(const QString &value) + { slotSpy = __PRETTY_FUNCTION__; propSpy = value; } + + void emitSignal(const QString &name, const QVariant &value) + { + if (name == "signalVoid") + emit signalVoid(); + else if (name == "signalInt") + emit signalInt(value.toInt()); + else if (name == "signalString") + emit signalString(value.toString()); + } + +public slots: + void methodVoid() { slotSpy = __PRETTY_FUNCTION__; } + void methodInt(int) { slotSpy = __PRETTY_FUNCTION__; } + void methodString(QString) { slotSpy = __PRETTY_FUNCTION__; } + +signals: + void signalVoid(); + void signalInt(int); + void signalString(const QString &); + +public: + static QDBusIntrospection::Methods methodData; + static QDBusIntrospection::Signals signalData; + static QDBusIntrospection::Properties propertyData; +}; + +class Interface4: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface4"); + Q_PROPERTY(QString prop1 READ prop1); + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2); +public: + Interface4(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return __PRETTY_FUNCTION__; } + + QString prop2() const + { return __PRETTY_FUNCTION__; } + + void setProp2(const QString &value) + { slotSpy = __PRETTY_FUNCTION__; propSpy = value; } + + void emitSignal(const QString &, const QVariant &value) + { + switch (value.type()) + { + case QVariant::Invalid: + emit signal(); + break; + case QVariant::Int: + emit signal(value.toInt()); + break; + case QVariant::String: + emit signal(value.toString()); + break; + default: + break; + } + } + +public slots: + void method() { slotSpy = __PRETTY_FUNCTION__; } + void method(int) { slotSpy = __PRETTY_FUNCTION__; } + void method(QString) { slotSpy = __PRETTY_FUNCTION__; } + +signals: + void signal(); + void signal(int); + void signal(const QString &); + +public: + static QDBusIntrospection::Methods methodData; + static QDBusIntrospection::Signals signalData; + static QDBusIntrospection::Properties propertyData; +}; + + +QDBusIntrospection::Methods Interface1::methodData; +QDBusIntrospection::Signals Interface1::signalData; +QDBusIntrospection::Properties Interface1::propertyData; +QDBusIntrospection::Methods Interface2::methodData; +QDBusIntrospection::Signals Interface2::signalData; +QDBusIntrospection::Properties Interface2::propertyData; +QDBusIntrospection::Methods Interface3::methodData; +QDBusIntrospection::Signals Interface3::signalData; +QDBusIntrospection::Properties Interface3::propertyData; +QDBusIntrospection::Methods Interface4::methodData; +QDBusIntrospection::Signals Interface4::signalData; +QDBusIntrospection::Properties Interface4::propertyData; + +void tst_QDBusAbstractAdaptor::initTestCase() +{ + QDBusIntrospection::Method method; + method.name = "Method"; + Interface2::methodData << method; + Interface4::methodData << method; + method.inputArgs << arg("i"); + Interface4::methodData << method; + method.inputArgs.clear(); + method.inputArgs << arg("s"); + Interface4::methodData << method; + + method.name = "MethodVoid"; + method.inputArgs.clear(); + Interface3::methodData << method; + method.name = "MethodInt"; + method.inputArgs << arg("i"); + Interface3::methodData << method; + method.name = "MethodString"; + method.inputArgs.clear(); + method.inputArgs << arg("s"); + Interface3::methodData << method; + + QDBusIntrospection::Signal signal; + signal.name = "Signal"; + Interface2::signalData << signal; + Interface4::signalData << signal; + signal.outputArgs << arg("i"); + Interface4::signalData << signal; + signal.outputArgs.clear(); + signal.outputArgs << arg("s"); + Interface4::signalData << signal; + + signal.name = "SignalVoid"; + signal.outputArgs.clear(); + Interface3::signalData << signal; + signal.name = "SignalInt"; + signal.outputArgs << arg("i"); + Interface3::signalData << signal; + signal.name = "SignalString"; + signal.outputArgs.clear(); + signal.outputArgs << arg("s"); + Interface3::signalData << signal; + + QDBusIntrospection::Property prop; + prop.name = "Prop1"; + prop.type = QDBusType('s'); + prop.access = QDBusIntrospection::Property::Read; + Interface2::propertyData << prop; + Interface3::propertyData << prop; + Interface4::propertyData << prop; + prop.name = "Prop2"; + prop.access = QDBusIntrospection::Property::ReadWrite; + Interface2::propertyData << prop; + Interface3::propertyData << prop; + Interface4::propertyData << prop; +} + +void tst_QDBusAbstractAdaptor::methodCalls_data() +{ + QTest::addColumn<int>("nInterfaces"); + QTest::newRow("0") << 0; + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("3") << 3; + QTest::newRow("4") << 4; +} + +void tst_QDBusAbstractAdaptor::methodCalls() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QVERIFY(dobj.isValid()); + + //QDBusInterface empty(dobj, QString()); + QDBusInterface if1(dobj, "local.Interface1"); + QDBusInterface if2(dobj, "local.Interface2"); + QDBusInterface if3(dobj, "local.Interface3"); + QDBusInterface if4(dobj, "local.Interface4"); + + // must fail: no object + //QCOMPARE(empty.call("method").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if1.call("method").type(), QDBusMessage::ErrorMessage); + + QObject obj; + con.registerObject("/", &obj); + + QFETCH(int, nInterfaces); + switch (nInterfaces) + { + case 4: + new Interface4(&obj); + case 3: + new Interface3(&obj); + case 2: + new Interface2(&obj); + case 1: + new Interface1(&obj); + } + + // must fail: no such method + QCOMPARE(if1.call("method").type(), QDBusMessage::ErrorMessage); + if (!nInterfaces--) + return; + if (!nInterfaces--) + return; + + // simple call: one such method exists + QCOMPARE(if2.call("method").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface2::method()"); + if (!nInterfaces--) + return; + + // multiple methods in multiple interfaces, no name overlap + QCOMPARE(if1.call("methodVoid").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if1.call("methodInt").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if1.call("methodString").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call("methodVoid").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call("methodInt").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call("methodString").type(), QDBusMessage::ErrorMessage); + + QCOMPARE(if3.call("methodVoid").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface3::methodVoid()"); + QCOMPARE(if3.call("methodInt", 42).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface3::methodInt(int)"); + QCOMPARE(if3.call("methodString", QString("")).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface3::methodString(QString)"); + + if (!nInterfaces--) + return; + + // method overloading: different interfaces + QCOMPARE(if4.call("method").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface4::method()"); + + // method overloading: different parameters + QCOMPARE(if4.call("method.i", 42).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface4::method(int)"); + QCOMPARE(if4.call("method.s", QString()).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpy, "void Interface4::method(QString)"); + +} + +static void emitSignal(QDBusConnection &con, const QString &iface, const QString &name, + const QVariant ¶meter) +{ + QObject obj; + Interface2 *if2 = new Interface2(&obj); + Interface3 *if3 = new Interface3(&obj); + Interface4 *if4 = new Interface4(&obj); + con.registerObject("/",&obj); + + if (iface.endsWith('2')) + if2->emitSignal(name, parameter); + else if (iface.endsWith('3')) + if3->emitSignal(name, parameter); + else if (iface.endsWith('4')) + if4->emitSignal(name, parameter); + + QTest::qWait(200); +} + +void tst_QDBusAbstractAdaptor::signalEmissions_data() +{ + QTest::addColumn<QString>("interface"); + QTest::addColumn<QString>("name"); + QTest::addColumn<QString>("signature"); + QTest::addColumn<QVariant>("parameter"); + + QTest::newRow("Interface2.signal") << "local.Interface2" << "signal" << QString() << QVariant(); + QTest::newRow("Interface3.signalVoid") << "local.Interface3" << "signalVoid" << QString() << QVariant(); + QTest::newRow("Interface3.signalInt") << "local.Interface3" << "signalInt" << "i" << QVariant(1); + QTest::newRow("Interface3.signalString") << "local.Interface3" << "signalString" << "s" << QVariant("foo"); +} + +void tst_QDBusAbstractAdaptor::signalEmissions() +{ + QFETCH(QString, interface); + QFETCH(QString, name); + QFETCH(QVariant, parameter); + + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QVERIFY(dobj.isValid()); + + //QDBusInterface empty(dobj, QString()); + QDBusInterface if2(dobj, "local.Interface2"); + QDBusInterface if3(dobj, "local.Interface3"); + + // connect all signals and emit only one + { + QDBusSignalSpy spy; + if2.connect("signal", &spy, SLOT(slot(QDBusMessage))); + if3.connect("signalVoid", &spy, SLOT(slot(QDBusMessage))); + if3.connect("signalInt", &spy, SLOT(slot(QDBusMessage))); + if3.connect("signalString", &spy, SLOT(slot(QDBusMessage))); + + emitSignal(con, interface, name, parameter); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } + + // connect one signal and emit them all + { + QDBusSignalSpy spy; + con.connect(con.baseService(), "/", interface, name, &spy, SLOT(slot(QDBusMessage))); + emitSignal(con, "local.Interface2", "signal", QVariant()); + emitSignal(con, "local.Interface3", "signalVoid", QVariant()); + emitSignal(con, "local.Interface3", "signalInt", QVariant(1)); + emitSignal(con, "local.Interface3", "signalString", QVariant("foo")); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } +} + +void tst_QDBusAbstractAdaptor::sameSignalDifferentPaths() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QObject obj; + Interface2 *if2 = new Interface2(&obj); + + con.registerObject("/p1",&obj); + con.registerObject("/p2",&obj); + + QDBusSignalSpy spy; + con.connect(con.baseService(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + if2->emitSignal(QString(), QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, QString("local.Interface2")); + QCOMPARE(spy.name, QString("signal")); + QVERIFY(spy.signature.isEmpty()); + + // now connect the other one + spy.count = 0; + con.connect(con.baseService(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + if2->emitSignal(QString(), QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 2); +} + +void tst_QDBusAbstractAdaptor::overloadedSignalEmission_data() +{ + QTest::addColumn<QString>("signature"); + QTest::addColumn<QVariant>("parameter"); + QTest::newRow("void") << QString("") << QVariant(); + QTest::newRow("int") << "i" << QVariant(1); + QTest::newRow("string") << "s" << QVariant("foo"); +} + +void tst_QDBusAbstractAdaptor::overloadedSignalEmission() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QString interface = "local.Interface4"; + QString name = "signal"; + QFETCH(QVariant, parameter); + QDBusInterface if4 = con.findInterface(con.baseService(), "/", interface); + + // connect all signals and emit only one + { + QDBusSignalSpy spy; + if4.connect("signal.", &spy, SLOT(slot(QDBusMessage))); + if4.connect("signal.i", &spy, SLOT(slot(QDBusMessage))); + if4.connect("signal.s", &spy, SLOT(slot(QDBusMessage))); + + emitSignal(con, interface, name, parameter); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } + + QFETCH(QString, signature); + // connect one signal and emit them all + { + QDBusSignalSpy spy; + con.connect(con.baseService(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage))); + emitSignal(con, "local.Interface4", "signal", QVariant()); + emitSignal(con, "local.Interface4", "signal", QVariant(1)); + emitSignal(con, "local.Interface4", "signal", QVariant("foo")); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } +} + +void tst_QDBusAbstractAdaptor::readProperties() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QObject obj; + new Interface2(&obj); + new Interface3(&obj); + new Interface4(&obj); + con.registerObject("/", &obj); + + for (int i = 2; i <= 4; ++i) { + QString name = QString("Interface%1").arg(i); + QDBusInterface iface = con.findInterface(con.baseService(), "/", "local." + name); + + for (int j = 1; j <= 2; ++j) { + QString propname = QString("prop%1").arg(j); + QDBusVariant value = iface.property(propname); + + QVERIFY(value.type == QDBusType('s')); + QVERIFY(value.value.type() == QVariant::String); + QCOMPARE(value.value.toString(), QString("QString %1::%2() const").arg(name, propname)); + } + } +} + +void tst_QDBusAbstractAdaptor::writeProperties() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QObject obj; + new Interface2(&obj); + new Interface3(&obj); + new Interface4(&obj); + con.registerObject("/", &obj); + + for (int i = 2; i <= 4; ++i) { + QString name = QString("Interface%1").arg(i); + QDBusInterface iface = con.findInterface(con.baseService(), "/", "local." + name); + + QDBusVariant value(name); + + propSpy.clear(); + iface.setProperty("prop1", value); + QVERIFY(propSpy.isEmpty()); // call mustn't have succeeded + + iface.setProperty("prop2", value); + QCOMPARE(propSpy, name); + QCOMPARE(QString(slotSpy), QString("void %1::setProp2(const QString&)").arg(name)); + } +} + +void tst_QDBusAbstractAdaptor::adaptorIntrospection_data() +{ + methodCalls_data(); +} + +void tst_QDBusAbstractAdaptor::adaptorIntrospection() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + QObject obj; + con.registerObject("/", &obj); + + QFETCH(int, nInterfaces); + switch (nInterfaces) + { + case 4: + new Interface4(&obj); + case 3: + new Interface3(&obj); + case 2: + new Interface2(&obj); + case 1: + new Interface1(&obj); + } + + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QVERIFY(dobj.isValid()); + + QString xml = dobj.introspect(); + QVERIFY(!xml.isEmpty()); + + QStringList interfaces = dobj.interfaces(); + QCOMPARE(interfaces.count(), nInterfaces + 2); + switch (nInterfaces) + { + case 4: { + QVERIFY(interfaces.contains("local.Interface4")); + QDBusInterface iface(dobj, "local.Interface4"); + QCOMPARE(iface.methodData(), Interface4::methodData); + QCOMPARE(iface.signalData(), Interface4::signalData); + QCOMPARE(iface.propertyData(), Interface4::propertyData); + } + case 3: { + QVERIFY(interfaces.contains("local.Interface3")); + QDBusInterface iface(dobj, "local.Interface3"); + QCOMPARE(iface.methodData(), Interface3::methodData); + QCOMPARE(iface.signalData(), Interface3::signalData); + QCOMPARE(iface.propertyData(), Interface3::propertyData); + } + case 2: { + QVERIFY(interfaces.contains("local.Interface2")); + QDBusInterface iface(dobj, "local.Interface2"); + QCOMPARE(iface.methodData(), Interface2::methodData); + QCOMPARE(iface.signalData(), Interface2::signalData); + QCOMPARE(iface.propertyData(), Interface2::propertyData); + } + case 1: { + QVERIFY(interfaces.contains("local.Interface1")); + QDBusInterface iface(dobj, "local.Interface1"); + QCOMPARE(iface.methodData(), Interface1::methodData); + QCOMPARE(iface.signalData(), Interface1::signalData); + QCOMPARE(iface.propertyData(), Interface1::propertyData); + } + } +} + +void tst_QDBusAbstractAdaptor::objectTreeIntrospection() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.isEmpty()); + } + + QObject root; + con.registerObject("/", &root); + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.isEmpty()); + } + + QObject p1; + con.registerObject("/p1", &p1); + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.contains("p1")); + } + + con.unregisterObject("/"); + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.contains("p1")); + } + + con.registerObject("/p1/q/r", &root); + { + QDBusObject dobj = con.findObject(con.baseService(), "/p1"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.contains("q")); + } + { + QDBusObject dobj = con.findObject(con.baseService(), "/p1/q"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.contains("r")); + } + + con.unregisterObject("/p1", QDBusConnection::UnregisterTree); + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.isEmpty()); + } + + QObject p2; + con.registerObject("/p2", &p2, QDBusConnection::ExportChildObjects); + { + QDBusObject dobj = con.findObject(con.baseService(), "/"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(!tree.childObjects.contains("p1")); + QVERIFY(tree.childObjects.contains("p2")); + } + + QObject q; + q.setParent(&p2); + { + QDBusObject dobj = con.findObject(con.baseService(), "/p2"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(!tree.childObjects.contains("q")); + } + + q.setObjectName("q"); + { + QDBusObject dobj = con.findObject(con.baseService(), "/p2"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(tree.childObjects.contains("q")); + } + + q.setParent(0); + { + QDBusObject dobj = con.findObject(con.baseService(), "/p2"); + QString xml = dobj.introspect(); + + QDBusIntrospection::Object tree = + QDBusIntrospection::parseObject(xml); + QVERIFY(!tree.childObjects.contains("q")); + } +} + +QTEST_MAIN(tst_QDBusAbstractAdaptor) + +#include "tst_qdbusabstractadaptor.moc" diff --git a/test/qt/tst_qdbusconnection.cpp b/test/qt/tst_qdbusconnection.cpp index c3b15a2a..52fb9ff9 100644 --- a/test/qt/tst_qdbusconnection.cpp +++ b/test/qt/tst_qdbusconnection.cpp @@ -3,15 +3,26 @@ #include <QtTest/QtTest> +#define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/qdbus.h> +class MyObject: public QObject +{ + Q_OBJECT +public slots: + void method(const QDBusMessage &msg) { serial = msg.serialNumber(); path = msg.path(); } + +public: + int serial; + QString path; + MyObject() : serial(0) { } +}; + class tst_QDBusConnection: public QObject { Q_OBJECT private slots: - void init(); - void cleanupTestCase(); void addConnection(); void connect(); void send(); @@ -23,6 +34,11 @@ private slots: void getNameOwner(); void releaseName_data(); void releaseName(); + + void registerObject(); + +public: + bool callMethod(const QDBusConnection &conn, const QString &path); }; class QDBusSpy: public QObject @@ -37,25 +53,9 @@ public: int serial; }; -void tst_QDBusConnection::init() -{ - if (qstrcmp(QTest::currentTestFunction(), "addConnection") == 0) - return; - - QDBusConnection::addConnection(QDBusConnection::SessionBus); - QVERIFY(QDBusConnection().isConnected()); -} - -void tst_QDBusConnection::cleanupTestCase() -{ - QDBusConnection::closeConnection(); - - QVERIFY(!QDBusConnection().isConnected()); -} - void tst_QDBusConnection::sendSignal() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); @@ -70,7 +70,7 @@ void tst_QDBusConnection::sendSignal() void tst_QDBusConnection::send() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); @@ -86,7 +86,7 @@ void tst_QDBusConnection::send() void tst_QDBusConnection::sendAsync() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); QDBusSpy spy; @@ -107,7 +107,7 @@ void tst_QDBusConnection::connect() { QDBusSpy spy; - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy, SLOT(handlePing(QString))); @@ -133,7 +133,7 @@ void tst_QDBusConnection::addConnection() QVERIFY(con.isConnected()); QVERIFY(!con.lastError().isValid()); - QDBusConnection con2; + QDBusConnection con2("foo"); QVERIFY(!con2.isConnected()); QVERIFY(!con2.lastError().isValid()); @@ -157,26 +157,6 @@ void tst_QDBusConnection::addConnection() QVERIFY(!con.isConnected()); QVERIFY(!con.lastError().isValid()); } - - { - { - QDBusConnection con = QDBusConnection::addConnection( - QDBusConnection::SessionBus); - QVERIFY(con.isConnected()); - } - - { - QDBusConnection con; - QVERIFY(con.isConnected()); - QDBusConnection::closeConnection(); - QVERIFY(con.isConnected()); - } - - { - QDBusConnection con; - QVERIFY(!con.isConnected()); - } - } } void tst_QDBusConnection::requestName_data() @@ -197,7 +177,7 @@ void tst_QDBusConnection::requestName_data() void tst_QDBusConnection::requestName() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); @@ -224,7 +204,7 @@ void tst_QDBusConnection::getNameOwner_data() QTest::newRow("bus") << "org.freedesktop.DBus" << "org.freedesktop.DBus"; - QString base = QDBusConnection().baseService(); + QString base = QDBus::sessionBus().baseService(); QTest::newRow("address") << base << base; QTest::newRow("self") << "com.trolltech.QtDBUS.tst_qdbusconnection" << base; } @@ -234,7 +214,7 @@ void tst_QDBusConnection::getNameOwner() QFETCH(QString, name); QFETCH(QString, expectedResult); - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); QString result = con.getNameOwner(name); @@ -249,7 +229,7 @@ void tst_QDBusConnection::releaseName_data() void tst_QDBusConnection::releaseName() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); @@ -260,6 +240,105 @@ void tst_QDBusConnection::releaseName() bool result = con.releaseName(requestedName); QCOMPARE(result, expectedResult); +} + +void tst_QDBusConnection::registerObject() +{ + QDBusConnection &con = QDBus::sessionBus(); + QVERIFY(con.isConnected()); + + // make sure nothing is using our paths: + QVERIFY(!callMethod(con, "/")); + QVERIFY(!callMethod(con, "/p1")); + QVERIFY(!callMethod(con, "/p2")); + QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY(!callMethod(con, "/p1/q/r")); + + { + // register one object at root: + MyObject obj; + QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportSlots)); + QVERIFY(callMethod(con, "/")); + QCOMPARE(obj.path, QString("/")); + } + // make sure it's gone + QVERIFY(!callMethod(con, "/")); + + { + // register one at an element: + MyObject obj; + QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportSlots)); + QVERIFY(!callMethod(con, "/")); + QVERIFY(callMethod(con, "/p1")); + QCOMPARE(obj.path, QString("/p1")); + + // re-register it somewhere else + QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportSlots)); + QVERIFY(callMethod(con, "/p1")); + QCOMPARE(obj.path, QString("/p1")); + QVERIFY(callMethod(con, "/p2")); + QCOMPARE(obj.path, QString("/p2")); + } + // make sure it's gone + QVERIFY(!callMethod(con, "/p1")); + QVERIFY(!callMethod(con, "/p2")); + + { + // register at a deep path + MyObject obj; + QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportSlots)); + QVERIFY(!callMethod(con, "/")); + QVERIFY(!callMethod(con, "/p1")); + QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY(callMethod(con, "/p1/q/r")); + QCOMPARE(obj.path, QString("/p1/q/r")); + } + // make sure it's gone + QVERIFY(!callMethod(con, "/p1/q/r")); + + { + MyObject obj; + QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportSlots)); + QVERIFY(callMethod(con, "/p1/q2")); + QCOMPARE(obj.path, QString("/p1/q2")); + + // try unregistering + con.unregisterObject("/p1/q2"); + QVERIFY(!callMethod(con, "/p1/q2")); + + // register it again + QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportSlots)); + QVERIFY(callMethod(con, "/p1/q2")); + QCOMPARE(obj.path, QString("/p1/q2")); + + // now try removing things around it: + con.unregisterObject("/p2"); + QVERIFY(callMethod(con, "/p1/q2")); // unrelated object shouldn't affect + + con.unregisterObject("/p1"); + QVERIFY(callMethod(con, "/p1/q2")); // unregistering just the parent shouldn't affect it + + con.unregisterObject("/p1/q2/r"); + QVERIFY(callMethod(con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + + con.unregisterObject("/p1/q"); + QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + + con.unregisterObject("/p1/r"); + QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + + // now remove it: + con.unregisterObject("/p1", QDBusConnection::UnregisterTree); + QVERIFY(!callMethod(con, "/p1/q2")); // we removed the full tree + } +} + +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); + + return reply.type() == QDBusMessage::ReplyMessage; } QTEST_MAIN(tst_QDBusConnection) diff --git a/test/qt/tst_qdbusinterface.cpp b/test/qt/tst_qdbusinterface.cpp index 599b6c0d..a7f8c704 100644 --- a/test/qt/tst_qdbusinterface.cpp +++ b/test/qt/tst_qdbusinterface.cpp @@ -20,6 +20,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#define DBUS_API_SUBJECT_TO_CHANGE 1 #include <qcoreapplication.h> #include <qmetatype.h> #include <QtTest/QtTest> @@ -63,26 +64,42 @@ const char introspectionData[] = "<node name=\"subObject\"/>" "</node>"; -class MyObject: public QObject +class IntrospectionAdaptor: public QDBusAbstractAdaptor { Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.DBus.Introspectable") +public: + IntrospectionAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) + { } + public slots: - void ping(const QDBusMessage &msg) + void Introspect(const QDBusMessage &msg) { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); QDBusMessage reply = QDBusMessage::methodReply(msg); - reply << static_cast<QList<QVariant> >(msg); - if (!con.send(reply)) + reply << ::introspectionData; + if (!msg.connection().send(reply)) exit(1); } +}; - void Introspect(const QDBusMessage &msg) +class MyObject: public QObject +{ + Q_OBJECT +public: + MyObject() + { + new IntrospectionAdaptor(this); + } + +public slots: + + void ping(const QDBusMessage &msg) { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); QDBusMessage reply = QDBusMessage::methodReply(msg); - reply << ::introspectionData; - if (!con.send(reply)) + reply << static_cast<QList<QVariant> >(msg); + if (!msg.connection().send(reply)) exit(1); } }; @@ -110,7 +127,7 @@ void emitSignal(const QString &interface, const QString &name, const QString &ar { QDBusMessage msg = QDBusMessage::signal("/", interface, name); msg << arg; - QDBusConnection().send(msg); + QDBus::sessionBus().send(msg); QTest::qWait(200); } @@ -121,7 +138,6 @@ class tst_QDBusInterface: public QObject MyObject obj; private slots: void initTestCase(); - void cleanupTestCase(); void call_data(); void call(); @@ -134,18 +150,11 @@ private slots: void tst_QDBusInterface::initTestCase() { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); QVERIFY(con.requestName( TEST_SERVICE_NAME )); - con.registerObject("/", "org.freedesktop.DBus.Introspectable", &obj); - con.registerObject("/", TEST_INTERFACE_NAME, &obj); -} - -void tst_QDBusInterface::cleanupTestCase() -{ - QDBusConnection::closeConnection(); - QVERIFY(!QDBusConnection().isConnected()); + con.registerObject("/", &obj, QDBusConnection::ExportAdaptors | QDBusConnection::ExportSlots); } void tst_QDBusInterface::call_data() @@ -209,9 +218,9 @@ void tst_QDBusInterface::call_data() void tst_QDBusInterface::call() { - QDBusConnection con; - QDBusInterface iface(con, con.baseService(), QLatin1String("/"), - TEST_INTERFACE_NAME); + QDBusConnection &con = QDBus::sessionBus(); + QDBusInterface iface = con.findInterface(con.baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); QFETCH(QString, method); QFETCH(QVariantList, input); @@ -262,16 +271,16 @@ void tst_QDBusInterface::call() void tst_QDBusInterface::introspect_data() { QTest::addColumn<QString>("service"); - QTest::newRow("base") << QDBusConnection().baseService(); + QTest::newRow("base") << QDBus::sessionBus().baseService(); QTest::newRow("name") << TEST_SERVICE_NAME; } void tst_QDBusInterface::introspect() { QFETCH(QString, service); - QDBusConnection con; - QDBusInterface iface(con, service, QLatin1String("/"), - TEST_INTERFACE_NAME); + QDBusConnection &con = QDBus::sessionBus(); + QDBusInterface iface = con.findInterface(service, QLatin1String("/"), + TEST_INTERFACE_NAME); QDBusIntrospection::Methods mm = iface.methodData(); QVERIFY(mm.count() == 2); @@ -287,9 +296,9 @@ void tst_QDBusInterface::introspect() void tst_QDBusInterface::signal() { - QDBusConnection con; - QDBusInterface iface(con, con.baseService(), QLatin1String("/"), - TEST_INTERFACE_NAME); + QDBusConnection &con = QDBus::sessionBus(); + QDBusInterface iface = con.findInterface(con.baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); QString signalName = TEST_SIGNAL_NAME; diff --git a/test/qt/tst_qdbusobject.cpp b/test/qt/tst_qdbusobject.cpp index 24d5077e..904e98b5 100644 --- a/test/qt/tst_qdbusobject.cpp +++ b/test/qt/tst_qdbusobject.cpp @@ -20,6 +20,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#define DBUS_API_SUBJECT_TO_CHANGE 1 #include <qcoreapplication.h> #include <qmetatype.h> #include <QtTest/QtTest> @@ -46,26 +47,42 @@ const char introspectionData[] = "<node name=\"subObject\"/>" "</node>"; -class MyObject: public QObject +class IntrospectionAdaptor: public QDBusAbstractAdaptor { Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.DBus.Introspectable") +public: + IntrospectionAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) + { } + public slots: - void ping(const QDBusMessage &msg) + void Introspect(const QDBusMessage &msg) { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); QDBusMessage reply = QDBusMessage::methodReply(msg); - reply << static_cast<QList<QVariant> >(msg); - if (!con.send(reply)) + reply << ::introspectionData; + if (!msg.connection().send(reply)) exit(1); } +}; - void Introspect(const QDBusMessage &msg) +class MyObject: public QObject +{ + Q_OBJECT +public: + MyObject() + { + new IntrospectionAdaptor(this); + } + +public slots: + + void ping(const QDBusMessage &msg) { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); QDBusMessage reply = QDBusMessage::methodReply(msg); - reply << ::introspectionData; - if (!con.send(reply)) + reply << static_cast<QList<QVariant> >(msg); + if (!msg.connection().send(reply)) exit(1); } }; @@ -77,7 +94,6 @@ class tst_QDBusObject: public QObject private slots: void initTestCase(); // connect to D-Bus - void cleanupTestCase(); // disconnect from D-Bus void construction_data(); void construction(); @@ -88,18 +104,11 @@ private slots: void tst_QDBusObject::initTestCase() { - QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus); + QDBusConnection &con = QDBus::sessionBus(); QVERIFY(con.isConnected()); QVERIFY(con.requestName("com.trolltech.tst_qdbusobject")); - con.registerObject("/", "org.freedesktop.DBus.Introspectable", &obj); - con.registerObject("/", "com.trolltech.tst_qdbusobject.MyObject", &obj); -} - -void tst_QDBusObject::cleanupTestCase() -{ - QDBusConnection::closeConnection(); - QVERIFY(!QDBusConnection().isConnected()); + con.registerObject("/", &obj, QDBusConnection::ExportAdaptors | QDBusConnection::ExportSlots); } void tst_QDBusObject::construction_data() @@ -128,14 +137,14 @@ void tst_QDBusObject::construction_data() void tst_QDBusObject::construction() { - QDBusConnection con; // default + QDBusConnection &con = QDBus::sessionBus(); QFETCH(QString, service); QFETCH(QString, path); QFETCH(bool, isValid); //QFETCH(bool, exists); - QDBusObject o(con, service, path); + QDBusObject o = con.findObject(service, path); QCOMPARE(o.isValid(), isValid); if (isValid) { @@ -164,7 +173,7 @@ void tst_QDBusObject::introspection_data() interfaces << "org.freedesktop.DBus" << DBUS_INTERFACE_INTROSPECTABLE; QTest::newRow("server") << "org.freedesktop.DBus" << "/" << interfaces; - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); interfaces.clear(); interfaces << "com.trolltech.tst_qdbusobject.MyObject" << DBUS_INTERFACE_INTROSPECTABLE; @@ -174,12 +183,12 @@ void tst_QDBusObject::introspection_data() void tst_QDBusObject::introspection() { - QDBusConnection con; + QDBusConnection &con = QDBus::sessionBus(); QFETCH(QString, service); QFETCH(QString, path); - QDBusObject o(con, service, path); + QDBusObject o = con.findObject(service, path); if (!o.isValid()) QVERIFY(o.introspect().isEmpty()); diff --git a/test/qt/tst_qdbustype.cpp b/test/qt/tst_qdbustype.cpp index 124e60cb..9520ae6d 100644 --- a/test/qt/tst_qdbustype.cpp +++ b/test/qt/tst_qdbustype.cpp @@ -20,6 +20,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#define DBUS_API_SUBJECT_TO_CHANGE 1 #include <qcoreapplication.h> #include <QtTest/QtTest> diff --git a/test/qt/tst_qdbusxmlparser.cpp b/test/qt/tst_qdbusxmlparser.cpp index c7337c3a..d9085703 100644 --- a/test/qt/tst_qdbusxmlparser.cpp +++ b/test/qt/tst_qdbusxmlparser.cpp @@ -20,12 +20,15 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#define DBUS_API_SUBJECT_TO_CHANGE 1 #include <qcoreapplication.h> #include <qmetatype.h> #include <QtTest/QtTest> #include <dbus/qdbus.h> +#include "common.h" + class tst_QDBusXmlParser: public QObject { Q_OBJECT @@ -50,140 +53,6 @@ private slots: void properties(); }; -// just to make it easier: -typedef QDBusIntrospection::Interfaces InterfaceMap; -typedef QDBusIntrospection::Objects ObjectMap; -typedef QDBusIntrospection::Arguments ArgumentList; -typedef QDBusIntrospection::Annotations AnnotationsMap; -typedef QDBusIntrospection::Methods MethodMap; -typedef QDBusIntrospection::Signals SignalMap; -typedef QDBusIntrospection::Properties PropertyMap; - -Q_DECLARE_METATYPE(QDBusIntrospection::Method) -Q_DECLARE_METATYPE(QDBusIntrospection::Signal) -Q_DECLARE_METATYPE(QDBusIntrospection::Property) -Q_DECLARE_METATYPE(MethodMap) -Q_DECLARE_METATYPE(SignalMap) -Q_DECLARE_METATYPE(PropertyMap) - -inline QDBusIntrospection::Argument arg(const char* type, const char *name = 0) -{ - QDBusIntrospection::Argument retval; - retval.type = QDBusType(type); - retval.name = QLatin1String(name); - return retval; -} - -template<typename T> -inline QMap<QString, T>& operator<<(QMap<QString, T>& map, const T& m) -{ map.insert(m.name, m); return map; } - -inline const char* mapName(const MethodMap&) -{ return "MethodMap"; } - -inline const char* mapName(const SignalMap&) -{ return "SignalMap"; } - -inline const char* mapName(const PropertyMap&) -{ return "PropertyMap"; } - -QString printable(const QDBusIntrospection::Method& m) -{ - QString result = m.name + "("; - foreach (QDBusIntrospection::Argument arg, m.inputArgs) - result += QString("in %1 %2, ") - .arg(arg.type.toString(QDBusType::ConventionalNames)) - .arg(arg.name); - foreach (QDBusIntrospection::Argument arg, m.outputArgs) - result += QString("out %1 %2, ") - .arg(arg.type.toString(QDBusType::ConventionalNames)) - .arg(arg.name); - AnnotationsMap::const_iterator it = m.annotations.begin(); - for ( ; it != m.annotations.end(); ++it) - result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); - - if (result.length() > 1) - result.truncate(result.length() - 2); - result += ")"; - return result; -} - -QString printable(const QDBusIntrospection::Signal& s) -{ - QString result = s.name + "("; - foreach (QDBusIntrospection::Argument arg, s.outputArgs) - result += QString("out %1 %2, ") - .arg(arg.type.toString(QDBusType::ConventionalNames)) - .arg(arg.name); - AnnotationsMap::const_iterator it = s.annotations.begin(); - for ( ; it != s.annotations.end(); ++it) - result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); - - if (result.length() > 1) - result.truncate(result.length() - 2); - result += ")"; - return result; -} - -QString printable(const QDBusIntrospection::Property& p) -{ - QString result; - if (p.access == QDBusIntrospection::Property::Read) - result = "read %1 %2, "; - else if (p.access == QDBusIntrospection::Property::Write) - result = "write %1 %2, "; - else - result = "readwrite %1 %2, "; - result = result.arg(p.type.toString(QDBusType::ConventionalNames)).arg(p.name); - - AnnotationsMap::const_iterator it = p.annotations.begin(); - for ( ; it != p.annotations.end(); ++it) - result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value()); - - if (result.length() > 1) - result.truncate(result.length() - 2); - return result; -} - -template<typename T> -char* printableMap(const QMap<QString, T>& map) -{ - QString contents = "\n"; - typename QMap<QString, T>::const_iterator it = map.begin(); - for ( ; it != map.end(); ++it) { - if (it.key() != it.value().name) - contents += it.value().name + ":"; - contents += printable(it.value()); - contents += ";\n"; - } - - QString result("%1(size = %2): {%3}"); - return qstrdup(qPrintable(result - .arg(mapName(map)) - .arg(map.size()) - .arg(contents))); -} - -namespace QTest { - template<> - inline char* toString(const MethodMap& map) - { - return printableMap(map); - } - - template<> - inline char* toString(const SignalMap& map) - { - return printableMap(map); - } - - template<> - inline char* toString(const PropertyMap& map) - { - return printableMap(map); - } -} - void tst_QDBusXmlParser::parsing_data() { QTest::addColumn<QString>("xmlData"); |