mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-04-18 19:00:37 +02:00
Add new tests and update the existing one.
This commit is contained in:
parent
345671f75c
commit
9076938fc0
7 changed files with 1710 additions and 15 deletions
|
|
@ -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
|
||||
TEST_BINARIES=qdbusconnection qdbusobject qdbusinterface qdbustype qdbusxmlparser hal
|
||||
TESTS=
|
||||
else
|
||||
TEST_BINARIES=
|
||||
|
|
@ -11,16 +11,25 @@ endif
|
|||
|
||||
noinst_PROGRAMS= $(TEST_BINARIES)
|
||||
|
||||
qdbusconnection_SOURCES= \
|
||||
tst_qdbusconnection.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
|
||||
hal_SOURCES = tst_hal.cpp
|
||||
|
||||
tst_qdbusconnection.cpp: tst_qdbusconnection.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_hal.o: tst_hal.moc
|
||||
|
||||
tst_qdbusconnection.moc:
|
||||
$(QT_MOC) $(srcdir)/tst_qdbusconnection.cpp > tst_qdbusconnection.moc
|
||||
%.moc: %.cpp
|
||||
$(QT_MOC) $< > $@
|
||||
|
||||
TEST_LIBS=$(DBUS_QTESTLIB_LIBS) $(top_builddir)/qt/libdbus-qt4-1.la
|
||||
|
||||
qdbusconnection_LDADD=$(TEST_LIBS)
|
||||
LDADD=$(TEST_LIBS)
|
||||
|
||||
CLEANFILES=tst_qdbusconnection.moc
|
||||
|
|
|
|||
78
test/qt/tst_hal.cpp
Normal file
78
test/qt/tst_hal.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include <qcoreapplication.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <dbus/qdbus.h>
|
||||
|
||||
class tst_Hal: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void getDevices();
|
||||
void lock();
|
||||
};
|
||||
|
||||
class Spy: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
int count;
|
||||
QDBusConnection conn;
|
||||
|
||||
Spy(QDBusConnection c) : count(0), conn(c)
|
||||
{ }
|
||||
|
||||
public slots:
|
||||
void spySlot(int, const QVariantList&)
|
||||
{
|
||||
++count;
|
||||
QDBusMessage msg = QDBusMessage::methodCall("org.freedesktop.Hal",
|
||||
"/org/freedesktop/Hal/devices/acpi_CPU0",
|
||||
"org.freedesktop.Hal.Device", "GetProperty");
|
||||
msg << "info.locked";
|
||||
|
||||
QDBusMessage reply = conn.sendWithReply(msg);
|
||||
QVERIFY(!reply.isEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void tst_Hal::getDevices()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SystemBus);
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusMessage msg = QDBusMessage::methodCall("org.freedesktop.Hal",
|
||||
"/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
|
||||
"GetAllDevices");
|
||||
|
||||
QDBusMessage reply = con.sendWithReply(msg);
|
||||
QVERIFY(!reply.isEmpty());
|
||||
qDebug() << reply;
|
||||
}
|
||||
|
||||
void tst_Hal::lock()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SystemBus);
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
Spy spy( con );
|
||||
|
||||
con.connect("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/acpi_CPU0",
|
||||
"org.freedesktop.Hal.Device", "PropertyModified",
|
||||
&spy, SLOT(spySlot(int, QVariantList)));
|
||||
QDBusMessage msg = QDBusMessage::methodCall("org.freedesktop.Hal",
|
||||
"/org/freedesktop/Hal/devices/acpi_CPU0", "org.freedesktop.Hal.Device",
|
||||
"Lock");
|
||||
msg << "No reason...";
|
||||
|
||||
QDBusMessage reply = con.sendWithReply(msg);
|
||||
qDebug() << reply;
|
||||
QCOMPARE(spy.count, 3);
|
||||
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Hal)
|
||||
|
||||
#include "tst_hal.moc"
|
||||
|
|
@ -10,11 +10,19 @@ class tst_QDBusConnection: public QObject
|
|||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void cleanupTestCase();
|
||||
void addConnection();
|
||||
void connect();
|
||||
void send();
|
||||
void sendAsync();
|
||||
void sendSignal();
|
||||
void requestName_data();
|
||||
void requestName();
|
||||
void getNameOwner_data();
|
||||
void getNameOwner();
|
||||
void releaseName_data();
|
||||
void releaseName();
|
||||
};
|
||||
|
||||
class QDBusSpy: public QObject
|
||||
|
|
@ -29,10 +37,25 @@ 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::addConnection(
|
||||
QDBusConnection::SessionBus);
|
||||
QDBusConnection con;
|
||||
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
|
|
@ -47,8 +70,7 @@ void tst_QDBusConnection::sendSignal()
|
|||
|
||||
void tst_QDBusConnection::send()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(
|
||||
QDBusConnection::SessionBus);
|
||||
QDBusConnection con;
|
||||
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
|
|
@ -64,7 +86,7 @@ void tst_QDBusConnection::send()
|
|||
|
||||
void tst_QDBusConnection::sendAsync()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus);
|
||||
QDBusConnection con;
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusSpy spy;
|
||||
|
|
@ -85,10 +107,9 @@ void tst_QDBusConnection::connect()
|
|||
{
|
||||
QDBusSpy spy;
|
||||
|
||||
QDBusConnection con = QDBusConnection::addConnection(
|
||||
QDBusConnection::SessionBus);
|
||||
QDBusConnection con;
|
||||
|
||||
con.connect("/org/kde/selftest", "org.kde.selftest", "ping", &spy,
|
||||
con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
|
||||
SLOT(handlePing(QString)));
|
||||
|
||||
QDBusMessage msg = QDBusMessage::signal("/org/kde/selftest", "org.kde.selftest",
|
||||
|
|
@ -158,6 +179,89 @@ void tst_QDBusConnection::addConnection()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::requestName_data()
|
||||
{
|
||||
QTest::addColumn<QString>("requestedName");
|
||||
QTest::addColumn<int>("flags");
|
||||
QTest::addColumn<bool>("expectedResult");
|
||||
|
||||
QTest::newRow("null") << QString() << (int)QDBusConnection::NoReplace << false;
|
||||
QTest::newRow("empty") << QString("") << (int)QDBusConnection::NoReplace << false;
|
||||
QTest::newRow("invalid") << "./invalid name" << (int)QDBusConnection::NoReplace << false;
|
||||
// QTest::newRow("existing") << "org.freedesktop.DBus"
|
||||
// << (int)QDBusConnection::NoReplace << false;
|
||||
|
||||
QTest::newRow("ok1") << "com.trolltech.QtDBUS.tst_qdbusconnection"
|
||||
<< (int)QDBusConnection::NoReplace << true;
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::requestName()
|
||||
{
|
||||
QDBusConnection con;
|
||||
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QFETCH(QString, requestedName);
|
||||
QFETCH(int, flags);
|
||||
QFETCH(bool, expectedResult);
|
||||
|
||||
bool result = con.requestName(requestedName, (QDBusConnection::NameRequestMode)flags);
|
||||
|
||||
// QEXPECT_FAIL("existing", "For whatever reason, the bus lets us replace this name", Abort);
|
||||
QCOMPARE(result, expectedResult);
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::getNameOwner_data()
|
||||
{
|
||||
QTest::addColumn<QString>("name");
|
||||
QTest::addColumn<QString>("expectedResult");
|
||||
|
||||
QTest::newRow("null") << QString() << QString();
|
||||
QTest::newRow("empty") << QString("") << QString();
|
||||
|
||||
QTest::newRow("invalid") << ".invalid" << QString();
|
||||
QTest::newRow("non-existent") << "com.trolltech.QtDBUS.foo" << QString();
|
||||
|
||||
QTest::newRow("bus") << "org.freedesktop.DBus" << "org.freedesktop.DBus";
|
||||
|
||||
QString base = QDBusConnection().baseService();
|
||||
QTest::newRow("address") << base << base;
|
||||
QTest::newRow("self") << "com.trolltech.QtDBUS.tst_qdbusconnection" << base;
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::getNameOwner()
|
||||
{
|
||||
QFETCH(QString, name);
|
||||
QFETCH(QString, expectedResult);
|
||||
|
||||
QDBusConnection con;
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QString result = con.getNameOwner(name);
|
||||
|
||||
QCOMPARE(result, expectedResult);
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::releaseName_data()
|
||||
{
|
||||
requestName_data();
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::releaseName()
|
||||
{
|
||||
QDBusConnection con;
|
||||
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QFETCH(QString, requestedName);
|
||||
//QFETCH(int, flags);
|
||||
QFETCH(bool, expectedResult);
|
||||
|
||||
bool result = con.releaseName(requestedName);
|
||||
|
||||
QCOMPARE(result, expectedResult);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusConnection)
|
||||
|
||||
#include "tst_qdbusconnection.moc"
|
||||
|
|
|
|||
325
test/qt/tst_qdbusinterface.cpp
Normal file
325
test/qt/tst_qdbusinterface.cpp
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include <qcoreapplication.h>
|
||||
#include <qmetatype.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <dbus/qdbus.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QVariantList)
|
||||
|
||||
#define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject"
|
||||
#define TEST_SERVICE_NAME "com.trolltech.QtDBus.tst_qdbusinterface"
|
||||
#define TEST_SIGNAL_NAME "somethingHappened"
|
||||
|
||||
const char introspectionData[] =
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||
"<node>"
|
||||
|
||||
"<interface name=\"org.freedesktop.DBus.Introspectable\">"
|
||||
"<method name=\"Introspect\">"
|
||||
"<arg name=\"data\" direction=\"out\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"</interface>"
|
||||
|
||||
"<interface name=\"" TEST_INTERFACE_NAME "\">"
|
||||
"<method name=\"ping\">"
|
||||
"<arg name=\"ping\" direction=\"in\" type=\"v\"/>"
|
||||
"<arg name=\"pong\" direction=\"out\" type=\"v\"/>"
|
||||
"</method>"
|
||||
"<method name=\"ping\">"
|
||||
"<arg name=\"ping1\" direction=\"in\" type=\"v\"/>"
|
||||
"<arg name=\"ping2\" direction=\"in\" type=\"v\"/>"
|
||||
"<arg name=\"pong1\" direction=\"out\" type=\"v\"/>"
|
||||
"<arg name=\"pong2\" direction=\"out\" type=\"v\"/>"
|
||||
"</method>"
|
||||
"<signal name=\"" TEST_SIGNAL_NAME "\">"
|
||||
"<arg type=\"s\"/>"
|
||||
"</signal>"
|
||||
"<property name=\"prop1\" access=\"readwrite\" type=\"i\" />"
|
||||
"</interface>"
|
||||
"<node name=\"subObject\"/>"
|
||||
"</node>";
|
||||
|
||||
class MyObject: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
|
||||
void ping(const QDBusMessage &msg)
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus);
|
||||
QDBusMessage reply = QDBusMessage::methodReply(msg);
|
||||
reply << static_cast<QList<QVariant> >(msg);
|
||||
if (!con.send(reply))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void Introspect(const QDBusMessage &msg)
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus);
|
||||
QDBusMessage reply = QDBusMessage::methodReply(msg);
|
||||
reply << ::introspectionData;
|
||||
if (!con.send(reply))
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
class Spy: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QString received;
|
||||
int count;
|
||||
|
||||
Spy() : count(0)
|
||||
{ }
|
||||
|
||||
public slots:
|
||||
void spySlot(const QString& arg)
|
||||
{
|
||||
received = arg;
|
||||
++count;
|
||||
}
|
||||
};
|
||||
|
||||
// helper function
|
||||
void emitSignal(const QString &interface, const QString &name, const QString &arg)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::signal("/", interface, name);
|
||||
msg << arg;
|
||||
QDBusConnection().send(msg);
|
||||
|
||||
QTest::qWait(200);
|
||||
}
|
||||
|
||||
class tst_QDBusInterface: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MyObject obj;
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
void call_data();
|
||||
void call();
|
||||
|
||||
void introspect_data();
|
||||
void introspect();
|
||||
|
||||
void signal();
|
||||
};
|
||||
|
||||
void tst_QDBusInterface::initTestCase()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::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());
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::call_data()
|
||||
{
|
||||
QTest::addColumn<QString>("method");
|
||||
QTest::addColumn<QVariantList>("input");
|
||||
QTest::addColumn<QVariantList>("output");
|
||||
|
||||
QVariantList input;
|
||||
QTest::newRow("empty") << "ping" << input << input;
|
||||
|
||||
input << qVariantFromValue(1);
|
||||
QTest::newRow("int") << "ping" << input << input;
|
||||
QTest::newRow("int-int") << "ping.i" << input << input;
|
||||
QTest::newRow("int-int16") << "ping.n" << input << input;
|
||||
|
||||
// try doing some conversions
|
||||
QVariantList output;
|
||||
output << qVariantFromValue(1U);
|
||||
QTest::newRow("int-uint") << "ping.u" << input << output;
|
||||
QTest::newRow("int-uint16") << "ping.q" << input << output;
|
||||
|
||||
QTest::newRow("int-int64") << "ping.x" << input << (QVariantList() << qVariantFromValue(1LL));
|
||||
QTest::newRow("int-uint64") << "ping.t" << input << (QVariantList() << qVariantFromValue(1ULL));
|
||||
QTest::newRow("int-double") << "ping.d" << input << (QVariantList() << qVariantFromValue(1.0));
|
||||
|
||||
output.clear();
|
||||
output << QString("1");
|
||||
QTest::newRow("int-string") << "ping.s" << input << output;
|
||||
|
||||
// try from string now
|
||||
input = output;
|
||||
QTest::newRow("string") << "ping" << input << output;
|
||||
QTest::newRow("string-string") << "ping.s" << input << output;
|
||||
|
||||
output.clear();
|
||||
output << qVariantFromValue(1);
|
||||
QTest::newRow("string-int") << "ping.i" << input << input;
|
||||
QTest::newRow("string-int16") << "ping.n" << input << input;
|
||||
|
||||
output.clear();
|
||||
output << qVariantFromValue(1U);
|
||||
QTest::newRow("string-uint") << "ping.u" << input << output;
|
||||
QTest::newRow("string-uint16") << "ping.q" << input << output;
|
||||
|
||||
QTest::newRow("string-int64") << "ping.x" << input << (QVariantList() << qVariantFromValue(1LL));
|
||||
QTest::newRow("string-uint64") << "ping.t" << input << (QVariantList() << qVariantFromValue(1ULL));
|
||||
QTest::newRow("string-double") << "ping.d" << input << (QVariantList() << qVariantFromValue(1.0));
|
||||
|
||||
// two args (must be strings!)
|
||||
input.clear();
|
||||
input << QString("Hello") << QString("World");
|
||||
output = input;
|
||||
QTest::newRow("two-strings") << "ping" << input << output;
|
||||
QTest::newRow("two-strings") << "ping.ss" << input << output;
|
||||
|
||||
// this should drop one of the arguments
|
||||
output.removeLast();
|
||||
QTest::newRow("last-dropped") << "ping.s" << input << output;
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::call()
|
||||
{
|
||||
QDBusConnection con;
|
||||
QDBusInterface iface(con, con.baseService(), QLatin1String("/"),
|
||||
TEST_INTERFACE_NAME);
|
||||
|
||||
QFETCH(QString, method);
|
||||
QFETCH(QVariantList, input);
|
||||
QFETCH(QVariantList, output);
|
||||
|
||||
QDBusMessage reply;
|
||||
// try first callWithArgs:
|
||||
reply = iface.callWithArgs(method, input);
|
||||
|
||||
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
||||
if (!output.isEmpty()) {
|
||||
QCOMPARE(reply.count(), output.count());
|
||||
QCOMPARE(static_cast<QVariantList>(reply), output);
|
||||
}
|
||||
|
||||
// try the template methods
|
||||
if (input.isEmpty())
|
||||
reply = iface.call(method);
|
||||
else if (input.count() == 1)
|
||||
switch (input.at(0).type())
|
||||
{
|
||||
case QVariant::Int:
|
||||
reply = iface.call(method, input.at(0).toInt());
|
||||
break;
|
||||
|
||||
case QVariant::UInt:
|
||||
reply = iface.call(method, input.at(0).toUInt());
|
||||
break;
|
||||
|
||||
case QVariant::String:
|
||||
reply = iface.call(method, input.at(0).toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
QFAIL("Unknown type. Please update the test case");
|
||||
break;
|
||||
}
|
||||
else
|
||||
reply = iface.call(method, input.at(0).toString(), input.at(1).toString());
|
||||
|
||||
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
||||
if (!output.isEmpty()) {
|
||||
QCOMPARE(reply.count(), output.count());
|
||||
QCOMPARE(static_cast<QVariantList>(reply), output);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::introspect_data()
|
||||
{
|
||||
QTest::addColumn<QString>("service");
|
||||
QTest::newRow("base") << QDBusConnection().baseService();
|
||||
QTest::newRow("name") << TEST_SERVICE_NAME;
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::introspect()
|
||||
{
|
||||
QFETCH(QString, service);
|
||||
QDBusConnection con;
|
||||
QDBusInterface iface(con, service, QLatin1String("/"),
|
||||
TEST_INTERFACE_NAME);
|
||||
|
||||
QDBusIntrospection::Methods mm = iface.methodData();
|
||||
QVERIFY(mm.count() == 2);
|
||||
|
||||
QDBusIntrospection::Signals sm = iface.signalData();
|
||||
QVERIFY(sm.count() == 1);
|
||||
QVERIFY(sm.contains(TEST_SIGNAL_NAME));
|
||||
|
||||
QDBusIntrospection::Properties pm = iface.propertyData();
|
||||
QVERIFY(pm.count() == 1);
|
||||
QVERIFY(pm.contains("prop1"));
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::signal()
|
||||
{
|
||||
QDBusConnection con;
|
||||
QDBusInterface iface(con, con.baseService(), QLatin1String("/"),
|
||||
TEST_INTERFACE_NAME);
|
||||
|
||||
QString signalName = TEST_SIGNAL_NAME;
|
||||
|
||||
QString arg = "So long and thanks for all the fish";
|
||||
{
|
||||
Spy spy;
|
||||
iface.connect(signalName, &spy, SLOT(spySlot(QString)));
|
||||
|
||||
emitSignal(TEST_INTERFACE_NAME, signalName, arg);
|
||||
QVERIFY(spy.count == 1);
|
||||
QCOMPARE(spy.received, arg);
|
||||
}
|
||||
|
||||
QDBusIntrospection::Signals sm = iface.signalData();
|
||||
QVERIFY(sm.contains(signalName));
|
||||
|
||||
const QDBusIntrospection::Signal& signal = sm.value(signalName);
|
||||
QCOMPARE(signal.name, signalName);
|
||||
QVERIFY(!signal.outputArgs.isEmpty());
|
||||
{
|
||||
Spy spy;
|
||||
iface.connect(signal, &spy, SLOT(spySlot(QString)));
|
||||
|
||||
emitSignal(TEST_INTERFACE_NAME, signalName, arg);
|
||||
QVERIFY(spy.count == 1);
|
||||
QCOMPARE(spy.received, arg);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusInterface)
|
||||
|
||||
#include "tst_qdbusinterface.moc"
|
||||
|
||||
198
test/qt/tst_qdbusobject.cpp
Normal file
198
test/qt/tst_qdbusobject.cpp
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include <qcoreapplication.h>
|
||||
#include <qmetatype.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <dbus/qdbus.h>
|
||||
|
||||
const char introspectionData[] =
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||
"<node>"
|
||||
|
||||
"<interface name=\"org.freedesktop.DBus.Introspectable\">"
|
||||
"<method name=\"Introspect\">"
|
||||
"<arg name=\"data\" direction=\"out\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"</interface>"
|
||||
|
||||
"<interface name=\"com.trolltech.tst_qdbusobject.MyObject\">"
|
||||
"<method name=\"ping\">"
|
||||
"<arg name=\"ping\" direction=\"in\" type=\"v\"/>"
|
||||
"<arg name=\"pong\" direction=\"out\" type=\"v\"/>"
|
||||
"</method>"
|
||||
"</interface>"
|
||||
"<node name=\"subObject\"/>"
|
||||
"</node>";
|
||||
|
||||
class MyObject: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
|
||||
void ping(const QDBusMessage &msg)
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus);
|
||||
QDBusMessage reply = QDBusMessage::methodReply(msg);
|
||||
reply << static_cast<QList<QVariant> >(msg);
|
||||
if (!con.send(reply))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void Introspect(const QDBusMessage &msg)
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::SessionBus);
|
||||
QDBusMessage reply = QDBusMessage::methodReply(msg);
|
||||
reply << ::introspectionData;
|
||||
if (!con.send(reply))
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
class tst_QDBusObject: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MyObject obj;
|
||||
|
||||
private slots:
|
||||
void initTestCase(); // connect to D-Bus
|
||||
void cleanupTestCase(); // disconnect from D-Bus
|
||||
|
||||
void construction_data();
|
||||
void construction();
|
||||
|
||||
void introspection_data();
|
||||
void introspection();
|
||||
};
|
||||
|
||||
void tst_QDBusObject::initTestCase()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::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());
|
||||
}
|
||||
|
||||
void tst_QDBusObject::construction_data()
|
||||
{
|
||||
QTest::addColumn<QString>("service");
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<bool>("isValid");
|
||||
QTest::addColumn<bool>("exists");
|
||||
|
||||
QTest::newRow("null") << QString() << QString() << false << false;
|
||||
|
||||
QTest::newRow("invalid1") << "foo.foo1" << "" << false << false;
|
||||
QTest::newRow("invalid2") << "foo.foo1" << "foo.bar" << false << false;
|
||||
QTest::newRow("invalid3") << "foo.foo1" << "/foo.bar" << false << false;
|
||||
QTest::newRow("invalid4") << "" << "/" << false << false;
|
||||
QTest::newRow("invalid5") << "foo" << "/" << false << false;
|
||||
QTest::newRow("invalid6") << ".foo" << "/" << false << false;
|
||||
|
||||
QTest::newRow("invalid7") << "org.freedesktop.DBus" << "" << false << false;
|
||||
QTest::newRow("invalid8") << "org.freedesktop.DBus" << "foo.bar" << false << false;
|
||||
QTest::newRow("invalid9") << "org.freedesktop.DBus" << "/foo.bar" << false << false;
|
||||
|
||||
QTest::newRow("existing") << "org.freedesktop.DBus" << "/" << true << true;
|
||||
QTest::newRow("non-existing") << "org.freedesktop.DBus" << "/foo" << true << false;
|
||||
}
|
||||
|
||||
void tst_QDBusObject::construction()
|
||||
{
|
||||
QDBusConnection con; // default
|
||||
|
||||
QFETCH(QString, service);
|
||||
QFETCH(QString, path);
|
||||
QFETCH(bool, isValid);
|
||||
//QFETCH(bool, exists);
|
||||
|
||||
QDBusObject o(con, service, path);
|
||||
QCOMPARE(o.isValid(), isValid);
|
||||
|
||||
if (isValid) {
|
||||
QCOMPARE(o.service(), service);
|
||||
QCOMPARE(o.path(), path);
|
||||
}
|
||||
else {
|
||||
QVERIFY(o.service().isNull());
|
||||
QVERIFY(o.path().isNull());
|
||||
}
|
||||
|
||||
//QCOMPARE(o.exists(), exists);
|
||||
}
|
||||
|
||||
void tst_QDBusObject::introspection_data()
|
||||
{
|
||||
QTest::addColumn<QString>("service");
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<QStringList>("interfaces");
|
||||
|
||||
QStringList interfaces;
|
||||
QTest::newRow("nowhere") << QString() << QString() << interfaces;
|
||||
|
||||
// IMPORTANT!
|
||||
// Keep the interface list sorted!
|
||||
interfaces << "org.freedesktop.DBus" << DBUS_INTERFACE_INTROSPECTABLE;
|
||||
QTest::newRow("server") << "org.freedesktop.DBus" << "/" << interfaces;
|
||||
|
||||
QDBusConnection con;
|
||||
interfaces.clear();
|
||||
interfaces << "com.trolltech.tst_qdbusobject.MyObject" << DBUS_INTERFACE_INTROSPECTABLE;
|
||||
|
||||
QTest::newRow("self1") << con.baseService() << "/" << interfaces;
|
||||
QTest::newRow("self2") << "com.trolltech.tst_qdbusobject" << "/" << interfaces;
|
||||
}
|
||||
|
||||
void tst_QDBusObject::introspection()
|
||||
{
|
||||
QDBusConnection con;
|
||||
|
||||
QFETCH(QString, service);
|
||||
QFETCH(QString, path);
|
||||
|
||||
QDBusObject o(con, service, path);
|
||||
|
||||
if (!o.isValid())
|
||||
QVERIFY(o.introspect().isEmpty());
|
||||
else {
|
||||
QFETCH(QStringList, interfaces);
|
||||
QStringList parsed = o.interfaces();
|
||||
parsed.sort();
|
||||
QCOMPARE(parsed.count(), interfaces.count());
|
||||
QCOMPARE(parsed, interfaces);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusObject)
|
||||
|
||||
#include "tst_qdbusobject.moc"
|
||||
|
||||
272
test/qt/tst_qdbustype.cpp
Normal file
272
test/qt/tst_qdbustype.cpp
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include <qcoreapplication.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <dbus/qdbus.h>
|
||||
|
||||
class tst_QDBusType: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void fromType_data();
|
||||
void fromType();
|
||||
void fromSignature_data();
|
||||
void fromSignature();
|
||||
void arrayOf_data();
|
||||
void arrayOf();
|
||||
void mapOf_data();
|
||||
void mapOf();
|
||||
};
|
||||
|
||||
inline QTestData &operator<<(QTestData &data, QVariant::Type t)
|
||||
{
|
||||
return data << int(t);
|
||||
}
|
||||
|
||||
void tst_QDBusType::fromType_data()
|
||||
{
|
||||
fromSignature_data();
|
||||
}
|
||||
|
||||
void tst_QDBusType:: arrayOf_data()
|
||||
{
|
||||
fromSignature_data();
|
||||
}
|
||||
|
||||
void tst_QDBusType::mapOf_data()
|
||||
{
|
||||
fromSignature_data();
|
||||
}
|
||||
|
||||
void tst_QDBusType::fromSignature_data()
|
||||
{
|
||||
QTest::addColumn<QString>("signature");
|
||||
QTest::addColumn<char>("type");
|
||||
QTest::addColumn<int>("qvariantType");
|
||||
QTest::addColumn<bool>("isValid");
|
||||
QTest::addColumn<bool>("isBasic");
|
||||
QTest::addColumn<bool>("isContainer");
|
||||
QTest::addColumn<int>("subtypeCount");
|
||||
|
||||
QTest::newRow("null") << QString() << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("empty") << QString("") << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("invalid") << QString("~") << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
|
||||
// integers:
|
||||
QTest::newRow("byte") << "y" << 'y' << QVariant::UInt << true << true << false << 0;
|
||||
QTest::newRow("boolean") << "b" << 'b' << QVariant::Bool << true << true << false << 0;
|
||||
QTest::newRow("int16") << "n" << 'n' << QVariant::Int << true << true << false << 0;
|
||||
QTest::newRow("uint16") << "q" << 'q' << QVariant::UInt << true << true << false << 0;
|
||||
QTest::newRow("int32") << "i" << 'i' << QVariant::Int << true << true << false << 0;
|
||||
QTest::newRow("uint32") << "u" << 'u' << QVariant::UInt << true << true << false << 0;
|
||||
QTest::newRow("int64") << "x" << 'x' << QVariant::LongLong << true << true << false << 0;
|
||||
QTest::newRow("uint64") << "t" << 't' << QVariant::ULongLong << true << true << false << 0;
|
||||
|
||||
// double:
|
||||
QTest::newRow("double") << "d" << 'd' << QVariant::Double << true << true << false << 0;
|
||||
|
||||
// string types:
|
||||
QTest::newRow("string") << "s" << 's' << QVariant::String << true << true << false << 0;
|
||||
QTest::newRow("objpath") << "o" << 'o' << QVariant::String << true << true << false << 0;
|
||||
QTest::newRow("signature")<<"g" << 'g' << QVariant::String << true << true << false << 0;
|
||||
|
||||
// variant
|
||||
QTest::newRow("variant") << "v" << 'v' << QVariant::UserType << true << false << true << 0;
|
||||
|
||||
// compound types:
|
||||
QTest::newRow("struct-empty") << "()" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("struct-invalid") << "(~)" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("struct-unterminated")<< "(iii" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("struct-bad-nest") << "(i(i)((i)i)" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("struct1") << "(i)" << 'r' << QVariant::List << true << false << true << 1;
|
||||
QTest::newRow("struct2") << "(ii)" << 'r' << QVariant::List << true << false << true << 2;
|
||||
|
||||
QTest::newRow("array-empty") << "a" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("array-invalid") << "a~" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("array-simple") << "ab" << 'a' << QVariant::List << true << false << true << 1;
|
||||
QTest::newRow("bytearray") << "ay" << 'a' << QVariant::ByteArray << true << false << true << 1;
|
||||
QTest::newRow("stringlist") << "as" << 'a' << QVariant::StringList << true << false << true << 1;
|
||||
|
||||
QTest::newRow("map-empty") << "e" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid1") << "a{}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid2") << "a{~}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid3") << "a{e}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid4") << "a{i}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid5") << "a{(i)d}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid6") << "{}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-invalid7") << "{i}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
//QTest::newRow("map-invalid8") << "{is}" << '\0' << QVariant::Invalid << false << false << false << 0; // this is valid when "a" is prepended
|
||||
QTest::newRow("map-bad-nesting") << "a{i(s}" << '\0' << QVariant::Invalid << false << false << false << 0;
|
||||
QTest::newRow("map-ok1") << "a{is}" << 'a' << QVariant::Map << true << false << true << 1;
|
||||
QTest::newRow("map-ok2") << "a{sv}" << 'a' << QVariant::Map << true << false << true << 1;
|
||||
|
||||
// compound of compounds:
|
||||
QTest::newRow("struct-struct") << "((i))" << 'r' << QVariant::List << true << false << true << 1;
|
||||
QTest::newRow("struct-structs") << "((ii)d(i))" << 'r' << QVariant::List << true << false << true << 3;
|
||||
QTest::newRow("map-struct") << "a{s(ii)}" << 'a' << QVariant::Map << true << false << true << 1;
|
||||
QTest::newRow("map-stringlist") << "a{sas}" << 'a' << QVariant::Map << true << false << true << 1;
|
||||
QTest::newRow("map-map") << "a{ia{sv}}" << 'a' << QVariant::Map << true << false << true << 1;
|
||||
QTest::newRow("array-struct") << "a(ii)" << 'a' << QVariant::List << true << false << true << 1;
|
||||
QTest::newRow("array-array") << "aai" << 'a' << QVariant::List << true << false << true << 1;
|
||||
QTest::newRow("array-map") << "aa{sv}" << 'a' << QVariant::List << true << false << true << 1;
|
||||
}
|
||||
|
||||
void tst_QDBusType::fromType()
|
||||
{
|
||||
QFETCH(QString, signature);
|
||||
if (signature.length() != 1)
|
||||
// can't transform to typecode
|
||||
return;
|
||||
|
||||
QFETCH(char, type);
|
||||
QFETCH(int, qvariantType);
|
||||
QFETCH(bool, isValid);
|
||||
QFETCH(bool, isBasic);
|
||||
QFETCH(bool, isContainer);
|
||||
|
||||
QDBusType t(signature.at(0).toLatin1());
|
||||
|
||||
QCOMPARE((char)t.dbusType(), type);
|
||||
QCOMPARE(t.qvariantType(), QVariant::Type(qvariantType));
|
||||
QCOMPARE(t.isValid(), isValid);
|
||||
QCOMPARE(t.isBasic(), isBasic);
|
||||
QCOMPARE(t.isContainer(), isContainer);
|
||||
}
|
||||
|
||||
void tst_QDBusType::fromSignature()
|
||||
{
|
||||
QFETCH(QString, signature);
|
||||
QFETCH(char, type);
|
||||
QFETCH(int, qvariantType);
|
||||
QFETCH(bool, isValid);
|
||||
QFETCH(bool, isBasic);
|
||||
QFETCH(bool, isContainer);
|
||||
QFETCH(int, subtypeCount);
|
||||
|
||||
QDBusType t(signature);
|
||||
|
||||
QCOMPARE((char)t.dbusType(), type);
|
||||
QCOMPARE(t.qvariantType(), QVariant::Type(qvariantType));
|
||||
QCOMPARE(t.isValid(), isValid);
|
||||
QCOMPARE(t.isBasic(), isBasic);
|
||||
QCOMPARE(t.isContainer(), isContainer);
|
||||
|
||||
if (isValid)
|
||||
QCOMPARE(QLatin1String(t.dbusSignature()), signature);
|
||||
|
||||
QCOMPARE(t.subTypes().count(), subtypeCount);
|
||||
}
|
||||
|
||||
void tst_QDBusType::arrayOf()
|
||||
{
|
||||
QFETCH(QString, signature);
|
||||
QFETCH(char, type);
|
||||
QFETCH(int, qvariantType);
|
||||
QFETCH(bool, isValid);
|
||||
QFETCH(bool, isBasic);
|
||||
QFETCH(bool, isContainer);
|
||||
QFETCH(int, subtypeCount);
|
||||
|
||||
QDBusType arr("a" + signature.toLatin1());
|
||||
QCOMPARE(arr.isValid(), isValid);
|
||||
QVERIFY(!arr.isBasic());
|
||||
|
||||
if (isValid) {
|
||||
QVERIFY(arr.isContainer());
|
||||
QVERIFY(arr.isArray());
|
||||
QCOMPARE((char)arr.dbusType(), 'a');
|
||||
QCOMPARE(arr.subTypes().count(), 1);
|
||||
|
||||
// handle special cases:
|
||||
if (type == 'y')
|
||||
QCOMPARE(arr.qvariantType(), QVariant::ByteArray);
|
||||
else if (type == 's' || type == 'o' || type == 'g')
|
||||
QCOMPARE(arr.qvariantType(), QVariant::StringList);
|
||||
else
|
||||
QCOMPARE(arr.qvariantType(), QVariant::List);
|
||||
|
||||
// handle the array element now:
|
||||
QDBusType t = arr.arrayElement();
|
||||
|
||||
QCOMPARE((char)t.dbusType(), type);
|
||||
QCOMPARE(t.qvariantType(), QVariant::Type(qvariantType));
|
||||
QCOMPARE(t.isValid(), isValid);
|
||||
QCOMPARE(t.isBasic(), isBasic);
|
||||
QCOMPARE(t.isContainer(), isContainer);
|
||||
|
||||
QCOMPARE(QLatin1String(t.dbusSignature()), signature);
|
||||
|
||||
QCOMPARE(t.subTypes().count(), subtypeCount);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusType::mapOf()
|
||||
{
|
||||
QFETCH(QString, signature);
|
||||
QFETCH(char, type);
|
||||
QFETCH(int, qvariantType);
|
||||
QFETCH(bool, isValid);
|
||||
QFETCH(bool, isBasic);
|
||||
QFETCH(bool, isContainer);
|
||||
QFETCH(int, subtypeCount);
|
||||
|
||||
QDBusType map("a{s" + signature.toLatin1() + '}');
|
||||
QCOMPARE(map.isValid(), isValid);
|
||||
QVERIFY(!map.isBasic());
|
||||
|
||||
if (isValid) {
|
||||
QVERIFY(map.isContainer());
|
||||
QVERIFY(map.isArray());
|
||||
QVERIFY(map.isMap());
|
||||
QCOMPARE((char)map.dbusType(), 'a');
|
||||
QCOMPARE(map.subTypes().count(), 1);
|
||||
|
||||
// handle the array element now:
|
||||
QDBusType dict_entry = map.arrayElement();
|
||||
QVERIFY(dict_entry.isValid());
|
||||
QVERIFY(dict_entry.isContainer());
|
||||
QVERIFY(!dict_entry.isMap());
|
||||
QVERIFY(!dict_entry.isArray());
|
||||
|
||||
QVERIFY(map.mapKey().isBasic());
|
||||
|
||||
// handle the value:
|
||||
QDBusType t = map.mapValue();
|
||||
|
||||
QCOMPARE((char)t.dbusType(), type);
|
||||
QCOMPARE(t.qvariantType(), QVariant::Type(qvariantType));
|
||||
QCOMPARE(t.isValid(), isValid);
|
||||
QCOMPARE(t.isBasic(), isBasic);
|
||||
QCOMPARE(t.isContainer(), isContainer);
|
||||
|
||||
QCOMPARE(QLatin1String(t.dbusSignature()), signature);
|
||||
|
||||
QCOMPARE(t.subTypes().count(), subtypeCount);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusType)
|
||||
|
||||
#include "tst_qdbustype.moc"
|
||||
709
test/qt/tst_qdbusxmlparser.cpp
Normal file
709
test/qt/tst_qdbusxmlparser.cpp
Normal file
|
|
@ -0,0 +1,709 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include <qcoreapplication.h>
|
||||
#include <qmetatype.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <dbus/qdbus.h>
|
||||
|
||||
class tst_QDBusXmlParser: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
void parsing_common(const QString&);
|
||||
|
||||
private slots:
|
||||
void parsing_data();
|
||||
void parsing();
|
||||
void parsingWithDoctype_data();
|
||||
void parsingWithDoctype();
|
||||
|
||||
void objectWithContent_data();
|
||||
void objectWithContent();
|
||||
|
||||
void methods_data();
|
||||
void methods();
|
||||
void signals__data();
|
||||
void signals_();
|
||||
void properties_data();
|
||||
void properties();
|
||||
};
|
||||
|
||||
// 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");
|
||||
QTest::addColumn<int>("interfaceCount");
|
||||
QTest::addColumn<int>("objectCount");
|
||||
|
||||
QTest::newRow("null") << QString() << 0 << 0;
|
||||
QTest::newRow("empty") << QString("") << 0 << 0;
|
||||
|
||||
QTest::newRow("junk") << "<junk/>" << 0 << 0;
|
||||
QTest::newRow("interface-inside-junk") << "<junk><interface name=\"iface.iface1\" /></junk>"
|
||||
<< 0 << 0;
|
||||
QTest::newRow("object-inside-junk") << "<junk><node name=\"obj1\" /></junk>"
|
||||
<< 0 << 0;
|
||||
|
||||
QTest::newRow("zero-interfaces") << "<node/>" << 0 << 0;
|
||||
QTest::newRow("one-interface") << "<node><interface name=\"iface.iface1\" /></node>" << 1 << 0;
|
||||
|
||||
|
||||
QTest::newRow("two-interfaces") << "<node><interface name=\"iface.iface1\" />"
|
||||
"<interface name=\"iface.iface2\"></node>"
|
||||
<< 2 << 0;
|
||||
|
||||
|
||||
QTest::newRow("one-object") << "<node><node name=\"obj1\"/></node>" << 0 << 1;
|
||||
QTest::newRow("two-objects") << "<node><node name=\"obj1\"/><node name=\"obj2\"></node>" << 0 << 2;
|
||||
|
||||
QTest::newRow("i1o1") << "<node><interface name=\"iface.iface1\"><node name=\"obj1\"></node>" << 1 << 1;
|
||||
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::parsing_common(const QString &xmlData)
|
||||
{
|
||||
QDBusIntrospection::ObjectTree obj =
|
||||
QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
|
||||
QFETCH(int, interfaceCount);
|
||||
QFETCH(int, objectCount);
|
||||
QCOMPARE(obj.interfaces.count(), interfaceCount);
|
||||
QCOMPARE(obj.childObjects.count(), objectCount);
|
||||
|
||||
// also verify the naming
|
||||
int i = 0;
|
||||
foreach (QString name, obj.interfaces)
|
||||
QCOMPARE(name, QString("iface.iface%1").arg(++i));
|
||||
|
||||
i = 0;
|
||||
foreach (QString name, obj.childObjects)
|
||||
QCOMPARE(name, QString("obj%1").arg(++i));
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::parsing()
|
||||
{
|
||||
QFETCH(QString, xmlData);
|
||||
|
||||
parsing_common(xmlData);
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::parsingWithDoctype_data()
|
||||
{
|
||||
parsing_data();
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::parsingWithDoctype()
|
||||
{
|
||||
QString docType = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";
|
||||
QFETCH(QString, xmlData);
|
||||
|
||||
parsing_common(docType + xmlData);
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::objectWithContent_data()
|
||||
{
|
||||
QTest::addColumn<QString>("xmlData");
|
||||
QTest::addColumn<QString>("probedObject");
|
||||
QTest::addColumn<int>("interfaceCount");
|
||||
QTest::addColumn<int>("objectCount");
|
||||
|
||||
QTest::newRow("zero") << "<node><node name=\"obj\"/></node>" << "obj" << 0 << 0;
|
||||
|
||||
QString xmlData = "<node><node name=\"obj\">"
|
||||
"<interface name=\"iface.iface1\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("one-interface") << xmlData << "obj" << 1 << 0;
|
||||
QTest::newRow("one-interface2") << xmlData << "obj2" << 0 << 0;
|
||||
|
||||
xmlData = "<node><node name=\"obj\">"
|
||||
"<interface name=\"iface.iface1\" />"
|
||||
"<interface name=\"iface.iface2\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("two-interfaces") << xmlData << "obj" << 2 << 0;
|
||||
QTest::newRow("two-interfaces2") << xmlData << "obj2" << 0 << 0;
|
||||
|
||||
xmlData = "<node><node name=\"obj\">"
|
||||
"<interface name=\"iface.iface1\" />"
|
||||
"<interface name=\"iface.iface2\" />"
|
||||
"</node><node name=\"obj2\">"
|
||||
"<interface name=\"iface.iface1\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("two-nodes-two-interfaces") << xmlData << "obj" << 2 << 0;
|
||||
QTest::newRow("two-nodes-one-interface") << xmlData << "obj2" << 1 << 0;
|
||||
|
||||
xmlData = "<node><node name=\"obj\">"
|
||||
"<node name=\"obj1\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("one-object") << xmlData << "obj" << 0 << 1;
|
||||
QTest::newRow("one-object2") << xmlData << "obj2" << 0 << 0;
|
||||
|
||||
xmlData = "<node><node name=\"obj\">"
|
||||
"<node name=\"obj1\" />"
|
||||
"<node name=\"obj2\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("two-objects") << xmlData << "obj" << 0 << 2;
|
||||
QTest::newRow("two-objects2") << xmlData << "obj2" << 0 << 0;
|
||||
|
||||
xmlData = "<node><node name=\"obj\">"
|
||||
"<node name=\"obj1\" />"
|
||||
"<node name=\"obj2\" />"
|
||||
"</node><node name=\"obj2\">"
|
||||
"<node name=\"obj1\" />"
|
||||
"</node></node>";
|
||||
QTest::newRow("two-nodes-two-objects") << xmlData << "obj" << 0 << 2;
|
||||
QTest::newRow("two-nodes-one-object") << xmlData << "obj2" << 0 << 1;
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::objectWithContent()
|
||||
{
|
||||
QFETCH(QString, xmlData);
|
||||
QFETCH(QString, probedObject);
|
||||
|
||||
QDBusIntrospection::ObjectTree tree =
|
||||
QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
|
||||
|
||||
const ObjectMap &om = tree.childObjectData;
|
||||
|
||||
if (om.contains(probedObject)) {
|
||||
const QSharedDataPointer<QDBusIntrospection::ObjectTree>& obj = om.value(probedObject);
|
||||
QVERIFY(obj != 0);
|
||||
|
||||
QFETCH(int, interfaceCount);
|
||||
QFETCH(int, objectCount);
|
||||
|
||||
QCOMPARE(obj->interfaces.count(), interfaceCount);
|
||||
QCOMPARE(obj->childObjects.count(), objectCount);
|
||||
|
||||
// verify the object names
|
||||
int i = 0;
|
||||
foreach (QString name, obj->interfaces)
|
||||
QCOMPARE(name, QString("iface.iface%1").arg(++i));
|
||||
|
||||
i = 0;
|
||||
foreach (QString name, obj->childObjects)
|
||||
QCOMPARE(name, QString("obj%1").arg(++i));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::methods_data()
|
||||
{
|
||||
QTest::addColumn<QString>("xmlDataFragment");
|
||||
QTest::addColumn<MethodMap>("methodMap");
|
||||
|
||||
MethodMap map;
|
||||
QTest::newRow("no-methods") << QString() << map;
|
||||
|
||||
// one method without arguments
|
||||
QDBusIntrospection::Method method;
|
||||
method.name = "Foo";
|
||||
map << method;
|
||||
QTest::newRow("one-method") << "<method name=\"Foo\"/>" << map;
|
||||
|
||||
// add another method without arguments
|
||||
method.name = "Bar";
|
||||
map << method;
|
||||
QTest::newRow("two-methods") << "<method name=\"Foo\"/>"
|
||||
"<method name=\"Bar\"/>"
|
||||
<< map;
|
||||
|
||||
// invert the order of the XML declaration
|
||||
QTest::newRow("two-methods-inverse") << "<method name=\"Bar\"/>"
|
||||
"<method name=\"Foo\"/>"
|
||||
<< map;
|
||||
|
||||
// add a third, with annotations
|
||||
method.name = "Baz";
|
||||
method.annotations.insert("foo.testing", "nothing to see here");
|
||||
map << method;
|
||||
QTest::newRow("method-with-annotation") <<
|
||||
"<method name=\"Foo\"/>"
|
||||
"<method name=\"Bar\"/>"
|
||||
"<method name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></method>"
|
||||
<< map;
|
||||
|
||||
// arguments
|
||||
map.clear();
|
||||
method.annotations.clear();
|
||||
|
||||
method.name = "Method";
|
||||
method.inputArgs << arg("s");
|
||||
map << method;
|
||||
QTest::newRow("one-in") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" direction=\"in\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// two arguments
|
||||
method.inputArgs << arg("v");
|
||||
map.clear();
|
||||
map << method;
|
||||
QTest::newRow("two-in") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" direction=\"in\"/>"
|
||||
"<arg type=\"v\" direction=\"in\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// one invalid arg
|
||||
QTest::newRow("two-in-one-invalid") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" direction=\"in\"/>"
|
||||
"<arg type=\"~\" name=\"invalid\" direction=\"in\"/>" // this line should be ignored
|
||||
"<arg type=\"v\" direction=\"in\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// one out argument
|
||||
method.inputArgs.clear();
|
||||
method.outputArgs << arg("s");
|
||||
map.clear();
|
||||
map << method;
|
||||
QTest::newRow("one-out") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" direction=\"out\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// two in and one out
|
||||
method.inputArgs << arg("s") << arg("v");
|
||||
map.clear();
|
||||
map << method;
|
||||
QTest::newRow("two-in-one-out") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" direction=\"in\"/>"
|
||||
"<arg type=\"v\" direction=\"in\"/>"
|
||||
"<arg type=\"s\" direction=\"out\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// let's try an arg with name
|
||||
method.outputArgs.clear();
|
||||
method.inputArgs.clear();
|
||||
method.inputArgs << arg("s", "foo");
|
||||
map.clear();
|
||||
map << method;
|
||||
QTest::newRow("one-in-with-name") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" name=\"foo\" direction=\"in\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// two args with name
|
||||
method.inputArgs << arg("i", "bar");
|
||||
map.clear();
|
||||
map << method;
|
||||
QTest::newRow("two-in-with-name") <<
|
||||
"<method name=\"Method\">"
|
||||
"<arg type=\"s\" name=\"foo\" direction=\"in\"/>"
|
||||
"<arg type=\"i\" name=\"bar\" direction=\"in\"/>"
|
||||
"</method>" << map;
|
||||
|
||||
// one complex
|
||||
map.clear();
|
||||
method = QDBusIntrospection::Method();
|
||||
|
||||
// Method1(in STRING arg1, in BYTE arg2, out ARRAY of STRING)
|
||||
method.inputArgs << arg("s", "arg1") << arg("y", "arg2");
|
||||
method.outputArgs << arg("as");
|
||||
method.name = "Method1";
|
||||
map << method;
|
||||
|
||||
// Method2(in ARRAY of DICT_ENTRY of (STRING,VARIANT) variantMap, in UINT32 index,
|
||||
// out STRING key, out VARIANT value)
|
||||
// with annotation "foo.equivalent":"QVariantMap"
|
||||
method = QDBusIntrospection::Method();
|
||||
method.inputArgs << arg("a{sv}", "variantMap") << arg("u", "index");
|
||||
method.outputArgs << arg("s", "key") << arg("v", "value");
|
||||
method.annotations.insert("foo.equivalent", "QVariantMap");
|
||||
method.name = "Method2";
|
||||
map << method;
|
||||
|
||||
QTest::newRow("complex") <<
|
||||
"<method name=\"Method1\">"
|
||||
"<arg name=\"arg1\" type=\"s\" direction=\"in\"/>"
|
||||
"<arg name=\"arg2\" type=\"y\" direction=\"in\"/>"
|
||||
"<arg type=\"as\" direction=\"out\"/>"
|
||||
"</method>"
|
||||
"<method name=\"Method2\">"
|
||||
"<arg name=\"variantMap\" type=\"a{sv}\" direction=\"in\"/>"
|
||||
"<arg name=\"index\" type=\"u\" direction=\"in\"/>"
|
||||
"<arg name=\"key\" type=\"s\" direction=\"out\"/>"
|
||||
"<arg name=\"value\" type=\"v\" direction=\"out\"/>"
|
||||
"<annotation name=\"foo.equivalent\" value=\"QVariantMap\"/>"
|
||||
"</method>" << map;
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::methods()
|
||||
{
|
||||
QString xmlHeader = "<node>"
|
||||
"<interface name=\"iface.iface1\">",
|
||||
xmlFooter = "</interface>"
|
||||
"</node>";
|
||||
|
||||
QFETCH(QString, xmlDataFragment);
|
||||
|
||||
QDBusIntrospection::Interface iface =
|
||||
QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
|
||||
|
||||
QCOMPARE(iface.name, QString("iface.iface1"));
|
||||
|
||||
QFETCH(MethodMap, methodMap);
|
||||
MethodMap parsedMap = iface.methods;
|
||||
|
||||
QCOMPARE(methodMap.count(), parsedMap.count());
|
||||
QCOMPARE(methodMap, parsedMap);
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::signals__data()
|
||||
{
|
||||
QTest::addColumn<QString>("xmlDataFragment");
|
||||
QTest::addColumn<SignalMap>("signalMap");
|
||||
|
||||
SignalMap map;
|
||||
QTest::newRow("no-signals") << QString() << map;
|
||||
|
||||
// one signal without arguments
|
||||
QDBusIntrospection::Signal signal;
|
||||
signal.name = "Foo";
|
||||
map << signal;
|
||||
QTest::newRow("one-signal") << "<signal name=\"Foo\"/>" << map;
|
||||
|
||||
// add another signal without arguments
|
||||
signal.name = "Bar";
|
||||
map << signal;
|
||||
QTest::newRow("two-signals") << "<signal name=\"Foo\"/>"
|
||||
"<signal name=\"Bar\"/>"
|
||||
<< map;
|
||||
|
||||
// invert the order of the XML declaration
|
||||
QTest::newRow("two-signals-inverse") << "<signal name=\"Bar\"/>"
|
||||
"<signal name=\"Foo\"/>"
|
||||
<< map;
|
||||
|
||||
// add a third, with annotations
|
||||
signal.name = "Baz";
|
||||
signal.annotations.insert("foo.testing", "nothing to see here");
|
||||
map << signal;
|
||||
QTest::newRow("signal-with-annotation") <<
|
||||
"<signal name=\"Foo\"/>"
|
||||
"<signal name=\"Bar\"/>"
|
||||
"<signal name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></signal>"
|
||||
<< map;
|
||||
|
||||
// one out argument
|
||||
map.clear();
|
||||
signal.annotations.clear();
|
||||
signal.outputArgs << arg("s");
|
||||
signal.name = "Signal";
|
||||
map.clear();
|
||||
map << signal;
|
||||
QTest::newRow("one-out") <<
|
||||
"<signal name=\"Signal\">"
|
||||
"<arg type=\"s\" direction=\"out\"/>"
|
||||
"</signal>" << map;
|
||||
|
||||
// without saying which direction it is
|
||||
QTest::newRow("one-out-no-direction") <<
|
||||
"<signal name=\"Signal\">"
|
||||
"<arg type=\"s\"/>"
|
||||
"</signal>" << map;
|
||||
|
||||
// two args with name
|
||||
signal.outputArgs << arg("i", "bar");
|
||||
map.clear();
|
||||
map << signal;
|
||||
QTest::newRow("two-out-with-name") <<
|
||||
"<signal name=\"Signal\">"
|
||||
"<arg type=\"s\" direction=\"out\"/>"
|
||||
"<arg type=\"i\" name=\"bar\"/>"
|
||||
"</signal>" << map;
|
||||
|
||||
// one complex
|
||||
map.clear();
|
||||
signal = QDBusIntrospection::Signal();
|
||||
|
||||
// Signal1(out ARRAY of STRING)
|
||||
signal.outputArgs << arg("as");
|
||||
signal.name = "Signal1";
|
||||
map << signal;
|
||||
|
||||
// Signal2(out STRING key, out VARIANT value)
|
||||
// with annotation "foo.equivalent":"QVariantMap"
|
||||
signal = QDBusIntrospection::Signal();
|
||||
signal.outputArgs << arg("s", "key") << arg("v", "value");
|
||||
signal.annotations.insert("foo.equivalent", "QVariantMap");
|
||||
signal.name = "Signal2";
|
||||
map << signal;
|
||||
|
||||
QTest::newRow("complex") <<
|
||||
"<signal name=\"Signal1\">"
|
||||
"<arg type=\"as\" direction=\"out\"/>"
|
||||
"</signal>"
|
||||
"<signal name=\"Signal2\">"
|
||||
"<arg name=\"key\" type=\"s\" direction=\"out\"/>"
|
||||
"<arg name=\"value\" type=\"v\" direction=\"out\"/>"
|
||||
"<annotation name=\"foo.equivalent\" value=\"QVariantMap\"/>"
|
||||
"</signal>" << map;
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::signals_()
|
||||
{
|
||||
QString xmlHeader = "<node>"
|
||||
"<interface name=\"iface.iface1\">",
|
||||
xmlFooter = "</interface>"
|
||||
"</node>";
|
||||
|
||||
QFETCH(QString, xmlDataFragment);
|
||||
|
||||
QDBusIntrospection::Interface iface =
|
||||
QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
|
||||
|
||||
QCOMPARE(iface.name, QString("iface.iface1"));
|
||||
|
||||
QFETCH(SignalMap, signalMap);
|
||||
SignalMap parsedMap = iface.signals_;
|
||||
|
||||
QCOMPARE(signalMap.count(), parsedMap.count());
|
||||
QCOMPARE(signalMap, parsedMap);
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::properties_data()
|
||||
{
|
||||
QTest::addColumn<QString>("xmlDataFragment");
|
||||
QTest::addColumn<PropertyMap>("propertyMap");
|
||||
|
||||
PropertyMap map;
|
||||
QTest::newRow("no-signals") << QString() << map;
|
||||
|
||||
// one readable signal
|
||||
QDBusIntrospection::Property prop;
|
||||
prop.name = "foo";
|
||||
prop.type = QDBusType("s");
|
||||
prop.access = QDBusIntrospection::Property::Read;
|
||||
map << prop;
|
||||
QTest::newRow("one-readable") << "<property name=\"foo\" type=\"s\" access=\"read\"/>" << map;
|
||||
|
||||
// one writable signal
|
||||
prop.access = QDBusIntrospection::Property::Write;
|
||||
map.clear();
|
||||
map << prop;
|
||||
QTest::newRow("one-writable") << "<property name=\"foo\" type=\"s\" access=\"write\"/>" << map;
|
||||
|
||||
// one read- & writable signal
|
||||
prop.access = QDBusIntrospection::Property::ReadWrite;
|
||||
map.clear();
|
||||
map << prop;
|
||||
QTest::newRow("one-read-writable") << "<property name=\"foo\" type=\"s\" access=\"readwrite\"/>"
|
||||
<< map;
|
||||
|
||||
// two, mixed properties
|
||||
prop.name = "bar";
|
||||
prop.type = QDBusType("i");
|
||||
prop.access = QDBusIntrospection::Property::Read;
|
||||
map << prop;
|
||||
QTest::newRow("two") <<
|
||||
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>"
|
||||
"<property name=\"bar\" type=\"i\" access=\"read\"/>" << map;
|
||||
|
||||
// invert the order of the declaration
|
||||
QTest::newRow("two") <<
|
||||
"<property name=\"bar\" type=\"i\" access=\"read\"/>"
|
||||
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
|
||||
|
||||
// add a third with annotations
|
||||
prop.name = "baz";
|
||||
prop.type = QDBusType("as");
|
||||
prop.access = QDBusIntrospection::Property::Write;
|
||||
prop.annotations.insert("foo.annotation", "Hello, World");
|
||||
prop.annotations.insert("foo.annotation2", "Goodbye, World");
|
||||
map << prop;
|
||||
QTest::newRow("complex") <<
|
||||
"<property name=\"bar\" type=\"i\" access=\"read\"/>"
|
||||
"<property name=\"baz\" type=\"as\" access=\"write\">"
|
||||
"<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
|
||||
"<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
|
||||
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
|
||||
|
||||
// and now change the order
|
||||
QTest::newRow("complex2") <<
|
||||
"<property name=\"baz\" type=\"as\" access=\"write\">"
|
||||
"<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
|
||||
"<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
|
||||
"<property name=\"bar\" type=\"i\" access=\"read\"/>"
|
||||
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
|
||||
}
|
||||
|
||||
void tst_QDBusXmlParser::properties()
|
||||
{
|
||||
QString xmlHeader = "<node>"
|
||||
"<interface name=\"iface.iface1\">",
|
||||
xmlFooter = "</interface>"
|
||||
"</node>";
|
||||
|
||||
QFETCH(QString, xmlDataFragment);
|
||||
|
||||
QDBusIntrospection::Interface iface =
|
||||
QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
|
||||
|
||||
QCOMPARE(iface.name, QString("iface.iface1"));
|
||||
|
||||
QFETCH(PropertyMap, propertyMap);
|
||||
PropertyMap parsedMap = iface.properties;
|
||||
|
||||
QCOMPARE(propertyMap.count(), parsedMap.count());
|
||||
QCOMPARE(propertyMap, parsedMap);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusXmlParser)
|
||||
|
||||
#include "tst_qdbusxmlparser.moc"
|
||||
Loading…
Add table
Reference in a new issue