diff options
| author | Thiago Macieira <thiago@kde.org> | 2006-03-06 14:30:52 +0000 | 
|---|---|---|
| committer | Thiago Macieira <thiago@kde.org> | 2006-03-06 14:30:52 +0000 | 
| commit | 12dc0934ae2a1fb92223f84804ad31a57689813c (patch) | |
| tree | f2f8d4ecc8493c109ff4834b2bcad91d3372aed8 | |
| parent | 9393d6b459d02a8508750a846bf97a69e48c97e2 (diff) | |
2006-03-06  Thiago Macieira  <thiago.macieira@trolltech.com>
	* test/qt/*: Update the self-tests.
| -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"); | 
