/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include "interface.h" #include "pinger.h" typedef QSharedPointer Pinger; class tst_QDBusAbstractInterface: public QObject { Q_OBJECT Interface targetObj; Pinger getPinger(QString service = "", const QString &path = "/") { QDBusConnection con = QDBusConnection::sessionBus(); if (!con.isConnected()) return Pinger(); if (service.isEmpty() && !service.isNull()) service = con.baseService(); return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); } public: tst_QDBusAbstractInterface(); private slots: void initTestCase(); void makeVoidCall(); void makeStringCall(); void makeComplexCall(); void makeMultiOutCall(); void makeAsyncVoidCall(); void makeAsyncStringCall(); void makeAsyncComplexCall(); void makeAsyncMultiOutCall(); void stringPropRead(); void stringPropWrite(); void variantPropRead(); void variantPropWrite(); void complexPropRead(); void complexPropWrite(); void stringPropDirectRead(); void stringPropDirectWrite(); void variantPropDirectRead(); void variantPropDirectWrite(); void complexPropDirectRead(); void complexPropDirectWrite(); void getVoidSignal_data(); void getVoidSignal(); void getStringSignal_data(); void getStringSignal(); void getComplexSignal_data(); void getComplexSignal(); void createErrors_data(); void createErrors(); void callErrors_data(); void callErrors(); void asyncCallErrors_data(); void asyncCallErrors(); void propertyReadErrors_data(); void propertyReadErrors(); void propertyWriteErrors_data(); void propertyWriteErrors(); void directPropertyReadErrors_data(); void directPropertyReadErrors(); void directPropertyWriteErrors_data(); void directPropertyWriteErrors(); }; tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() { // register the meta types qDBusRegisterMetaType(); qRegisterMetaType(); } void tst_QDBusAbstractInterface::initTestCase() { // register the object QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); } void tst_QDBusAbstractInterface::makeVoidCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusReply r = p->voidMethod(); QVERIFY(r.isValid()); } void tst_QDBusAbstractInterface::makeStringCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusReply r = p->stringMethod(); QVERIFY(r.isValid()); QCOMPARE(r.value(), targetObj.stringMethod()); } void tst_QDBusAbstractInterface::makeComplexCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusReply r = p->complexMethod(); QVERIFY(r.isValid()); QCOMPARE(r.value(), targetObj.complexMethod()); } void tst_QDBusAbstractInterface::makeMultiOutCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); int value; QDBusReply r = p->multiOutMethod(value); QVERIFY(r.isValid()); int expectedValue; QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); QCOMPARE(value, expectedValue); } void tst_QDBusAbstractInterface::makeAsyncVoidCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusPendingReply r = p->voidMethod(); r.waitForFinished(); QVERIFY(r.isValid()); } void tst_QDBusAbstractInterface::makeAsyncStringCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusPendingReply r = p->stringMethod(); r.waitForFinished(); QVERIFY(r.isValid()); QCOMPARE(r.value(), targetObj.stringMethod()); } void tst_QDBusAbstractInterface::makeAsyncComplexCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusPendingReply r = p->complexMethod(); r.waitForFinished(); QVERIFY(r.isValid()); QCOMPARE(r.value(), targetObj.complexMethod()); } void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusPendingReply r = p->multiOutMethod(); r.waitForFinished(); QVERIFY(r.isValid()); int expectedValue; QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); QCOMPARE(r.argumentAt<1>(), expectedValue); } void tst_QDBusAbstractInterface::stringPropRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QString expectedValue = targetObj.m_stringProp = "This is a test"; QVariant v = p->property("stringProp"); QVERIFY(v.isValid()); QCOMPARE(v.toString(), expectedValue); } void tst_QDBusAbstractInterface::stringPropWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QString expectedValue = "This is a value"; QVERIFY(p->setProperty("stringProp", expectedValue)); QCOMPARE(targetObj.m_stringProp, expectedValue); } void tst_QDBusAbstractInterface::variantPropRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(QVariant(42)); QVariant v = p->property("variantProp"); QVERIFY(v.isValid()); QDBusVariant value = v.value(); QCOMPARE(value.variant().userType(), expectedValue.variant().userType()); QCOMPARE(value.variant(), expectedValue.variant()); } void tst_QDBusAbstractInterface::variantPropWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); } void tst_QDBusAbstractInterface::complexPropRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); QVariant v = p->property("complexProp"); QVERIFY(v.userType() == qMetaTypeId()); QCOMPARE(v.value(), targetObj.m_complexProp); } void tst_QDBusAbstractInterface::complexPropWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); RegisteredType expectedValue = RegisteredType("This is a value"); QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); QCOMPARE(targetObj.m_complexProp, expectedValue); } void tst_QDBusAbstractInterface::stringPropDirectRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QString expectedValue = targetObj.m_stringProp = "This is a test"; QCOMPARE(p->stringProp(), expectedValue); } void tst_QDBusAbstractInterface::stringPropDirectWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QString expectedValue = "This is a value"; p->setStringProp(expectedValue); QCOMPARE(targetObj.m_stringProp, expectedValue); } void tst_QDBusAbstractInterface::variantPropDirectRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(42); QCOMPARE(p->variantProp().variant(), expectedValue.variant()); } void tst_QDBusAbstractInterface::variantPropDirectWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); p->setVariantProp(expectedValue); QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); } void tst_QDBusAbstractInterface::complexPropDirectRead() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); QCOMPARE(p->complexProp(), targetObj.m_complexProp); } void tst_QDBusAbstractInterface::complexPropDirectWrite() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); RegisteredType expectedValue = RegisteredType("This is a value"); p->setComplexProp(expectedValue); QCOMPARE(targetObj.m_complexProp, expectedValue); } void tst_QDBusAbstractInterface::getVoidSignal_data() { QTest::addColumn("service"); QTest::addColumn("path"); QTest::newRow("specific") << QDBusConnection::sessionBus().baseService() << "/"; QTest::newRow("service-wildcard") << QString() << "/"; QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString(); QTest::newRow("full-wildcard") << QString() << QString(); } void tst_QDBusAbstractInterface::getVoidSignal() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we need to connect the signal somewhere in order for D-Bus to enable the rules QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); QSignalSpy s(p.data(), SIGNAL(voidSignal())); emit targetObj.voidSignal(); QTestEventLoop::instance().enterLoop(2); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(s.size() == 1); QVERIFY(s.at(0).size() == 0); } void tst_QDBusAbstractInterface::getStringSignal_data() { getVoidSignal_data(); } void tst_QDBusAbstractInterface::getStringSignal() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we need to connect the signal somewhere in order for D-Bus to enable the rules QTestEventLoop::instance().connect(p.data(), SIGNAL(stringSignal(QString)), SLOT(exitLoop())); QSignalSpy s(p.data(), SIGNAL(stringSignal(QString))); QString expectedValue = "Good morning"; emit targetObj.stringSignal(expectedValue); QTestEventLoop::instance().enterLoop(2); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(s.size() == 1); QVERIFY(s[0].size() == 1); QCOMPARE(s[0][0].userType(), int(QVariant::String)); QCOMPARE(s[0][0].toString(), expectedValue); } void tst_QDBusAbstractInterface::getComplexSignal_data() { getVoidSignal_data(); } void tst_QDBusAbstractInterface::getComplexSignal() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we need to connect the signal somewhere in order for D-Bus to enable the rules QTestEventLoop::instance().connect(p.data(), SIGNAL(complexSignal(RegisteredType)), SLOT(exitLoop())); QSignalSpy s(p.data(), SIGNAL(complexSignal(RegisteredType))); RegisteredType expectedValue("Good evening"); emit targetObj.complexSignal(expectedValue); QTestEventLoop::instance().enterLoop(2); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(s.size() == 1); QVERIFY(s[0].size() == 1); QCOMPARE(s[0][0].userType(), qMetaTypeId()); QCOMPARE(s[0][0].value(), expectedValue); } void tst_QDBusAbstractInterface::createErrors_data() { QTest::addColumn("service"); QTest::addColumn("path"); QTest::addColumn("errorName"); QTest::newRow("invalid-service") << "this isn't valid" << "/" << "com.trolltech.QtDBus.Error.InvalidService"; QTest::newRow("invalid-path") << QDBusConnection::sessionBus().baseService() << "this isn't valid" << "com.trolltech.QtDBus.Error.InvalidObjectPath"; } void tst_QDBusAbstractInterface::createErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); QVERIFY(!p->isValid()); QTEST(p->lastError().name(), "errorName"); } void tst_QDBusAbstractInterface::callErrors_data() { createErrors_data(); QTest::newRow("service-wildcard") << QString() << "/" << "com.trolltech.QtDBus.Error.InvalidService"; QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString() << "com.trolltech.QtDBus.Error.InvalidObjectPath"; QTest::newRow("full-wildcard") << QString() << QString() << "com.trolltech.QtDBus.Error.InvalidService"; } void tst_QDBusAbstractInterface::callErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to make this call: QDBusReply r = p->stringMethod(); QVERIFY(!r.isValid()); QTEST(r.error().name(), "errorName"); QCOMPARE(p->lastError().name(), r.error().name()); } void tst_QDBusAbstractInterface::asyncCallErrors_data() { callErrors_data(); } void tst_QDBusAbstractInterface::asyncCallErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to make this call: QDBusPendingReply r = p->stringMethod(); QVERIFY(r.isError()); QTEST(r.error().name(), "errorName"); QCOMPARE(p->lastError().name(), r.error().name()); } void tst_QDBusAbstractInterface::propertyReadErrors_data() { callErrors_data(); } void tst_QDBusAbstractInterface::propertyReadErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to get this value: QVariant v = p->property("stringProp"); QVERIFY(v.isNull()); QVERIFY(!v.isValid()); QTEST(p->lastError().name(), "errorName"); } void tst_QDBusAbstractInterface::propertyWriteErrors_data() { callErrors_data(); } void tst_QDBusAbstractInterface::propertyWriteErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to get this value: if (p->isValid()) QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); QVERIFY(!p->setProperty("stringProp", "")); QTEST(p->lastError().name(), "errorName"); } void tst_QDBusAbstractInterface::directPropertyReadErrors_data() { callErrors_data(); } void tst_QDBusAbstractInterface::directPropertyReadErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to get this value: QString v = p->stringProp(); QVERIFY(v.isNull()); QTEST(p->lastError().name(), "errorName"); } void tst_QDBusAbstractInterface::directPropertyWriteErrors_data() { callErrors_data(); } void tst_QDBusAbstractInterface::directPropertyWriteErrors() { QFETCH(QString, service); QFETCH(QString, path); Pinger p = getPinger(service, path); QVERIFY2(p, "Not connected to D-Bus"); // we shouldn't be able to get this value: // but there's no direct way of verifying that the setting failed if (p->isValid()) QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); p->setStringProp(""); QTEST(p->lastError().name(), "errorName"); } QTEST_MAIN(tst_QDBusAbstractInterface) #include "tst_qdbusabstractinterface.moc"