~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
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.
 
16
**
 
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.
 
24
**
 
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.
 
28
**
 
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.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
/* -*- C++ -*-
 
42
 */
 
43
 
 
44
#include <qcoreapplication.h>
 
45
#include <qmetatype.h>
 
46
#include <QtTest/QtTest>
 
47
#include <QtCore/qvariant.h>
 
48
#include <QtDBus/QtDBus>
 
49
#include <qdebug.h>
 
50
#include "../qdbusmarshall/common.h"
 
51
#include "myobject.h"
 
52
 
 
53
#define TEST_INTERFACE_NAME "org.qtproject.QtDBus.MyObject"
 
54
#define TEST_SIGNAL_NAME "somethingHappened"
 
55
 
 
56
static const char serviceName[] = "org.qtproject.autotests.qmyserver";
 
57
static const char objectPath[] = "/org/qtproject/qmyserver";
 
58
static const char *interfaceName = serviceName;
 
59
 
 
60
int MyObject::callCount = 0;
 
61
QVariantList MyObject::callArgs;
 
62
 
 
63
class MyObjectUnknownType: public QObject
 
64
{
 
65
    Q_OBJECT
 
66
    Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject")
 
67
    Q_CLASSINFO("D-Bus Introspection", ""
 
68
"  <interface name=\"org.qtproject.QtDBus.MyObjectUnknownTypes\" >\n"
 
69
"    <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n"
 
70
"    <signal name=\"somethingHappened\" >\n"
 
71
"      <arg direction=\"out\" type=\"~\" />\n"
 
72
"    </signal>\n"
 
73
"    <method name=\"ping\" >\n"
 
74
"      <arg direction=\"in\" type=\"~\" name=\"ping\" />\n"
 
75
"      <arg direction=\"out\" type=\"~\" name=\"ping\" />\n"
 
76
"    </method>\n"
 
77
"    <method name=\"regularMethod\" />\n"
 
78
"  </interface>\n"
 
79
                "")
 
80
};
 
81
 
 
82
class Spy: public QObject
 
83
{
 
84
    Q_OBJECT
 
85
public:
 
86
    QString received;
 
87
    int count;
 
88
 
 
89
    Spy() : count(0)
 
90
    { }
 
91
 
 
92
public slots:
 
93
    void spySlot(const QString& arg)
 
94
    {
 
95
        received = arg;
 
96
        ++count;
 
97
    }
 
98
};
 
99
 
 
100
class DerivedFromQDBusInterface: public QDBusInterface
 
101
{
 
102
    Q_OBJECT
 
103
public:
 
104
    DerivedFromQDBusInterface()
 
105
        : QDBusInterface("com.example.Test", "/")
 
106
    {}
 
107
 
 
108
public slots:
 
109
    void method() {}
 
110
};
 
111
 
 
112
// helper function
 
113
void emitSignal(const QString &interface, const QString &name, const QString &arg)
 
114
{
 
115
    QDBusMessage msg = QDBusMessage::createSignal("/", interface, name);
 
116
    msg << arg;
 
117
    QDBusConnection::sessionBus().send(msg);
 
118
 
 
119
    QTest::qWait(1000);
 
120
}
 
121
 
 
122
void emitSignalPeer(const QString &interface, const QString &name, const QString &arg)
 
123
{
 
124
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
 
125
    req << interface;
 
126
    req << name;
 
127
    req << arg;
 
128
    QDBusConnection::sessionBus().send(req);
 
129
 
 
130
    QTest::qWait(1000);
 
131
}
 
132
 
 
133
int callCountPeer()
 
134
{
 
135
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callCount");
 
136
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
137
    return reply.arguments().at(0).toInt();
 
138
}
 
139
 
 
140
QVariantList callArgsPeer()
 
141
{
 
142
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callArgs");
 
143
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
144
    return qdbus_cast<QVariantList>(reply.arguments().at(0));
 
145
}
 
146
 
 
147
void setProp1Peer(int val)
 
148
{
 
149
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setProp1");
 
150
    req << val;
 
151
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
152
}
 
153
 
 
154
int prop1Peer()
 
155
{
 
156
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "prop1");
 
157
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
158
    return reply.arguments().at(0).toInt();
 
159
}
 
160
 
 
161
void setComplexPropPeer(QList<int> val)
 
162
{
 
163
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setComplexProp");
 
164
    req << QVariant::fromValue(val);
 
165
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
166
}
 
167
 
 
168
QList<int> complexPropPeer()
 
169
{
 
170
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexProp");
 
171
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
 
172
    return qdbus_cast<QList<int> >(reply.arguments().at(0));
 
173
}
 
174
 
 
175
void resetPeer()
 
176
{
 
177
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset");
 
178
    QDBusConnection::sessionBus().call(req);
 
179
}
 
180
 
 
181
class tst_QDBusInterface: public QObject
 
182
{
 
183
    Q_OBJECT
 
184
    MyObject obj;
 
185
 
 
186
public slots:
 
187
    void testServiceOwnerChanged(const QString &service)
 
188
    {
 
189
        if (service == "com.example.Test")
 
190
            QTestEventLoop::instance().exitLoop();
 
191
    }
 
192
 
 
193
private slots:
 
194
    void initTestCase();
 
195
    void cleanupTestCase();
 
196
 
 
197
    void notConnected();
 
198
    void notValid();
 
199
    void notValidDerived();
 
200
    void invalidAfterServiceOwnerChanged();
 
201
    void introspect();
 
202
    void introspectUnknownTypes();
 
203
    void introspectVirtualObject();
 
204
    void callMethod();
 
205
    void invokeMethod();
 
206
    void invokeMethodWithReturn();
 
207
    void invokeMethodWithMultiReturn();
 
208
    void invokeMethodWithComplexReturn();
 
209
 
 
210
    void introspectPeer();
 
211
    void callMethodPeer();
 
212
    void invokeMethodPeer();
 
213
    void invokeMethodWithReturnPeer();
 
214
    void invokeMethodWithMultiReturnPeer();
 
215
    void invokeMethodWithComplexReturnPeer();
 
216
 
 
217
    void signal();
 
218
    void signalPeer();
 
219
 
 
220
    void propertyRead();
 
221
    void propertyWrite();
 
222
    void complexPropertyRead();
 
223
    void complexPropertyWrite();
 
224
 
 
225
    void propertyReadPeer();
 
226
    void propertyWritePeer();
 
227
    void complexPropertyReadPeer();
 
228
    void complexPropertyWritePeer();
 
229
private:
 
230
    QProcess proc;
 
231
};
 
232
 
 
233
class WaitForQMyServer: public QObject
 
234
{
 
235
    Q_OBJECT
 
236
public:
 
237
    WaitForQMyServer();
 
238
    bool ok();
 
239
public Q_SLOTS:
 
240
    void ownerChange(const QString &name)
 
241
    {
 
242
        if (name == serviceName)
 
243
            loop.quit();
 
244
    }
 
245
 
 
246
private:
 
247
    QEventLoop loop;
 
248
};
 
249
 
 
250
WaitForQMyServer::WaitForQMyServer()
 
251
{
 
252
    QDBusConnection con = QDBusConnection::sessionBus();
 
253
    if (!ok()) {
 
254
        connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
 
255
                SLOT(ownerChange(QString)));
 
256
        QTimer::singleShot(2000, &loop, SLOT(quit()));
 
257
        loop.exec();
 
258
    }
 
259
}
 
260
 
 
261
bool WaitForQMyServer::ok()
 
262
{
 
263
    return QDBusConnection::sessionBus().isConnected() &&
 
264
        QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
 
265
}
 
266
 
 
267
void tst_QDBusInterface::initTestCase()
 
268
{
 
269
    QDBusConnection con = QDBusConnection::sessionBus();
 
270
    QVERIFY(con.isConnected());
 
271
    QTest::qWait(500);
 
272
 
 
273
    con.registerObject("/", &obj, QDBusConnection::ExportAllProperties
 
274
                       | QDBusConnection::ExportAllSlots
 
275
                       | QDBusConnection::ExportAllInvokables);
 
276
 
 
277
    // start peer server
 
278
    #ifdef Q_OS_WIN
 
279
    proc.start("qmyserver");
 
280
    #else
 
281
    proc.start("./qmyserver/qmyserver");
 
282
    #endif
 
283
    QVERIFY(proc.waitForStarted());
 
284
 
 
285
    WaitForQMyServer w;
 
286
    QVERIFY(w.ok());
 
287
    //QTest::qWait(2000);
 
288
 
 
289
    // get peer server address
 
290
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address");
 
291
    QDBusMessage rpl = con.call(req);
 
292
    QVERIFY(rpl.type() == QDBusMessage::ReplyMessage);
 
293
    QString address = rpl.arguments().at(0).toString();
 
294
 
 
295
    // connect to peer server
 
296
    QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
 
297
    QVERIFY(peercon.isConnected());
 
298
 
 
299
    QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
 
300
    QDBusMessage rpl2 = con.call(req2);
 
301
    QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
 
302
    QVERIFY(rpl2.arguments().at(0).toBool());
 
303
}
 
304
 
 
305
void tst_QDBusInterface::cleanupTestCase()
 
306
{
 
307
    proc.close();
 
308
    proc.kill();
 
309
}
 
310
 
 
311
void tst_QDBusInterface::notConnected()
 
312
{
 
313
    QDBusConnection connection("");
 
314
    QVERIFY(!connection.isConnected());
 
315
 
 
316
    QDBusInterface interface("org.freedesktop.DBus", "/", "org.freedesktop.DBus",
 
317
                             connection);
 
318
 
 
319
    QVERIFY(!interface.isValid());
 
320
    QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
 
321
}
 
322
 
 
323
void tst_QDBusInterface::notValid()
 
324
{
 
325
    QDBusConnection connection("");
 
326
    QVERIFY(!connection.isConnected());
 
327
 
 
328
    QDBusInterface interface("com.example.Test", QString(), "org.example.Test",
 
329
                             connection);
 
330
 
 
331
    QVERIFY(!interface.isValid());
 
332
    QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
 
333
}
 
334
 
 
335
void tst_QDBusInterface::notValidDerived()
 
336
{
 
337
    DerivedFromQDBusInterface c;
 
338
    QVERIFY(!c.isValid());
 
339
    QMetaObject::invokeMethod(&c, "method", Qt::DirectConnection);
 
340
}
 
341
 
 
342
void tst_QDBusInterface::invalidAfterServiceOwnerChanged()
 
343
{
 
344
    // this test is technically the same as tst_QDBusAbstractInterface::followSignal
 
345
    QDBusConnection conn = QDBusConnection::sessionBus();
 
346
    QDBusConnectionInterface *connIface = conn.interface();
 
347
 
 
348
    QDBusInterface validInterface(conn.baseService(), "/");
 
349
    QVERIFY(validInterface.isValid());
 
350
    QDBusInterface invalidInterface("com.example.Test", "/");
 
351
    QVERIFY(!invalidInterface.isValid());
 
352
 
 
353
    QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
 
354
                                       SLOT(exitLoop()));
 
355
    QVERIFY(connIface->registerService("com.example.Test") == QDBusConnectionInterface::ServiceRegistered);
 
356
 
 
357
    QTestEventLoop::instance().enterLoop(5);
 
358
 
 
359
    QVERIFY(!QTestEventLoop::instance().timeout());
 
360
    QVERIFY(invalidInterface.isValid());
 
361
}
 
362
 
 
363
void tst_QDBusInterface::introspect()
 
364
{
 
365
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
366
                         TEST_INTERFACE_NAME);
 
367
 
 
368
    const QMetaObject *mo = iface.metaObject();
 
369
 
 
370
    QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
 
371
    QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
 
372
 
 
373
    QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
 
374
    QVERIFY(mo->indexOfProperty("prop1") != -1);
 
375
    QVERIFY(mo->indexOfProperty("complexProp") != -1);
 
376
}
 
377
 
 
378
void tst_QDBusInterface::introspectUnknownTypes()
 
379
{
 
380
    QDBusConnection con = QDBusConnection::sessionBus();
 
381
    MyObjectUnknownType obj;
 
382
    con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents);
 
383
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"),
 
384
                         "org.qtproject.QtDBus.MyObjectUnknownTypes");
 
385
 
 
386
    const QMetaObject *mo = iface.metaObject();
 
387
    QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control
 
388
    QVERIFY(mo->indexOfMethod("somethingHappened(QDBusRawType<0x7e>*)") != -1);
 
389
 
 
390
    QVERIFY(mo->indexOfMethod("ping(QDBusRawType<0x7e>*)") != -1);
 
391
    int midx = mo->indexOfMethod("ping(QDBusRawType<0x7e>*)");
 
392
    QCOMPARE(mo->method(midx).typeName(), "QDBusRawType<0x7e>*");
 
393
 
 
394
    QVERIFY(mo->indexOfProperty("prop1") != -1);
 
395
    int pidx = mo->indexOfProperty("prop1");
 
396
    QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*");
 
397
 
 
398
 
 
399
 
 
400
    QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), "/unknownTypes", "org.freedesktop.DBus.Introspectable", "Introspect");
 
401
    QDBusMessage reply = con.call(message, QDBus::Block, 5000);
 
402
    qDebug() << "REPL: " << reply.arguments();
 
403
 
 
404
}
 
405
 
 
406
 
 
407
class VirtualObject: public QDBusVirtualObject
 
408
{
 
409
    Q_OBJECT
 
410
public:
 
411
    VirtualObject() :success(true) {}
 
412
 
 
413
    QString introspect(const QString &path) const {
 
414
        if (path == "/some/path/superNode")
 
415
            return "zitroneneis";
 
416
        if (path == "/some/path/superNode/foo")
 
417
            return  "  <interface name=\"org.qtproject.QtDBus.VirtualObject\">\n"
 
418
                    "    <method name=\"klingeling\" />\n"
 
419
                    "  </interface>\n" ;
 
420
        return QString();
 
421
    }
 
422
 
 
423
    bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
 
424
        ++callCount;
 
425
        lastMessage = message;
 
426
 
 
427
        if (success) {
 
428
            QDBusMessage reply = message.createReply(replyArguments);
 
429
            connection.send(reply);
 
430
        }
 
431
        emit messageReceived(message);
 
432
        return success;
 
433
    }
 
434
signals:
 
435
    void messageReceived(const QDBusMessage &message) const;
 
436
 
 
437
public:
 
438
    mutable QDBusMessage lastMessage;
 
439
    QVariantList replyArguments;
 
440
    mutable int callCount;
 
441
    bool success;
 
442
};
 
443
 
 
444
void tst_QDBusInterface::introspectVirtualObject()
 
445
{
 
446
    QDBusConnection con = QDBusConnection::sessionBus();
 
447
    QVERIFY(con.isConnected());
 
448
    VirtualObject obj;
 
449
 
 
450
    obj.success = false;
 
451
 
 
452
    QString path = "/some/path/superNode";
 
453
    QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
 
454
 
 
455
    QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, "org.freedesktop.DBus.Introspectable", "Introspect");
 
456
    QDBusMessage reply = con.call(message, QDBus::Block, 5000);
 
457
    QVERIFY(reply.arguments().at(0).toString().contains(
 
458
        QRegExp("<node>.*zitroneneis.*<interface name=") ));
 
459
 
 
460
    QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect");
 
461
    QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000);
 
462
    QVERIFY(reply2.arguments().at(0).toString().contains(
 
463
        QRegExp("<node>.*<interface name=\"org.qtproject.QtDBus.VirtualObject\">"
 
464
                ".*<method name=\"klingeling\" />\n"
 
465
                ".*</interface>.*<interface name=") ));
 
466
}
 
467
 
 
468
void tst_QDBusInterface::callMethod()
 
469
{
 
470
    QDBusConnection con = QDBusConnection::sessionBus();
 
471
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
472
                         TEST_INTERFACE_NAME);
 
473
 
 
474
    MyObject::callCount = 0;
 
475
 
 
476
    // call a SLOT method
 
477
    QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
 
478
    QCOMPARE(MyObject::callCount, 1);
 
479
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
 
480
 
 
481
    // verify what the callee received
 
482
    QCOMPARE(MyObject::callArgs.count(), 1);
 
483
    QVariant v = MyObject::callArgs.at(0);
 
484
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
485
    QCOMPARE(dv.variant().type(), QVariant::String);
 
486
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
487
 
 
488
    // verify reply
 
489
    QCOMPARE(reply.arguments().count(), 1);
 
490
    v = reply.arguments().at(0);
 
491
    dv = qdbus_cast<QDBusVariant>(v);
 
492
    QCOMPARE(dv.variant().type(), QVariant::String);
 
493
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
494
 
 
495
    // call an INVOKABLE method
 
496
    reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
 
497
    QCOMPARE(MyObject::callCount, 2);
 
498
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
 
499
 
 
500
    // verify what the callee received
 
501
    QCOMPARE(MyObject::callArgs.count(), 1);
 
502
    v = MyObject::callArgs.at(0);
 
503
    dv = qdbus_cast<QDBusVariant>(v);
 
504
    QCOMPARE(dv.variant().type(), QVariant::String);
 
505
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
506
 
 
507
    // verify reply
 
508
    QCOMPARE(reply.arguments().count(), 1);
 
509
    v = reply.arguments().at(0);
 
510
    dv = qdbus_cast<QDBusVariant>(v);
 
511
    QCOMPARE(dv.variant().type(), QVariant::String);
 
512
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
513
}
 
514
 
 
515
void tst_QDBusInterface::invokeMethod()
 
516
{
 
517
    QDBusConnection con = QDBusConnection::sessionBus();
 
518
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
519
                         TEST_INTERFACE_NAME);
 
520
 
 
521
    MyObject::callCount = 0;
 
522
 
 
523
    // make the SLOT call without a return type
 
524
    QDBusVariant arg("foo");
 
525
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
 
526
    QCOMPARE(MyObject::callCount, 1);
 
527
 
 
528
    // verify what the callee received
 
529
    QCOMPARE(MyObject::callArgs.count(), 1);
 
530
    QVariant v = MyObject::callArgs.at(0);
 
531
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
532
    QCOMPARE(dv.variant().type(), QVariant::String);
 
533
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
534
 
 
535
    // make the INVOKABLE call without a return type
 
536
    QDBusVariant arg2("bar");
 
537
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
 
538
    QCOMPARE(MyObject::callCount, 2);
 
539
 
 
540
    // verify what the callee received
 
541
    QCOMPARE(MyObject::callArgs.count(), 1);
 
542
    v = MyObject::callArgs.at(0);
 
543
    dv = qdbus_cast<QDBusVariant>(v);
 
544
    QCOMPARE(dv.variant().type(), QVariant::String);
 
545
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
546
}
 
547
 
 
548
void tst_QDBusInterface::invokeMethodWithReturn()
 
549
{
 
550
    QDBusConnection con = QDBusConnection::sessionBus();
 
551
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
552
                         TEST_INTERFACE_NAME);
 
553
 
 
554
    MyObject::callCount = 0;
 
555
    QDBusVariant retArg;
 
556
 
 
557
    // make the SLOT call without a return type
 
558
    QDBusVariant arg("foo");
 
559
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
 
560
    QCOMPARE(MyObject::callCount, 1);
 
561
 
 
562
    // verify what the callee received
 
563
    QCOMPARE(MyObject::callArgs.count(), 1);
 
564
    QVariant v = MyObject::callArgs.at(0);
 
565
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
566
    QCOMPARE(dv.variant().type(), QVariant::String);
 
567
    QCOMPARE(dv.variant().toString(), arg.variant().toString());
 
568
 
 
569
    // verify that we got the reply as expected
 
570
    QCOMPARE(retArg.variant(), arg.variant());
 
571
 
 
572
    // make the INVOKABLE call without a return type
 
573
    QDBusVariant arg2("bar");
 
574
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
 
575
    QCOMPARE(MyObject::callCount, 2);
 
576
 
 
577
    // verify what the callee received
 
578
    QCOMPARE(MyObject::callArgs.count(), 1);
 
579
    v = MyObject::callArgs.at(0);
 
580
    dv = qdbus_cast<QDBusVariant>(v);
 
581
    QCOMPARE(dv.variant().type(), QVariant::String);
 
582
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());
 
583
 
 
584
    // verify that we got the reply as expected
 
585
    QCOMPARE(retArg.variant(), arg2.variant());
 
586
}
 
587
 
 
588
void tst_QDBusInterface::invokeMethodWithMultiReturn()
 
589
{
 
590
    QDBusConnection con = QDBusConnection::sessionBus();
 
591
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
592
                         TEST_INTERFACE_NAME);
 
593
 
 
594
    MyObject::callCount = 0;
 
595
    QDBusVariant retArg, retArg2;
 
596
 
 
597
    // make the SLOT call without a return type
 
598
    QDBusVariant arg("foo"), arg2("bar");
 
599
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
 
600
                                      Q_RETURN_ARG(QDBusVariant, retArg),
 
601
                                      Q_ARG(QDBusVariant, arg),
 
602
                                      Q_ARG(QDBusVariant, arg2),
 
603
                                      Q_ARG(QDBusVariant&, retArg2)));
 
604
    QCOMPARE(MyObject::callCount, 1);
 
605
 
 
606
    // verify what the callee received
 
607
    QCOMPARE(MyObject::callArgs.count(), 2);
 
608
    QVariant v = MyObject::callArgs.at(0);
 
609
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
610
    QCOMPARE(dv.variant().type(), QVariant::String);
 
611
    QCOMPARE(dv.variant().toString(), arg.variant().toString());
 
612
 
 
613
    v = MyObject::callArgs.at(1);
 
614
    dv = qdbus_cast<QDBusVariant>(v);
 
615
    QCOMPARE(dv.variant().type(), QVariant::String);
 
616
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());
 
617
 
 
618
    // verify that we got the replies as expected
 
619
    QCOMPARE(retArg.variant(), arg.variant());
 
620
    QCOMPARE(retArg2.variant(), arg2.variant());
 
621
 
 
622
    // make the INVOKABLE call without a return type
 
623
    QDBusVariant arg3("hello"), arg4("world");
 
624
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
 
625
                                      Q_RETURN_ARG(QDBusVariant, retArg),
 
626
                                      Q_ARG(QDBusVariant, arg3),
 
627
                                      Q_ARG(QDBusVariant, arg4),
 
628
                                      Q_ARG(QDBusVariant&, retArg2)));
 
629
    QCOMPARE(MyObject::callCount, 2);
 
630
 
 
631
    // verify what the callee received
 
632
    QCOMPARE(MyObject::callArgs.count(), 2);
 
633
    v = MyObject::callArgs.at(0);
 
634
    dv = qdbus_cast<QDBusVariant>(v);
 
635
    QCOMPARE(dv.variant().type(), QVariant::String);
 
636
    QCOMPARE(dv.variant().toString(), arg3.variant().toString());
 
637
 
 
638
    v = MyObject::callArgs.at(1);
 
639
    dv = qdbus_cast<QDBusVariant>(v);
 
640
    QCOMPARE(dv.variant().type(), QVariant::String);
 
641
    QCOMPARE(dv.variant().toString(), arg4.variant().toString());
 
642
 
 
643
    // verify that we got the replies as expected
 
644
    QCOMPARE(retArg.variant(), arg3.variant());
 
645
    QCOMPARE(retArg2.variant(), arg4.variant());
 
646
}
 
647
 
 
648
void tst_QDBusInterface::invokeMethodWithComplexReturn()
 
649
{
 
650
    QDBusConnection con = QDBusConnection::sessionBus();
 
651
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
652
                         TEST_INTERFACE_NAME);
 
653
 
 
654
    MyObject::callCount = 0;
 
655
    QList<int> retArg;
 
656
 
 
657
    // make the SLOT call without a return type
 
658
    QList<int> arg = QList<int>() << 42 << -47;
 
659
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
 
660
    QCOMPARE(MyObject::callCount, 1);
 
661
 
 
662
    // verify what the callee received
 
663
    QCOMPARE(MyObject::callArgs.count(), 1);
 
664
    QVariant v = MyObject::callArgs.at(0);
 
665
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
 
666
    QCOMPARE(qdbus_cast<QList<int> >(v), arg);
 
667
 
 
668
    // verify that we got the reply as expected
 
669
    QCOMPARE(retArg, arg);
 
670
 
 
671
    // make the INVOKABLE call without a return type
 
672
    QList<int> arg2 = QList<int>() << 24 << -74;
 
673
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
 
674
    QCOMPARE(MyObject::callCount, 2);
 
675
 
 
676
    // verify what the callee received
 
677
    QCOMPARE(MyObject::callArgs.count(), 1);
 
678
    v = MyObject::callArgs.at(0);
 
679
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
 
680
    QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
 
681
 
 
682
    // verify that we got the reply as expected
 
683
    QCOMPARE(retArg, arg2);
 
684
}
 
685
 
 
686
void tst_QDBusInterface::introspectPeer()
 
687
{
 
688
    QDBusConnection con("peer");
 
689
    QDBusInterface iface(QString(), QLatin1String("/"),
 
690
                         TEST_INTERFACE_NAME, con);
 
691
 
 
692
    const QMetaObject *mo = iface.metaObject();
 
693
 
 
694
    QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
 
695
    QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
 
696
 
 
697
    QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
 
698
    QVERIFY(mo->indexOfProperty("prop1") != -1);
 
699
    QVERIFY(mo->indexOfProperty("complexProp") != -1);
 
700
}
 
701
 
 
702
void tst_QDBusInterface::callMethodPeer()
 
703
{
 
704
    QDBusConnection con("peer");
 
705
    QDBusInterface iface(QString(), QLatin1String("/"),
 
706
                         TEST_INTERFACE_NAME, con);
 
707
 
 
708
    resetPeer();
 
709
 
 
710
    // call a SLOT method
 
711
    QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
 
712
    QCOMPARE(callCountPeer(), 1);
 
713
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
 
714
 
 
715
    // verify what the callee received
 
716
    QVariantList callArgs = callArgsPeer();
 
717
    QCOMPARE(callArgs.count(), 1);
 
718
    QVariant v = callArgs.at(0);
 
719
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
720
    QCOMPARE(dv.variant().type(), QVariant::String);
 
721
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
722
 
 
723
    // verify reply
 
724
    QCOMPARE(reply.arguments().count(), 1);
 
725
    v = reply.arguments().at(0);
 
726
    dv = qdbus_cast<QDBusVariant>(v);
 
727
    QCOMPARE(dv.variant().type(), QVariant::String);
 
728
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
729
 
 
730
    // call an INVOKABLE method
 
731
    reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
 
732
    QCOMPARE(callCountPeer(), 2);
 
733
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
 
734
 
 
735
    // verify what the callee received
 
736
    callArgs = callArgsPeer();
 
737
    QCOMPARE(callArgs.count(), 1);
 
738
    v = callArgs.at(0);
 
739
    dv = qdbus_cast<QDBusVariant>(v);
 
740
    QCOMPARE(dv.variant().type(), QVariant::String);
 
741
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
742
 
 
743
    // verify reply
 
744
    QCOMPARE(reply.arguments().count(), 1);
 
745
    v = reply.arguments().at(0);
 
746
    dv = qdbus_cast<QDBusVariant>(v);
 
747
    QCOMPARE(dv.variant().type(), QVariant::String);
 
748
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
749
}
 
750
 
 
751
void tst_QDBusInterface::invokeMethodPeer()
 
752
{
 
753
    QDBusConnection con("peer");
 
754
    QDBusInterface iface(QString(), QLatin1String("/"),
 
755
                         TEST_INTERFACE_NAME, con);
 
756
 
 
757
    resetPeer();
 
758
 
 
759
    // make the SLOT call without a return type
 
760
    QDBusVariant arg("foo");
 
761
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
 
762
    QCOMPARE(callCountPeer(), 1);
 
763
 
 
764
    // verify what the callee received
 
765
    QVariantList callArgs = callArgsPeer();
 
766
    QCOMPARE(callArgs.count(), 1);
 
767
    QVariant v = callArgs.at(0);
 
768
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
769
    QCOMPARE(dv.variant().type(), QVariant::String);
 
770
    QCOMPARE(dv.variant().toString(), QString("foo"));
 
771
 
 
772
    // make the INVOKABLE call without a return type
 
773
    QDBusVariant arg2("bar");
 
774
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
 
775
    QCOMPARE(callCountPeer(), 2);
 
776
 
 
777
    // verify what the callee received
 
778
    callArgs = callArgsPeer();
 
779
    QCOMPARE(callArgs.count(), 1);
 
780
    v = callArgs.at(0);
 
781
    dv = qdbus_cast<QDBusVariant>(v);
 
782
    QCOMPARE(dv.variant().type(), QVariant::String);
 
783
    QCOMPARE(dv.variant().toString(), QString("bar"));
 
784
}
 
785
 
 
786
void tst_QDBusInterface::invokeMethodWithReturnPeer()
 
787
{
 
788
    QDBusConnection con("peer");
 
789
    QDBusInterface iface(QString(), QLatin1String("/"),
 
790
                         TEST_INTERFACE_NAME, con);
 
791
 
 
792
    resetPeer();
 
793
    QDBusVariant retArg;
 
794
 
 
795
    // make the SLOT call without a return type
 
796
    QDBusVariant arg("foo");
 
797
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
 
798
    QCOMPARE(callCountPeer(), 1);
 
799
 
 
800
    // verify what the callee received
 
801
    QVariantList callArgs = callArgsPeer();
 
802
    QCOMPARE(callArgs.count(), 1);
 
803
    QVariant v = callArgs.at(0);
 
804
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
805
    QCOMPARE(dv.variant().type(), QVariant::String);
 
806
    QCOMPARE(dv.variant().toString(), arg.variant().toString());
 
807
 
 
808
    // verify that we got the reply as expected
 
809
    QCOMPARE(retArg.variant(), arg.variant());
 
810
 
 
811
    // make the INVOKABLE call without a return type
 
812
    QDBusVariant arg2("bar");
 
813
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
 
814
    QCOMPARE(callCountPeer(), 2);
 
815
 
 
816
    // verify what the callee received
 
817
    callArgs = callArgsPeer();
 
818
    QCOMPARE(callArgs.count(), 1);
 
819
    v = callArgs.at(0);
 
820
    dv = qdbus_cast<QDBusVariant>(v);
 
821
    QCOMPARE(dv.variant().type(), QVariant::String);
 
822
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());
 
823
 
 
824
    // verify that we got the reply as expected
 
825
    QCOMPARE(retArg.variant(), arg2.variant());
 
826
}
 
827
 
 
828
void tst_QDBusInterface::invokeMethodWithMultiReturnPeer()
 
829
{
 
830
    QDBusConnection con("peer");
 
831
    QDBusInterface iface(QString(), QLatin1String("/"),
 
832
                         TEST_INTERFACE_NAME, con);
 
833
 
 
834
    resetPeer();
 
835
    QDBusVariant retArg, retArg2;
 
836
 
 
837
    // make the SLOT call without a return type
 
838
    QDBusVariant arg("foo"), arg2("bar");
 
839
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
 
840
                                      Q_RETURN_ARG(QDBusVariant, retArg),
 
841
                                      Q_ARG(QDBusVariant, arg),
 
842
                                      Q_ARG(QDBusVariant, arg2),
 
843
                                      Q_ARG(QDBusVariant&, retArg2)));
 
844
    QCOMPARE(callCountPeer(), 1);
 
845
 
 
846
    // verify what the callee received
 
847
    QVariantList callArgs = callArgsPeer();
 
848
    QCOMPARE(callArgs.count(), 2);
 
849
    QVariant v = callArgs.at(0);
 
850
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
 
851
    QCOMPARE(dv.variant().type(), QVariant::String);
 
852
    QCOMPARE(dv.variant().toString(), arg.variant().toString());
 
853
 
 
854
    v = callArgs.at(1);
 
855
    dv = qdbus_cast<QDBusVariant>(v);
 
856
    QCOMPARE(dv.variant().type(), QVariant::String);
 
857
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());
 
858
 
 
859
    // verify that we got the replies as expected
 
860
    QCOMPARE(retArg.variant(), arg.variant());
 
861
    QCOMPARE(retArg2.variant(), arg2.variant());
 
862
 
 
863
    // make the INVOKABLE call without a return type
 
864
    QDBusVariant arg3("hello"), arg4("world");
 
865
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
 
866
                                      Q_RETURN_ARG(QDBusVariant, retArg),
 
867
                                      Q_ARG(QDBusVariant, arg3),
 
868
                                      Q_ARG(QDBusVariant, arg4),
 
869
                                      Q_ARG(QDBusVariant&, retArg2)));
 
870
    QCOMPARE(callCountPeer(), 2);
 
871
 
 
872
    // verify what the callee received
 
873
    callArgs = callArgsPeer();
 
874
    QCOMPARE(callArgs.count(), 2);
 
875
    v = callArgs.at(0);
 
876
    dv = qdbus_cast<QDBusVariant>(v);
 
877
    QCOMPARE(dv.variant().type(), QVariant::String);
 
878
    QCOMPARE(dv.variant().toString(), arg3.variant().toString());
 
879
 
 
880
    v = callArgs.at(1);
 
881
    dv = qdbus_cast<QDBusVariant>(v);
 
882
    QCOMPARE(dv.variant().type(), QVariant::String);
 
883
    QCOMPARE(dv.variant().toString(), arg4.variant().toString());
 
884
 
 
885
    // verify that we got the replies as expected
 
886
    QCOMPARE(retArg.variant(), arg3.variant());
 
887
    QCOMPARE(retArg2.variant(), arg4.variant());
 
888
}
 
889
 
 
890
void tst_QDBusInterface::invokeMethodWithComplexReturnPeer()
 
891
{
 
892
    QDBusConnection con("peer");
 
893
    QDBusInterface iface(QString(), QLatin1String("/"),
 
894
                         TEST_INTERFACE_NAME, con);
 
895
 
 
896
    resetPeer();
 
897
    QList<int> retArg;
 
898
 
 
899
    // make the SLOT call without a return type
 
900
    QList<int> arg = QList<int>() << 42 << -47;
 
901
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
 
902
    QCOMPARE(callCountPeer(), 1);
 
903
 
 
904
    // verify what the callee received
 
905
    QVariantList callArgs = callArgsPeer();
 
906
    QCOMPARE(callArgs.count(), 1);
 
907
    QVariant v = callArgs.at(0);
 
908
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
 
909
    QCOMPARE(qdbus_cast<QList<int> >(v), arg);
 
910
 
 
911
    // verify that we got the reply as expected
 
912
    QCOMPARE(retArg, arg);
 
913
 
 
914
    // make the INVOKABLE call without a return type
 
915
    QList<int> arg2 = QList<int>() << 24 << -74;
 
916
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
 
917
    QCOMPARE(callCountPeer(), 2);
 
918
 
 
919
    // verify what the callee received
 
920
    callArgs = callArgsPeer();
 
921
    QCOMPARE(callArgs.count(), 1);
 
922
    v = callArgs.at(0);
 
923
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
 
924
    QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
 
925
 
 
926
    // verify that we got the reply as expected
 
927
    QCOMPARE(retArg, arg2);
 
928
}
 
929
 
 
930
void tst_QDBusInterface::signal()
 
931
{
 
932
    QDBusConnection con = QDBusConnection::sessionBus();
 
933
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
934
                         TEST_INTERFACE_NAME);
 
935
 
 
936
    QString arg = "So long and thanks for all the fish";
 
937
    {
 
938
        Spy spy;
 
939
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
940
 
 
941
        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
942
        QCOMPARE(spy.count, 1);
 
943
        QCOMPARE(spy.received, arg);
 
944
    }
 
945
 
 
946
    QDBusInterface iface2(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
947
                          TEST_INTERFACE_NAME);
 
948
    {
 
949
        Spy spy;
 
950
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
951
        spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
952
 
 
953
        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
954
        QCOMPARE(spy.count, 2);
 
955
        QCOMPARE(spy.received, arg);
 
956
    }
 
957
 
 
958
    {
 
959
        Spy spy, spy2;
 
960
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
961
        spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
962
 
 
963
        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
964
        QCOMPARE(spy.count, 1);
 
965
        QCOMPARE(spy.received, arg);
 
966
        QCOMPARE(spy2.count, 1);
 
967
        QCOMPARE(spy2.received, arg);
 
968
    }
 
969
}
 
970
 
 
971
void tst_QDBusInterface::signalPeer()
 
972
{
 
973
    QDBusConnection con("peer");
 
974
    QDBusInterface iface(QString(), QLatin1String("/"),
 
975
                         TEST_INTERFACE_NAME, con);
 
976
 
 
977
    QString arg = "So long and thanks for all the fish";
 
978
    {
 
979
        Spy spy;
 
980
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
981
 
 
982
        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
983
        QCOMPARE(spy.count, 1);
 
984
        QCOMPARE(spy.received, arg);
 
985
    }
 
986
 
 
987
    QDBusInterface iface2(QString(), QLatin1String("/"),
 
988
                          TEST_INTERFACE_NAME, con);
 
989
    {
 
990
        Spy spy;
 
991
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
992
        spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
993
 
 
994
        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
995
        QCOMPARE(spy.count, 2);
 
996
        QCOMPARE(spy.received, arg);
 
997
    }
 
998
 
 
999
    {
 
1000
        Spy spy, spy2;
 
1001
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
1002
        spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
 
1003
 
 
1004
        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
 
1005
        QCOMPARE(spy.count, 1);
 
1006
        QCOMPARE(spy.received, arg);
 
1007
        QCOMPARE(spy2.count, 1);
 
1008
        QCOMPARE(spy2.received, arg);
 
1009
    }
 
1010
}
 
1011
 
 
1012
void tst_QDBusInterface::propertyRead()
 
1013
{
 
1014
    QDBusConnection con = QDBusConnection::sessionBus();
 
1015
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
1016
                         TEST_INTERFACE_NAME);
 
1017
 
 
1018
    int arg = obj.m_prop1 = 42;
 
1019
    MyObject::callCount = 0;
 
1020
 
 
1021
    QVariant v = iface.property("prop1");
 
1022
    QVERIFY(v.isValid());
 
1023
    QCOMPARE(v.userType(), int(QVariant::Int));
 
1024
    QCOMPARE(v.toInt(), arg);
 
1025
    QCOMPARE(MyObject::callCount, 1);
 
1026
}
 
1027
 
 
1028
void tst_QDBusInterface::propertyWrite()
 
1029
{
 
1030
    QDBusConnection con = QDBusConnection::sessionBus();
 
1031
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
1032
                         TEST_INTERFACE_NAME);
 
1033
 
 
1034
    int arg = 42;
 
1035
    obj.m_prop1 = 0;
 
1036
    MyObject::callCount = 0;
 
1037
 
 
1038
    QVERIFY(iface.setProperty("prop1", arg));
 
1039
    QCOMPARE(MyObject::callCount, 1);
 
1040
    QCOMPARE(obj.m_prop1, arg);
 
1041
}
 
1042
 
 
1043
void tst_QDBusInterface::complexPropertyRead()
 
1044
{
 
1045
    QDBusConnection con = QDBusConnection::sessionBus();
 
1046
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
1047
                         TEST_INTERFACE_NAME);
 
1048
 
 
1049
    QList<int> arg = obj.m_complexProp = QList<int>() << 42 << -47;
 
1050
    MyObject::callCount = 0;
 
1051
 
 
1052
    QVariant v = iface.property("complexProp");
 
1053
    QVERIFY(v.isValid());
 
1054
    QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
 
1055
    QCOMPARE(v.value<QList<int> >(), arg);
 
1056
    QCOMPARE(MyObject::callCount, 1);
 
1057
}
 
1058
 
 
1059
void tst_QDBusInterface::complexPropertyWrite()
 
1060
{
 
1061
    QDBusConnection con = QDBusConnection::sessionBus();
 
1062
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
 
1063
                         TEST_INTERFACE_NAME);
 
1064
 
 
1065
    QList<int> arg = QList<int>() << -47 << 42;
 
1066
    obj.m_complexProp.clear();
 
1067
    MyObject::callCount = 0;
 
1068
 
 
1069
    QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
 
1070
    QCOMPARE(MyObject::callCount, 1);
 
1071
    QCOMPARE(obj.m_complexProp, arg);
 
1072
}
 
1073
 
 
1074
void tst_QDBusInterface::propertyReadPeer()
 
1075
{
 
1076
    QDBusConnection con("peer");
 
1077
    QDBusInterface iface(QString(), QLatin1String("/"),
 
1078
                         TEST_INTERFACE_NAME, con);
 
1079
 
 
1080
    resetPeer();
 
1081
    int arg = 42;
 
1082
    setProp1Peer(42);
 
1083
 
 
1084
    QVariant v = iface.property("prop1");
 
1085
    QVERIFY(v.isValid());
 
1086
    QCOMPARE(v.userType(), int(QVariant::Int));
 
1087
    QCOMPARE(v.toInt(), arg);
 
1088
    QCOMPARE(callCountPeer(), 1);
 
1089
}
 
1090
 
 
1091
void tst_QDBusInterface::propertyWritePeer()
 
1092
{
 
1093
    QDBusConnection con("peer");
 
1094
    QDBusInterface iface(QString(), QLatin1String("/"),
 
1095
                         TEST_INTERFACE_NAME, con);
 
1096
 
 
1097
    resetPeer();
 
1098
    int arg = 42;
 
1099
    setProp1Peer(0);
 
1100
 
 
1101
    QVERIFY(iface.setProperty("prop1", arg));
 
1102
    QCOMPARE(callCountPeer(), 1);
 
1103
    QCOMPARE(prop1Peer(), arg);
 
1104
}
 
1105
 
 
1106
void tst_QDBusInterface::complexPropertyReadPeer()
 
1107
{
 
1108
    QDBusConnection con("peer");
 
1109
    QDBusInterface iface(QString(), QLatin1String("/"),
 
1110
                         TEST_INTERFACE_NAME, con);
 
1111
 
 
1112
    resetPeer();
 
1113
    QList<int> arg = QList<int>() << 42 << -47;
 
1114
    setComplexPropPeer(arg);
 
1115
 
 
1116
    QVariant v = iface.property("complexProp");
 
1117
    QVERIFY(v.isValid());
 
1118
    QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
 
1119
    QCOMPARE(v.value<QList<int> >(), arg);
 
1120
    QCOMPARE(callCountPeer(), 1);
 
1121
}
 
1122
 
 
1123
void tst_QDBusInterface::complexPropertyWritePeer()
 
1124
{
 
1125
    QDBusConnection con("peer");
 
1126
    QDBusInterface iface(QString(), QLatin1String("/"),
 
1127
                         TEST_INTERFACE_NAME, con);
 
1128
 
 
1129
    resetPeer();
 
1130
    QList<int> arg = QList<int>() << -47 << 42;
 
1131
 
 
1132
    QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
 
1133
    QCOMPARE(callCountPeer(), 1);
 
1134
    QCOMPARE(complexPropPeer(), arg);
 
1135
}
 
1136
 
 
1137
QTEST_MAIN(tst_QDBusInterface)
 
1138
 
 
1139
#include "tst_qdbusinterface.moc"