1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
41
#include <qcoreapplication.h>
44
#include <QtTest/QtTest>
48
#include "../qdbusmarshall/common.h"
51
static const char serviceName[] = "org.qtproject.autotests.qmyserver";
52
static const char objectPath[] = "/org/qtproject/qmyserver";
53
static const char *interfaceName = serviceName;
60
char *toString(QDBusMessage::MessageType t)
64
case QDBusMessage::InvalidMessage:
65
return qstrdup("InvalidMessage");
66
case QDBusMessage::MethodCallMessage:
67
return qstrdup("MethodCallMessage");
68
case QDBusMessage::ReplyMessage:
69
return qstrdup("ReplyMessage");
70
case QDBusMessage::ErrorMessage:
71
return qstrdup("ErrorMessage");
72
case QDBusMessage::SignalMessage:
73
return qstrdup("SignalMessage");
81
class TypesInterface: public QDBusAbstractAdaptor
84
Q_CLASSINFO("D-Bus Interface", "local.TypesInterface")
86
TypesInterface(QObject *parent)
87
: QDBusAbstractAdaptor(parent)
104
QVariantList listSpy;
105
QStringList stringlistSpy;
106
QByteArray bytearraySpy;
108
StringStringMap ssmapSpy;
109
LLDateTimeMap lldtmapSpy;
113
void methodBool(bool b)
115
slotSpy = "void TypesInterface::methodBool(bool)";
119
void methodUChar(uchar uc)
121
slotSpy = "void TypesInterface::methodUChar(uchar)";
125
void methodShort(short s)
127
slotSpy = "void TypesInterface::methodShort(short)";
131
void methodUShort(ushort us)
133
slotSpy = "void TypesInterface::methodUShort(ushort)";
137
void methodInt(int i)
139
slotSpy = "void TypesInterface::methodInt(int)";
143
void methodUInt(uint ui)
145
slotSpy = "void TypesInterface::methodUInt(uint)";
149
void methodLongLong(qlonglong ll)
151
slotSpy = "void TypesInterface::methodLongLong(qlonglong)";
155
void methodULongLong(qulonglong ull)
157
slotSpy = "void TypesInterface::methodULongLong(qulonglong)";
161
void methodDouble(double d)
163
slotSpy = "void TypesInterface::methodDouble(double)";
167
void methodString(const QString &s)
169
slotSpy = "void TypesInterface::methodString(const QString &)";
173
void methodObjectPath(const QDBusObjectPath &op)
175
slotSpy = "void TypesInterface::methodObjectPath(const QDBusObjectPath &)";
176
stringSpy = op.path();
179
void methodSignature(const QDBusSignature &s)
181
slotSpy = "void TypesInterface::methodSignature(const QDBusSignature &)";
182
stringSpy = s.signature();
185
void methodVariant(const QDBusVariant &v)
187
slotSpy = "void TypesInterface::methodVariant(const QDBusVariant &)";
188
variantSpy = v.variant();
191
void methodList(const QVariantList &l)
193
slotSpy = "void TypesInterface::methodList(const QVariantList &)";
197
void methodStringList(const QStringList &sl)
199
slotSpy = "void TypesInterface::methodStringList(const QStringList &)";
203
void methodByteArray(const QByteArray &ba)
205
slotSpy = "void TypesInterface::methodByteArray(const QByteArray &)";
209
void methodMap(const QVariantMap &m)
211
slotSpy = "void TypesInterface::methodMap(const QVariantMap &)";
215
void methodSSMap(const StringStringMap &ssmap)
217
slotSpy = "void TypesInterface::methodSSMap(const StringStringMap &)";
221
void methodLLDateTimeMap(const LLDateTimeMap &lldtmap)
223
slotSpy = "void TypesInterface::methodLLDateTimeMap(const LLDateTimeMap &)";
224
lldtmapSpy = lldtmap;
227
void methodStruct(const MyStruct &s)
229
slotSpy = "void TypesInterface::methodStruct(const MyStruct &)";
238
uchar retrieveUChar()
243
short retrieveShort()
248
ushort retrieveUShort()
263
qlonglong retrieveLongLong()
268
qulonglong retrieveULongLong()
273
double retrieveDouble()
278
QString retrieveString()
283
QDBusObjectPath retrieveObjectPath()
285
return QDBusObjectPath(stringSpy);
288
QDBusSignature retrieveSignature()
290
return QDBusSignature(stringSpy);
293
QDBusVariant retrieveVariant()
295
return QDBusVariant(variantSpy);
298
QVariantList retrieveList()
303
QStringList retrieveStringList()
305
return stringlistSpy;
308
QByteArray retrieveByteArray()
313
QVariantMap retrieveMap()
318
StringStringMap retrieveSSMap()
323
LLDateTimeMap retrieveLLDateTimeMap()
328
MyStruct retrieveStruct()
334
void newMyObjectPeer(int nInterfaces = 4)
336
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "newMyObject");
338
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
341
void registerMyObjectPeer(const QString & path, QDBusConnection::RegisterOptions options = QDBusConnection::ExportAdaptors)
343
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "registerMyObject");
346
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
349
void emitSignalPeer(const QString &interface, const QString &name, const QVariant ¶meter)
351
if (parameter.isValid())
353
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
356
req << QVariant::fromValue(QDBusVariant(parameter));
357
QDBusConnection::sessionBus().send(req);
361
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal2");
364
QDBusConnection::sessionBus().send(req);
370
const char* slotSpyPeer()
372
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "slotSpyServer");
373
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
374
return reply.arguments().at(0).toString().toLatin1().data();
377
QString valueSpyPeer()
379
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "valueSpyServer");
380
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
381
return reply.arguments().at(0).toString();
384
void clearValueSpyPeer()
386
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "clearValueSpy");
387
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
390
class tst_QDBusAbstractAdaptor: public QObject
396
void cleanupTestCase();
398
void methodCalls_data();
400
void methodCallScriptable();
401
void signalEmissions_data();
402
void signalEmissions();
403
void sameSignalDifferentPaths();
404
void sameObjectDifferentPaths();
405
void scriptableSignalOrNot();
406
void overloadedSignalEmission_data();
407
void overloadedSignalEmission();
408
void readProperties();
409
void readPropertiesInvalidInterface();
410
void readPropertiesEmptyInterface_data();
411
void readPropertiesEmptyInterface();
412
void readAllProperties();
413
void readAllPropertiesInvalidInterface();
414
void readAllPropertiesEmptyInterface_data();
415
void readAllPropertiesEmptyInterface();
416
void writeProperties();
418
void methodCallsPeer_data();
419
void methodCallsPeer();
420
void methodCallScriptablePeer();
421
void signalEmissionsPeer_data();
422
void signalEmissionsPeer();
423
void sameSignalDifferentPathsPeer();
424
void sameObjectDifferentPathsPeer();
425
void scriptableSignalOrNotPeer();
426
void overloadedSignalEmissionPeer_data();
427
void overloadedSignalEmissionPeer();
428
void readPropertiesPeer();
429
void readPropertiesInvalidInterfacePeer();
430
void readPropertiesEmptyInterfacePeer_data();
431
void readPropertiesEmptyInterfacePeer();
432
void readAllPropertiesPeer();
433
void readAllPropertiesInvalidInterfacePeer();
434
void readAllPropertiesEmptyInterfacePeer_data();
435
void readAllPropertiesEmptyInterfacePeer();
436
void writePropertiesPeer();
438
void typeMatching_data();
441
void methodWithMoreThanOneReturnValue();
442
void methodWithMoreThanOneReturnValuePeer();
447
class WaitForQMyServer: public QObject
454
void ownerChange(const QString &name)
456
if (name == serviceName)
464
WaitForQMyServer::WaitForQMyServer()
466
QDBusConnection con = QDBusConnection::sessionBus();
468
connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
469
SLOT(ownerChange(QString)));
470
QTimer::singleShot(2000, &loop, SLOT(quit()));
475
bool WaitForQMyServer::ok()
477
return QDBusConnection::sessionBus().isConnected() &&
478
QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
481
void tst_QDBusAbstractAdaptor::initTestCase()
487
proc.start("qmyserver");
489
proc.start("./qmyserver/qmyserver");
491
QVERIFY(proc.waitForStarted());
495
//QTest::qWait(2000);
497
// get peer server address
498
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address");
499
QDBusMessage rpl = QDBusConnection::sessionBus().call(req);
500
QVERIFY(rpl.type() == QDBusMessage::ReplyMessage);
501
QString address = rpl.arguments().at(0).toString();
503
// connect to peer server
504
QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
505
QVERIFY(peercon.isConnected());
507
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
508
QDBusMessage rpl2 = QDBusConnection::sessionBus().call(req2);
509
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
510
QVERIFY(rpl2.arguments().at(0).toBool());
513
void tst_QDBusAbstractAdaptor::cleanupTestCase()
519
void tst_QDBusAbstractAdaptor::methodCalls_data()
521
QTest::addColumn<int>("nInterfaces");
522
QTest::newRow("0") << 0;
523
QTest::newRow("1") << 1;
524
QTest::newRow("2") << 2;
525
QTest::newRow("3") << 3;
526
QTest::newRow("4") << 4;
529
void tst_QDBusAbstractAdaptor::methodCalls()
531
QDBusConnection con = QDBusConnection::sessionBus();
532
QVERIFY(con.isConnected());
534
//QDBusInterface emptycon.baseService(), "/", QString());
537
// must fail: no object
538
QDBusInterface if1(con.baseService(), "/", "local.Interface1", con);
539
QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
542
QFETCH(int, nInterfaces);
543
MyObject obj(nInterfaces);
544
con.registerObject("/", &obj);
546
QDBusInterface if1(con.baseService(), "/", "local.Interface1", con);
547
QDBusInterface if2(con.baseService(), "/", "local.Interface2", con);
548
QDBusInterface if3(con.baseService(), "/", "local.Interface3", con);
549
QDBusInterface if4(con.baseService(), "/", "local.Interface4", con);
551
// must fail: no such method
552
QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
558
// simple call: one such method exists
559
QCOMPARE(if2.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
560
QCOMPARE(slotSpy, "void Interface2::method()");
564
// multiple methods in multiple interfaces, no name overlap
565
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
566
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
567
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
568
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
569
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
570
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
572
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ReplyMessage);
573
QCOMPARE(slotSpy, "void Interface3::methodVoid()");
574
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodInt", 42).type(), QDBusMessage::ReplyMessage);
575
QCOMPARE(slotSpy, "void Interface3::methodInt(int)");
576
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodString", QString("")).type(), QDBusMessage::ReplyMessage);
577
QCOMPARE(slotSpy, "void Interface3::methodString(QString)");
582
// method overloading: different interfaces
583
QCOMPARE(if4.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
584
QCOMPARE(slotSpy, "void Interface4::method()");
586
// method overloading: different parameters
587
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.i", 42).type(), QDBusMessage::ReplyMessage);
588
QCOMPARE(slotSpy, "void Interface4::method(int)");
589
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.s", QString()).type(), QDBusMessage::ReplyMessage);
590
QCOMPARE(slotSpy, "void Interface4::method(QString)");
594
void tst_QDBusAbstractAdaptor::methodCallScriptable()
596
QDBusConnection con = QDBusConnection::sessionBus();
597
QVERIFY(con.isConnected());
600
con.registerObject("/", &obj);
602
QDBusInterface if2(con.baseService(), "/", "local.Interface2", con);
604
QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage);
605
QCOMPARE(slotSpy, "void Interface2::scriptableMethod()");
608
static void emitSignal(MyObject *obj, const QString &iface, const QString &name,
609
const QVariant ¶meter)
611
if (iface.endsWith('2'))
612
obj->if2->emitSignal(name, parameter);
613
else if (iface.endsWith('3'))
614
obj->if3->emitSignal(name, parameter);
615
else if (iface.endsWith('4'))
616
obj->if4->emitSignal(name, parameter);
618
obj->emitSignal(name, parameter);
623
void tst_QDBusAbstractAdaptor::signalEmissions_data()
625
QTest::addColumn<QString>("interface");
626
QTest::addColumn<QString>("name");
627
QTest::addColumn<QString>("signature");
628
QTest::addColumn<QVariant>("parameter");
630
QTest::newRow("Interface2.signal") << "local.Interface2" << "signal" << QString() << QVariant();
631
QTest::newRow("Interface3.signalVoid") << "local.Interface3" << "signalVoid" << QString() << QVariant();
632
QTest::newRow("Interface3.signalInt") << "local.Interface3" << "signalInt" << "i" << QVariant(1);
633
QTest::newRow("Interface3.signalString") << "local.Interface3" << "signalString" << "s" << QVariant("foo");
634
QTest::newRow("MyObject.scriptableSignalVoid") << "local.MyObject" << "scriptableSignalVoid" << QString() << QVariant();
635
QTest::newRow("MyObject.scriptableSignalInt") << "local.MyObject" << "scriptableSignalInt" << "i" << QVariant(1);
636
QTest::newRow("MyObject.nySignalString") << "local.MyObject" << "scriptableSignalString" << "s" << QVariant("foo");
639
void tst_QDBusAbstractAdaptor::signalEmissions()
641
QFETCH(QString, interface);
642
QFETCH(QString, name);
643
QFETCH(QVariant, parameter);
645
QDBusConnection con = QDBusConnection::sessionBus();
646
QVERIFY(con.isConnected());
647
con.registerService("org.qtproject.tst_QDBusAbstractAdaptor");
650
con.registerObject("/", &obj, QDBusConnection::ExportAdaptors
651
| QDBusConnection::ExportScriptableSignals);
653
// connect all signals and emit only one
656
con.connect(con.baseService(), "/", "local.Interface2", "signal",
657
&spy, SLOT(slot(QDBusMessage)));
658
con.connect(con.baseService(), "/", "local.Interface3", "signalVoid",
659
&spy, SLOT(slot(QDBusMessage)));
660
con.connect(con.baseService(), "/", "local.Interface3", "signalInt",
661
&spy, SLOT(slot(QDBusMessage)));
662
con.connect(con.baseService(), "/", "local.Interface3", "signalString",
663
&spy, SLOT(slot(QDBusMessage)));
664
con.connect(con.baseService(), "/", "local.MyObject", "scriptableSignalVoid",
665
&spy, SLOT(slot(QDBusMessage)));
666
con.connect(con.baseService(), "/", "local.MyObject", "scriptableSignalInt",
667
&spy, SLOT(slot(QDBusMessage)));
668
con.connect(con.baseService(), "/", "local.MyObject", "scriptableSignalString",
669
&spy, SLOT(slot(QDBusMessage)));
671
emitSignal(&obj, interface, name, parameter);
673
QCOMPARE(spy.count, 1);
674
QCOMPARE(spy.interface, interface);
675
QCOMPARE(spy.name, name);
676
QTEST(spy.signature, "signature");
677
QCOMPARE(spy.value, parameter);
680
// connect one signal and emit them all
683
con.connect(con.baseService(), "/", interface, name, &spy, SLOT(slot(QDBusMessage)));
684
emitSignal(&obj, "local.Interface2", "signal", QVariant());
685
emitSignal(&obj, "local.Interface3", "signalVoid", QVariant());
686
emitSignal(&obj, "local.Interface3", "signalInt", QVariant(1));
687
emitSignal(&obj, "local.Interface3", "signalString", QVariant("foo"));
688
emitSignal(&obj, "local.MyObject", "scriptableSignalVoid", QVariant());
689
emitSignal(&obj, "local.MyObject", "scriptableSignalInt", QVariant(1));
690
emitSignal(&obj, "local.MyObject", "scriptableSignalString", QVariant("foo"));
692
QCOMPARE(spy.count, 1);
693
QCOMPARE(spy.interface, interface);
694
QCOMPARE(spy.name, name);
695
QTEST(spy.signature, "signature");
696
QCOMPARE(spy.value, parameter);
700
void tst_QDBusAbstractAdaptor::sameSignalDifferentPaths()
702
QDBusConnection con = QDBusConnection::sessionBus();
703
QVERIFY(con.isConnected());
707
con.registerObject("/p1",&obj);
708
con.registerObject("/p2",&obj);
711
con.connect(con.baseService(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
712
obj.if2->emitSignal(QString(), QVariant());
715
QCOMPARE(spy.count, 1);
716
QCOMPARE(spy.interface, QString("local.Interface2"));
717
QCOMPARE(spy.name, QString("signal"));
718
QVERIFY(spy.signature.isEmpty());
720
// now connect the other one
722
con.connect(con.baseService(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
723
obj.if2->emitSignal(QString(), QVariant());
726
QCOMPARE(spy.count, 2);
729
void tst_QDBusAbstractAdaptor::sameObjectDifferentPaths()
731
QDBusConnection con = QDBusConnection::sessionBus();
732
QVERIFY(con.isConnected());
736
con.registerObject("/p1",&obj);
737
con.registerObject("/p2",&obj, 0); // don't export anything
740
con.connect(con.baseService(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
741
con.connect(con.baseService(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
742
obj.if2->emitSignal(QString(), QVariant());
745
QCOMPARE(spy.count, 1);
746
QCOMPARE(spy.interface, QString("local.Interface2"));
747
QCOMPARE(spy.name, QString("signal"));
748
QVERIFY(spy.signature.isEmpty());
751
void tst_QDBusAbstractAdaptor::scriptableSignalOrNot()
753
QDBusConnection con = QDBusConnection::sessionBus();
754
QVERIFY(con.isConnected());
759
con.registerObject("/p1",&obj, QDBusConnection::ExportScriptableSignals);
760
con.registerObject("/p2",&obj, 0); // don't export anything
763
con.connect(con.baseService(), "/p1", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
764
con.connect(con.baseService(), "/p2", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
765
con.connect(con.baseService(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
766
con.connect(con.baseService(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
767
obj.emitSignal("scriptableSignalVoid", QVariant());
768
obj.emitSignal("nonScriptableSignalVoid", QVariant());
771
QCOMPARE(spy.count, 1); // only /p1 must have emitted
772
QCOMPARE(spy.interface, QString("local.MyObject"));
773
QCOMPARE(spy.name, QString("scriptableSignalVoid"));
774
QCOMPARE(spy.path, QString("/p1"));
775
QVERIFY(spy.signature.isEmpty());
781
con.registerObject("/p1",&obj, QDBusConnection::ExportScriptableSignals);
782
con.registerObject("/p2",&obj, QDBusConnection::ExportScriptableSignals
783
| QDBusConnection::ExportNonScriptableSignals);
786
con.connect(con.baseService(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
787
con.connect(con.baseService(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
788
obj.emitSignal("nonScriptableSignalVoid", QVariant());
791
QCOMPARE(spy.count, 1); // only /p2 must have emitted now
792
QCOMPARE(spy.interface, QString("local.MyObject"));
793
QCOMPARE(spy.name, QString("nonScriptableSignalVoid"));
794
QCOMPARE(spy.path, QString("/p2"));
795
QVERIFY(spy.signature.isEmpty());
800
con.connect(con.baseService(), "/p1", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
801
con.connect(con.baseService(), "/p2", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
806
con.registerObject("/p1",&obj, QDBusConnection::ExportScriptableSignals);
807
con.registerObject("/p2",&obj, QDBusConnection::ExportScriptableSignals
808
| QDBusConnection::ExportNonScriptableSignals);
809
} // <--- QObject emits the destroyed(QObject*) signal at this point
813
QCOMPARE(spy.count, 0);
817
void tst_QDBusAbstractAdaptor::overloadedSignalEmission_data()
819
QTest::addColumn<QString>("signature");
820
QTest::addColumn<QVariant>("parameter");
821
QTest::newRow("void") << QString("") << QVariant();
822
QTest::newRow("int") << "i" << QVariant(1);
823
QTest::newRow("string") << "s" << QVariant("foo");
826
void tst_QDBusAbstractAdaptor::overloadedSignalEmission()
828
QDBusConnection con = QDBusConnection::sessionBus();
829
QVERIFY(con.isConnected());
832
con.registerObject("/", &obj);
834
QString interface = "local.Interface4";
835
QString name = "signal";
836
QFETCH(QVariant, parameter);
837
//QDBusInterface *if4 = new QDBusInterface(con.baseService(), "/", interface, con);
839
// connect all signals and emit only one
842
con.connect(con.baseService(), "/", "local.Interface4", "signal", "",
843
&spy, SLOT(slot(QDBusMessage)));
844
con.connect(con.baseService(), "/", "local.Interface4", "signal", "i",
845
&spy, SLOT(slot(QDBusMessage)));
846
con.connect(con.baseService(), "/", "local.Interface4", "signal", "s",
847
&spy, SLOT(slot(QDBusMessage)));
849
emitSignal(&obj, interface, name, parameter);
851
QCOMPARE(spy.count, 1);
852
QCOMPARE(spy.interface, interface);
853
QCOMPARE(spy.name, name);
854
QTEST(spy.signature, "signature");
855
QCOMPARE(spy.value, parameter);
858
QFETCH(QString, signature);
859
// connect one signal and emit them all
862
con.connect(con.baseService(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage)));
863
emitSignal(&obj, "local.Interface4", "signal", QVariant());
864
emitSignal(&obj, "local.Interface4", "signal", QVariant(1));
865
emitSignal(&obj, "local.Interface4", "signal", QVariant("foo"));
867
QCOMPARE(spy.count, 1);
868
QCOMPARE(spy.interface, interface);
869
QCOMPARE(spy.name, name);
870
QTEST(spy.signature, "signature");
871
QCOMPARE(spy.value, parameter);
875
void tst_QDBusAbstractAdaptor::readProperties()
877
QDBusConnection con = QDBusConnection::sessionBus();
878
QVERIFY(con.isConnected());
881
con.registerObject("/", &obj);
883
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
884
for (int i = 2; i <= 4; ++i) {
885
QString name = QString("Interface%1").arg(i);
887
for (int j = 1; j <= 2; ++j) {
888
QString propname = QString("prop%1").arg(j);
889
QDBusReply<QVariant> reply =
890
properties.call(QDBus::BlockWithGui, "Get", "local." + name, propname);
891
QVariant value = reply;
893
QCOMPARE(value.userType(), int(QVariant::String));
894
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
899
void tst_QDBusAbstractAdaptor::readPropertiesInvalidInterface()
901
QDBusConnection con = QDBusConnection::sessionBus();
902
QVERIFY(con.isConnected());
905
con.registerObject("/", &obj);
907
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
909
// test an invalid interface:
910
QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "local.DoesntExist", "prop1");
911
QVERIFY(!reply.isValid());
914
void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterface_data()
916
QTest::addColumn<QVariantMap>("expectedProperties");
917
QTest::addColumn<bool>("existing");
919
QVariantMap expectedProperties;
920
expectedProperties["prop1"] = QVariant();
921
expectedProperties["prop2"] = QVariant();
922
expectedProperties["interface3prop"] = "QString Interface3::interface3prop() const";
923
expectedProperties["interface4prop"] = "QString Interface4::interface4prop() const";
924
QTest::newRow("existing") << expectedProperties << true;
926
expectedProperties.clear();
927
expectedProperties["prop5"] = QVariant();
928
expectedProperties["foobar"] = QVariant();
929
QTest::newRow("non-existing") << expectedProperties << false;
932
void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterface()
934
QDBusConnection con = QDBusConnection::sessionBus();
935
QVERIFY(con.isConnected());
938
con.registerObject("/", &obj);
940
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
942
QFETCH(QVariantMap, expectedProperties);
943
QFETCH(bool, existing);
945
QVariantMap::ConstIterator it = expectedProperties.constBegin();
946
for ( ; it != expectedProperties.constEnd(); ++it) {
947
QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "", it.key());
950
QVERIFY2(reply.isValid(), qPrintable(it.key()));
952
QVERIFY2(!reply.isValid(), qPrintable(it.key()));
956
QCOMPARE(int(reply.value().type()), int(QVariant::String));
957
if (it.value().isValid())
958
QCOMPARE(reply.value().toString(), it.value().toString());
962
void tst_QDBusAbstractAdaptor::readAllProperties()
964
QDBusConnection con = QDBusConnection::sessionBus();
965
QVERIFY(con.isConnected());
968
con.registerObject("/", &obj);
970
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
971
for (int i = 2; i <= 4; ++i) {
972
QString name = QString("Interface%1").arg(i);
973
QDBusReply<QVariantMap> reply =
974
properties.call(QDBus::BlockWithGui, "GetAll", "local." + name);
976
for (int j = 1; j <= 2; ++j) {
977
QString propname = QString("prop%1").arg(j);
978
QVERIFY2(reply.value().contains(propname),
979
qPrintable(propname + " on " + name));
980
QVariant value = reply.value().value(propname);
982
QCOMPARE(value.userType(), int(QVariant::String));
983
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
988
void tst_QDBusAbstractAdaptor::readAllPropertiesInvalidInterface()
990
QDBusConnection con = QDBusConnection::sessionBus();
991
QVERIFY(con.isConnected());
994
con.registerObject("/", &obj);
996
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
998
// test an invalid interface:
999
QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "local.DoesntExist");
1000
QVERIFY(!reply.isValid());
1003
void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterface_data()
1005
readPropertiesEmptyInterface_data();
1008
void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterface()
1010
QDBusConnection con = QDBusConnection::sessionBus();
1011
QVERIFY(con.isConnected());
1014
con.registerObject("/", &obj);
1016
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
1018
QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "");
1019
QVERIFY(reply.isValid());
1021
QVariantMap allprops = reply;
1023
QFETCH(QVariantMap, expectedProperties);
1024
QFETCH(bool, existing);
1026
QVariantMap::ConstIterator it = expectedProperties.constBegin();
1028
for ( ; it != expectedProperties.constEnd(); ++it) {
1029
QVERIFY2(allprops.contains(it.key()), qPrintable(it.key()));
1031
QVariant propvalue = allprops.value(it.key());
1032
QVERIFY2(!propvalue.isNull(), qPrintable(it.key()));
1033
QVERIFY2(propvalue.isValid(), qPrintable(it.key()));
1035
QString stringvalue = propvalue.toString();
1036
QVERIFY2(!stringvalue.isEmpty(), qPrintable(it.key()));
1038
if (it.value().isValid())
1039
QCOMPARE(stringvalue, it.value().toString());
1041
// remove this property from the map
1042
allprops.remove(it.key());
1045
QVERIFY2(allprops.isEmpty(),
1046
qPrintable(QStringList(allprops.keys()).join(' ')));
1048
for ( ; it != expectedProperties.constEnd(); ++it)
1049
QVERIFY2(!allprops.contains(it.key()), qPrintable(it.key()));
1053
void tst_QDBusAbstractAdaptor::writeProperties()
1055
QDBusConnection con = QDBusConnection::sessionBus();
1056
QVERIFY(con.isConnected());
1059
con.registerObject("/", &obj);
1061
QDBusInterface properties(con.baseService(), "/", "org.freedesktop.DBus.Properties", con);
1062
for (int i = 2; i <= 4; ++i) {
1063
QString name = QString("Interface%1").arg(i);
1066
properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop1"),
1067
QVariant::fromValue(QDBusVariant(name)));
1068
QVERIFY(valueSpy.isEmpty()); // call mustn't have succeeded
1070
properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop2"),
1071
QVariant::fromValue(QDBusVariant(name)));
1072
QCOMPARE(valueSpy, name);
1073
QCOMPARE(QString(slotSpy), QString("void %1::setProp2(const QString &)").arg(name));
1077
void tst_QDBusAbstractAdaptor::methodCallsPeer_data()
1082
void tst_QDBusAbstractAdaptor::methodCallsPeer()
1084
QDBusConnection con("peer");
1085
QVERIFY(con.isConnected());
1088
// must fail: no object
1089
QDBusInterface if1(QString(), "/", "local.Interface1", con);
1090
QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
1093
QFETCH(int, nInterfaces);
1094
newMyObjectPeer(nInterfaces);
1095
registerMyObjectPeer("/");
1097
QDBusInterface if1(QString(), "/", "local.Interface1", con);
1098
QDBusInterface if2(QString(), "/", "local.Interface2", con);
1099
QDBusInterface if3(QString(), "/", "local.Interface3", con);
1100
QDBusInterface if4(QString(), "/", "local.Interface4", con);
1102
// must fail: no such method
1103
QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage);
1109
// simple call: one such method exists
1110
QCOMPARE(if2.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
1111
QCOMPARE(slotSpyPeer(), "void Interface2::method()");
1115
// multiple methods in multiple interfaces, no name overlap
1116
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
1117
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
1118
QCOMPARE(if1.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
1119
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage);
1120
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage);
1121
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
1123
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ReplyMessage);
1124
QCOMPARE(slotSpyPeer(), "void Interface3::methodVoid()");
1125
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodInt", 42).type(), QDBusMessage::ReplyMessage);
1126
QCOMPARE(slotSpyPeer(), "void Interface3::methodInt(int)");
1127
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodString", QString("")).type(), QDBusMessage::ReplyMessage);
1128
QCOMPARE(slotSpyPeer(), "void Interface3::methodString(QString)");
1133
// method overloading: different interfaces
1134
QCOMPARE(if4.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
1135
QCOMPARE(slotSpyPeer(), "void Interface4::method()");
1137
// method overloading: different parameters
1138
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.i", 42).type(), QDBusMessage::ReplyMessage);
1139
QCOMPARE(slotSpyPeer(), "void Interface4::method(int)");
1140
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.s", QString()).type(), QDBusMessage::ReplyMessage);
1141
QCOMPARE(slotSpyPeer(), "void Interface4::method(QString)");
1144
void tst_QDBusAbstractAdaptor::methodCallScriptablePeer()
1146
QDBusConnection con("peer");
1147
QVERIFY(con.isConnected());
1150
registerMyObjectPeer("/");
1152
QDBusInterface if2(QString(), "/", "local.Interface2", con);
1154
QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage);
1155
QCOMPARE(slotSpyPeer(), "void Interface2::scriptableMethod()");
1158
void tst_QDBusAbstractAdaptor::signalEmissionsPeer_data()
1160
signalEmissions_data();
1163
void tst_QDBusAbstractAdaptor::signalEmissionsPeer()
1165
QFETCH(QString, interface);
1166
QFETCH(QString, name);
1167
QFETCH(QVariant, parameter);
1169
QDBusConnection con("peer");
1170
QVERIFY(con.isConnected());
1173
registerMyObjectPeer("/", QDBusConnection::ExportAdaptors
1174
| QDBusConnection::ExportScriptableSignals);
1176
// connect all signals and emit only one
1179
con.connect(QString(), "/", "local.Interface2", "signal",
1180
&spy, SLOT(slot(QDBusMessage)));
1181
con.connect(QString(), "/", "local.Interface3", "signalVoid",
1182
&spy, SLOT(slot(QDBusMessage)));
1183
con.connect(QString(), "/", "local.Interface3", "signalInt",
1184
&spy, SLOT(slot(QDBusMessage)));
1185
con.connect(QString(), "/", "local.Interface3", "signalString",
1186
&spy, SLOT(slot(QDBusMessage)));
1187
con.connect(QString(), "/", "local.MyObject", "scriptableSignalVoid",
1188
&spy, SLOT(slot(QDBusMessage)));
1189
con.connect(QString(), "/", "local.MyObject", "scriptableSignalInt",
1190
&spy, SLOT(slot(QDBusMessage)));
1191
con.connect(QString(), "/", "local.MyObject", "scriptableSignalString",
1192
&spy, SLOT(slot(QDBusMessage)));
1194
emitSignalPeer(interface, name, parameter);
1196
QCOMPARE(spy.count, 1);
1197
QCOMPARE(spy.interface, interface);
1198
QCOMPARE(spy.name, name);
1199
QTEST(spy.signature, "signature");
1200
QCOMPARE(spy.value, parameter);
1203
// connect one signal and emit them all
1206
con.connect(QString(), "/", interface, name, &spy, SLOT(slot(QDBusMessage)));
1207
emitSignalPeer("local.Interface2", "signal", QVariant());
1208
emitSignalPeer("local.Interface3", "signalVoid", QVariant());
1209
emitSignalPeer("local.Interface3", "signalInt", QVariant(1));
1210
emitSignalPeer("local.Interface3", "signalString", QVariant("foo"));
1211
emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant());
1212
emitSignalPeer("local.MyObject", "scriptableSignalInt", QVariant(1));
1213
emitSignalPeer("local.MyObject", "scriptableSignalString", QVariant("foo"));
1215
QCOMPARE(spy.count, 1);
1216
QCOMPARE(spy.interface, interface);
1217
QCOMPARE(spy.name, name);
1218
QTEST(spy.signature, "signature");
1219
QCOMPARE(spy.value, parameter);
1223
void tst_QDBusAbstractAdaptor::sameSignalDifferentPathsPeer()
1225
QDBusConnection con("peer");
1226
QVERIFY(con.isConnected());
1230
registerMyObjectPeer("/p1");
1231
registerMyObjectPeer("/p2");
1234
con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
1235
emitSignalPeer("local.Interface2", QString(), QVariant());
1238
QCOMPARE(spy.count, 1);
1239
QCOMPARE(spy.interface, QString("local.Interface2"));
1240
QCOMPARE(spy.name, QString("signal"));
1241
QVERIFY(spy.signature.isEmpty());
1243
// now connect the other one
1245
con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
1246
emitSignalPeer("local.Interface2", QString(), QVariant());
1249
QCOMPARE(spy.count, 2);
1252
void tst_QDBusAbstractAdaptor::sameObjectDifferentPathsPeer()
1254
QDBusConnection con("peer");
1255
QVERIFY(con.isConnected());
1259
registerMyObjectPeer("/p1");
1260
registerMyObjectPeer("/p2", 0); // don't export anything
1263
con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
1264
con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
1265
emitSignalPeer("local.Interface2", QString(), QVariant());
1268
QCOMPARE(spy.count, 1);
1269
QCOMPARE(spy.interface, QString("local.Interface2"));
1270
QCOMPARE(spy.name, QString("signal"));
1271
QVERIFY(spy.signature.isEmpty());
1274
void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
1276
QDBusConnection con("peer");;
1277
QVERIFY(con.isConnected());
1282
registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
1283
registerMyObjectPeer("/p2", 0); // don't export anything
1286
con.connect(QString(), "/p1", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1287
con.connect(QString(), "/p2", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1288
con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1289
con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1290
emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant());
1291
emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
1294
QCOMPARE(spy.count, 1); // only /p1 must have emitted
1295
QCOMPARE(spy.interface, QString("local.MyObject"));
1296
QCOMPARE(spy.name, QString("scriptableSignalVoid"));
1297
QCOMPARE(spy.path, QString("/p1"));
1298
QVERIFY(spy.signature.isEmpty());
1304
registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
1305
registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals
1306
| QDBusConnection::ExportNonScriptableSignals);
1309
con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1310
con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
1311
emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
1314
QCOMPARE(spy.count, 1); // only /p2 must have emitted now
1315
QCOMPARE(spy.interface, QString("local.MyObject"));
1316
QCOMPARE(spy.name, QString("nonScriptableSignalVoid"));
1317
QCOMPARE(spy.path, QString("/p2"));
1318
QVERIFY(spy.signature.isEmpty());
1323
con.connect(QString(), "/p1", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
1324
con.connect(QString(), "/p2", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage)));
1329
registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
1330
registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals
1331
| QDBusConnection::ExportNonScriptableSignals);
1332
} // <--- QObject emits the destroyed(QObject*) signal at this point
1336
QCOMPARE(spy.count, 0);
1340
void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer_data()
1342
overloadedSignalEmission_data();
1345
void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer()
1347
QDBusConnection con("peer");
1348
QVERIFY(con.isConnected());
1351
registerMyObjectPeer("/");
1353
QString interface = "local.Interface4";
1354
QString name = "signal";
1355
QFETCH(QVariant, parameter);
1356
//QDBusInterface *if4 = new QDBusInterface(QString(), "/", interface, con);
1358
// connect all signals and emit only one
1361
con.connect(QString(), "/", "local.Interface4", "signal", "",
1362
&spy, SLOT(slot(QDBusMessage)));
1363
con.connect(QString(), "/", "local.Interface4", "signal", "i",
1364
&spy, SLOT(slot(QDBusMessage)));
1365
con.connect(QString(), "/", "local.Interface4", "signal", "s",
1366
&spy, SLOT(slot(QDBusMessage)));
1368
emitSignalPeer(interface, name, parameter);
1370
QCOMPARE(spy.count, 1);
1371
QCOMPARE(spy.interface, interface);
1372
QCOMPARE(spy.name, name);
1373
QTEST(spy.signature, "signature");
1374
QCOMPARE(spy.value, parameter);
1377
QFETCH(QString, signature);
1378
// connect one signal and emit them all
1381
con.connect(QString(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage)));
1382
emitSignalPeer("local.Interface4", "signal", QVariant());
1383
emitSignalPeer("local.Interface4", "signal", QVariant(1));
1384
emitSignalPeer("local.Interface4", "signal", QVariant("foo"));
1386
QCOMPARE(spy.count, 1);
1387
QCOMPARE(spy.interface, interface);
1388
QCOMPARE(spy.name, name);
1389
QTEST(spy.signature, "signature");
1390
QCOMPARE(spy.value, parameter);
1394
void tst_QDBusAbstractAdaptor::readPropertiesPeer()
1396
QDBusConnection con("peer");
1397
QVERIFY(con.isConnected());
1400
registerMyObjectPeer("/");
1402
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1403
for (int i = 2; i <= 4; ++i) {
1404
QString name = QString("Interface%1").arg(i);
1406
for (int j = 1; j <= 2; ++j) {
1407
QString propname = QString("prop%1").arg(j);
1408
QDBusReply<QVariant> reply =
1409
properties.call(QDBus::BlockWithGui, "Get", "local." + name, propname);
1410
QVariant value = reply;
1412
QCOMPARE(value.userType(), int(QVariant::String));
1413
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
1418
void tst_QDBusAbstractAdaptor::readPropertiesInvalidInterfacePeer()
1420
QDBusConnection con("peer");
1421
QVERIFY(con.isConnected());
1424
registerMyObjectPeer("/");
1426
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1428
// test an invalid interface:
1429
QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "local.DoesntExist", "prop1");
1430
QVERIFY(!reply.isValid());
1433
void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer_data()
1435
readPropertiesEmptyInterface_data();
1438
void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer()
1440
QDBusConnection con("peer");
1441
QVERIFY(con.isConnected());
1444
registerMyObjectPeer("/");
1446
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1448
QFETCH(QVariantMap, expectedProperties);
1449
QFETCH(bool, existing);
1451
QVariantMap::ConstIterator it = expectedProperties.constBegin();
1452
for ( ; it != expectedProperties.constEnd(); ++it) {
1453
QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "", it.key());
1456
QVERIFY2(reply.isValid(), qPrintable(it.key()));
1458
QVERIFY2(!reply.isValid(), qPrintable(it.key()));
1462
QCOMPARE(int(reply.value().type()), int(QVariant::String));
1463
if (it.value().isValid())
1464
QCOMPARE(reply.value().toString(), it.value().toString());
1468
void tst_QDBusAbstractAdaptor::readAllPropertiesPeer()
1470
QDBusConnection con("peer");
1471
QVERIFY(con.isConnected());
1474
registerMyObjectPeer("/");
1476
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1477
for (int i = 2; i <= 4; ++i) {
1478
QString name = QString("Interface%1").arg(i);
1479
QDBusReply<QVariantMap> reply =
1480
properties.call(QDBus::BlockWithGui, "GetAll", "local." + name);
1482
for (int j = 1; j <= 2; ++j) {
1483
QString propname = QString("prop%1").arg(j);
1484
QVERIFY2(reply.value().contains(propname),
1485
qPrintable(propname + " on " + name));
1486
QVariant value = reply.value().value(propname);
1488
QCOMPARE(value.userType(), int(QVariant::String));
1489
QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname));
1494
void tst_QDBusAbstractAdaptor::readAllPropertiesInvalidInterfacePeer()
1496
QDBusConnection con("peer");
1497
QVERIFY(con.isConnected());
1500
registerMyObjectPeer("/");
1502
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1504
// test an invalid interface:
1505
QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "local.DoesntExist");
1506
QVERIFY(!reply.isValid());
1509
void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer_data()
1511
readAllPropertiesEmptyInterface_data();
1514
void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer()
1516
QDBusConnection con("peer");
1517
QVERIFY(con.isConnected());
1520
registerMyObjectPeer("/");
1522
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1524
QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "");
1525
QVERIFY(reply.isValid());
1527
QVariantMap allprops = reply;
1529
QFETCH(QVariantMap, expectedProperties);
1530
QFETCH(bool, existing);
1532
QVariantMap::ConstIterator it = expectedProperties.constBegin();
1534
for ( ; it != expectedProperties.constEnd(); ++it) {
1535
QVERIFY2(allprops.contains(it.key()), qPrintable(it.key()));
1537
QVariant propvalue = allprops.value(it.key());
1538
QVERIFY2(!propvalue.isNull(), qPrintable(it.key()));
1539
QVERIFY2(propvalue.isValid(), qPrintable(it.key()));
1541
QString stringvalue = propvalue.toString();
1542
QVERIFY2(!stringvalue.isEmpty(), qPrintable(it.key()));
1544
if (it.value().isValid())
1545
QCOMPARE(stringvalue, it.value().toString());
1547
// remove this property from the map
1548
allprops.remove(it.key());
1551
QVERIFY2(allprops.isEmpty(),
1552
qPrintable(QStringList(allprops.keys()).join(' ')));
1554
for ( ; it != expectedProperties.constEnd(); ++it)
1555
QVERIFY2(!allprops.contains(it.key()), qPrintable(it.key()));
1559
void tst_QDBusAbstractAdaptor::writePropertiesPeer()
1561
QDBusConnection con("peer");
1562
QVERIFY(con.isConnected());
1565
registerMyObjectPeer("/");
1567
QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con);
1568
for (int i = 2; i <= 4; ++i) {
1569
QString name = QString("Interface%1").arg(i);
1571
clearValueSpyPeer();
1572
properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop1"),
1573
QVariant::fromValue(QDBusVariant(name)));
1574
QVERIFY(valueSpyPeer().isEmpty()); // call mustn't have succeeded
1576
properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop2"),
1577
QVariant::fromValue(QDBusVariant(name)));
1578
QCOMPARE(valueSpyPeer(), name);
1579
QCOMPARE(QString(slotSpyPeer()), QString("void %1::setProp2(const QString &)").arg(name));
1584
void tst_QDBusAbstractAdaptor::adaptorIntrospection_data()
1589
void tst_QDBusAbstractAdaptor::adaptorIntrospection()
1591
QDBusConnection con = QDBus::sessionBus();
1592
QVERIFY(con.isConnected());
1595
con.registerObject("/", &obj);
1597
QFETCH(int, nInterfaces);
1598
switch (nInterfaces)
1601
new Interface4(&obj);
1603
new Interface3(&obj);
1605
new Interface2(&obj);
1607
new Interface1(&obj);
1610
QDBusObject dobj = con.findObject(con.baseService(), "/");
1611
QVERIFY(dobj.isValid());
1613
QString xml = dobj.introspect();
1614
QVERIFY(!xml.isEmpty());
1616
QStringList interfaces = dobj.interfaces();
1617
QCOMPARE(interfaces.count(), nInterfaces + 2);
1618
switch (nInterfaces)
1621
QVERIFY(interfaces.contains("local.Interface4"));
1622
QDBusInterface iface(dobj, "local.Interface4");
1623
QCOMPARE(iface.methodData(), Interface4::methodData);
1624
QCOMPARE(iface.signalData(), Interface4::signalData);
1625
QCOMPARE(iface.propertyData(), Interface4::propertyData);
1628
QVERIFY(interfaces.contains("local.Interface3"));
1629
QDBusInterface iface(dobj, "local.Interface3");
1630
QCOMPARE(iface.methodData(), Interface3::methodData);
1631
QCOMPARE(iface.signalData(), Interface3::signalData);
1632
QCOMPARE(iface.propertyData(), Interface3::propertyData);
1635
QVERIFY(interfaces.contains("local.Interface2"));
1636
QDBusInterface iface(dobj, "local.Interface2");
1637
QCOMPARE(iface.methodData(), Interface2::methodData);
1638
QCOMPARE(iface.signalData(), Interface2::signalData);
1639
QCOMPARE(iface.propertyData(), Interface2::propertyData);
1642
QVERIFY(interfaces.contains("local.Interface1"));
1643
QDBusInterface iface(dobj, "local.Interface1");
1644
QCOMPARE(iface.methodData(), Interface1::methodData);
1645
QCOMPARE(iface.signalData(), Interface1::signalData);
1646
QCOMPARE(iface.propertyData(), Interface1::propertyData);
1651
void tst_QDBusAbstractAdaptor::objectTreeIntrospection()
1653
QDBusConnection con = QDBus::sessionBus();
1654
QVERIFY(con.isConnected());
1657
QDBusObject dobj = con.findObject(con.baseService(), "/");
1658
QString xml = dobj.introspect();
1660
QDBusIntrospection::Object tree =
1661
QDBusIntrospection::parseObject(xml);
1662
QVERIFY(tree.childObjects.isEmpty());
1666
con.registerObject("/", &root);
1668
QDBusObject dobj = con.findObject(con.baseService(), "/");
1669
QString xml = dobj.introspect();
1671
QDBusIntrospection::Object tree =
1672
QDBusIntrospection::parseObject(xml);
1673
QVERIFY(tree.childObjects.isEmpty());
1677
con.registerObject("/p1", &p1);
1679
QDBusObject dobj = con.findObject(con.baseService(), "/");
1680
QString xml = dobj.introspect();
1682
QDBusIntrospection::Object tree =
1683
QDBusIntrospection::parseObject(xml);
1684
QVERIFY(tree.childObjects.contains("p1"));
1687
con.unregisterObject("/");
1689
QDBusObject dobj = con.findObject(con.baseService(), "/");
1690
QString xml = dobj.introspect();
1692
QDBusIntrospection::Object tree =
1693
QDBusIntrospection::parseObject(xml);
1694
QVERIFY(tree.childObjects.contains("p1"));
1697
con.registerObject("/p1/q/r", &root);
1699
QDBusObject dobj = con.findObject(con.baseService(), "/p1");
1700
QString xml = dobj.introspect();
1702
QDBusIntrospection::Object tree =
1703
QDBusIntrospection::parseObject(xml);
1704
QVERIFY(tree.childObjects.contains("q"));
1707
QDBusObject dobj = con.findObject(con.baseService(), "/p1/q");
1708
QString xml = dobj.introspect();
1710
QDBusIntrospection::Object tree =
1711
QDBusIntrospection::parseObject(xml);
1712
QVERIFY(tree.childObjects.contains("r"));
1715
con.unregisterObject("/p1", QDBusConnection::UnregisterTree);
1717
QDBusObject dobj = con.findObject(con.baseService(), "/");
1718
QString xml = dobj.introspect();
1720
QDBusIntrospection::Object tree =
1721
QDBusIntrospection::parseObject(xml);
1722
QVERIFY(tree.childObjects.isEmpty());
1726
con.registerObject("/p2", &p2, QDBusConnection::ExportChildObjects);
1728
QDBusObject dobj = con.findObject(con.baseService(), "/");
1729
QString xml = dobj.introspect();
1731
QDBusIntrospection::Object tree =
1732
QDBusIntrospection::parseObject(xml);
1733
QVERIFY(!tree.childObjects.contains("p1"));
1734
QVERIFY(tree.childObjects.contains("p2"));
1740
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
1741
QString xml = dobj.introspect();
1743
QDBusIntrospection::Object tree =
1744
QDBusIntrospection::parseObject(xml);
1745
QVERIFY(!tree.childObjects.contains("q"));
1748
q.setObjectName("q");
1750
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
1751
QString xml = dobj.introspect();
1753
QDBusIntrospection::Object tree =
1754
QDBusIntrospection::parseObject(xml);
1755
QVERIFY(tree.childObjects.contains("q"));
1760
QDBusObject dobj = con.findObject(con.baseService(), "/p2");
1761
QString xml = dobj.introspect();
1763
QDBusIntrospection::Object tree =
1764
QDBusIntrospection::parseObject(xml);
1765
QVERIFY(!tree.childObjects.contains("q"));
1770
void tst_QDBusAbstractAdaptor::typeMatching_data()
1772
QTest::addColumn<QString>("basename");
1773
QTest::addColumn<QString>("signature");
1774
QTest::addColumn<QVariant>("value");
1776
QTest::newRow("bool") << "Bool" << "b" << QVariant(true);
1777
QTest::newRow("byte") << "UChar" << "y" << QVariant::fromValue(uchar(42));
1778
QTest::newRow("short") << "Short" << "n" << QVariant::fromValue(short(-43));
1779
QTest::newRow("ushort") << "UShort" << "q" << QVariant::fromValue(ushort(44));
1780
QTest::newRow("int") << "Int" << "i" << QVariant(42);
1781
QTest::newRow("uint") << "UInt" << "u" << QVariant(42U);
1782
QTest::newRow("qlonglong") << "LongLong" << "x" << QVariant(Q_INT64_C(42));
1783
QTest::newRow("qulonglong") << "ULongLong" << "t" << QVariant(Q_UINT64_C(42));
1784
QTest::newRow("double") << "Double" << "d" << QVariant(2.5);
1785
QTest::newRow("string") << "String" << "s" << QVariant("Hello, World!");
1787
QTest::newRow("variant") << "Variant" << "v" << QVariant::fromValue(QDBusVariant("Hello again!"));
1788
QTest::newRow("list") << "List" << "av" << QVariant(QVariantList()
1791
<< QByteArray("bar")
1792
<< QVariant::fromValue(QDBusVariant(QString("baz"))));
1793
QTest::newRow("stringlist") << "StringList" << "as" << QVariant(QStringList() << "Hello" << "world");
1794
QTest::newRow("bytearray") << "ByteArray" << "ay" << QVariant(QByteArray("foo"));
1797
map["one"] = 1; // int
1798
map["The answer to life, the Universe and everything"] = 42u; // uint
1799
map["In the beginning..."] = QString("There was nothing"); // string
1800
map["but Unix came and said"] = QByteArray("\"Hello, World\""); // bytearray
1801
map["two"] = QVariant::fromValue(short(2)); // short
1802
QTest::newRow("map") << "Map" << "a{sv}" << QVariant(map);
1804
StringStringMap ssmap;
1807
QTest::newRow("ssmap") << "SSMap" << "a{ss}" << QVariant::fromValue(ssmap);
1809
LLDateTimeMap lldtmap;
1810
lldtmap[-1] = QDateTime();
1811
QDateTime now = QDateTime::currentDateTime();
1812
lldtmap[now.toTime_t()] = now; // array of struct of int64 and struct of 3 ints and struct of 4 ints and int
1813
QTest::newRow("lldtmap") << "LLDateTimeMap" << "a{x((iii)(iiii)i)}" << QVariant::fromValue(lldtmap);
1818
QTest::newRow("struct") << "Struct" << "(is)" << QVariant::fromValue(s);
1821
void tst_QDBusAbstractAdaptor::typeMatching()
1824
new TypesInterface(&obj);
1826
QDBusConnection con = QDBusConnection::sessionBus();
1827
con.registerObject("/types", &obj);
1829
QFETCH(QString, basename);
1830
QFETCH(QString, signature);
1831
QFETCH(QVariant, value);
1834
QDBusInterface iface(con.baseService(), "/types", "local.TypesInterface", con);
1836
reply = iface.callWithArgumentList(QDBus::BlockWithGui, "method" + basename,
1837
QVariantList() << value);
1838
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
1840
reply = iface.call(QDBus::BlockWithGui, "retrieve" + basename);
1841
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
1842
QCOMPARE(reply.arguments().count(), 1);
1844
const QVariant &retval = reply.arguments().at(0);
1845
QVERIFY(compare(retval, value));
1848
void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValue()
1850
QDBusConnection con = QDBusConnection::sessionBus();
1851
QVERIFY(con.isConnected());
1854
con.registerObject("/", &obj);
1856
QString testString = "This is a test string.";
1858
QDBusInterface remote(con.baseService(), "/", "local.Interface3", con);
1859
QDBusMessage reply = remote.call(QDBus::BlockWithGui, "methodStringString", testString);
1860
QVERIFY(reply.arguments().count() == 2);
1862
QDBusReply<int> intreply = reply;
1863
QVERIFY(intreply.isValid());
1864
QCOMPARE(intreply.value(), 42);
1866
QCOMPARE(reply.arguments().at(1).userType(), int(QVariant::String));
1867
QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString);
1870
void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValuePeer()
1872
QDBusConnection con("peer");
1873
QVERIFY(con.isConnected());
1876
registerMyObjectPeer("/");
1878
QString testString = "This is a test string.";
1880
QDBusInterface remote(QString(), "/", "local.Interface3", con);
1881
QDBusMessage reply = remote.call(QDBus::BlockWithGui, "methodStringString", testString);
1882
QVERIFY(reply.arguments().count() == 2);
1884
QDBusReply<int> intreply = reply;
1885
QVERIFY(intreply.isValid());
1886
QCOMPARE(intreply.value(), 42);
1888
QCOMPARE(reply.arguments().at(1).userType(), int(QVariant::String));
1889
QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString);
1892
QTEST_MAIN(tst_QDBusAbstractAdaptor)
1894
#include "tst_qdbusabstractadaptor.moc"