1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
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 The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | #include <qcoreapplication.h> |
29 | #include <qdebug.h> |
30 | #include <qvariant.h> |
31 | |
32 | #include <QtTest/QtTest> |
33 | |
34 | #include <QtDBus> |
35 | |
36 | typedef QMap<int,QString> IntStringMap; |
37 | Q_DECLARE_METATYPE(IntStringMap) |
38 | |
39 | struct MyStruct |
40 | { |
41 | int i; |
42 | QString s; |
43 | |
44 | MyStruct() : i(1), s("String" ) { } |
45 | bool operator==(const MyStruct &other) const |
46 | { return i == other.i && s == other.s; } |
47 | }; |
48 | Q_DECLARE_METATYPE(MyStruct) |
49 | |
50 | QDBusArgument &operator<<(QDBusArgument &arg, const MyStruct &ms) |
51 | { |
52 | arg.beginStructure(); |
53 | arg << ms.i << ms.s; |
54 | arg.endStructure(); |
55 | return arg; |
56 | } |
57 | |
58 | const QDBusArgument &operator>>(const QDBusArgument &arg, MyStruct &ms) |
59 | { |
60 | arg.beginStructure(); |
61 | arg >> ms.i >> ms.s; |
62 | arg.endStructure(); |
63 | return arg; |
64 | } |
65 | |
66 | class TypesInterface; |
67 | class tst_QDBusReply: public QObject |
68 | { |
69 | Q_OBJECT |
70 | QDBusInterface *iface; |
71 | TypesInterface *adaptor; |
72 | public: |
73 | tst_QDBusReply(); |
74 | |
75 | private slots: |
76 | void initTestCase() |
77 | { |
78 | qDBusRegisterMetaType<IntStringMap>(); |
79 | qDBusRegisterMetaType<MyStruct>(); |
80 | } |
81 | |
82 | void init(); |
83 | void unconnected(); |
84 | void simpleTypes(); |
85 | void complexTypes(); |
86 | void wrongTypes(); |
87 | void error(); |
88 | }; |
89 | |
90 | class TypesInterface: public QDBusAbstractAdaptor |
91 | { |
92 | Q_OBJECT |
93 | Q_CLASSINFO("D-Bus Interface" , "org.qtproject.Qt.Autotests.TypesInterface" ) |
94 | public: |
95 | TypesInterface(QObject *parent) |
96 | : QDBusAbstractAdaptor(parent) |
97 | { } |
98 | |
99 | public slots: |
100 | bool retrieveBool() |
101 | { |
102 | return true; |
103 | } |
104 | |
105 | uchar retrieveUChar() |
106 | { |
107 | return 'A'; |
108 | } |
109 | |
110 | short retrieveShort() |
111 | { |
112 | return -47; |
113 | } |
114 | |
115 | ushort retrieveUShort() |
116 | { |
117 | return 42U; |
118 | } |
119 | |
120 | int retrieveInt() |
121 | { |
122 | return -470000; |
123 | } |
124 | |
125 | uint retrieveUInt() |
126 | { |
127 | return 42424242; |
128 | } |
129 | |
130 | qlonglong retrieveLongLong() |
131 | { |
132 | return -(Q_INT64_C(1) << 32); |
133 | } |
134 | |
135 | qulonglong retrieveULongLong() |
136 | { |
137 | return Q_INT64_C(1) << 32; |
138 | } |
139 | |
140 | double retrieveDouble() |
141 | { |
142 | return 1.5; |
143 | } |
144 | |
145 | QString retrieveString() |
146 | { |
147 | return "This string you should see" ; |
148 | } |
149 | |
150 | QDBusObjectPath retrieveObjectPath() |
151 | { |
152 | return QDBusObjectPath("/" ); |
153 | } |
154 | |
155 | QDBusSignature retrieveSignature() |
156 | { |
157 | return QDBusSignature("g" ); |
158 | } |
159 | |
160 | QDBusVariant retrieveVariant() |
161 | { |
162 | return QDBusVariant(retrieveString()); |
163 | } |
164 | |
165 | QStringList retrieveStringList() |
166 | { |
167 | return QStringList() << "one" << "two" ; |
168 | } |
169 | |
170 | QByteArray retrieveByteArray() |
171 | { |
172 | return "Hello, World" ; |
173 | } |
174 | |
175 | QVariantList retrieveList() |
176 | { |
177 | return QVariantList() << retrieveInt() << retrieveString() |
178 | << retrieveByteArray(); |
179 | } |
180 | |
181 | QList<QDBusObjectPath> retrieveObjectPathList() |
182 | { |
183 | return QList<QDBusObjectPath>() << QDBusObjectPath("/" ) << QDBusObjectPath("/foo" ); |
184 | } |
185 | |
186 | QVariantMap retrieveMap() |
187 | { |
188 | QVariantMap map; |
189 | map["one" ] = 1; |
190 | map["two" ] = 2U; |
191 | map["string" ] = retrieveString(); |
192 | map["stringlist" ] = retrieveStringList(); |
193 | return map; |
194 | } |
195 | |
196 | IntStringMap retrieveIntStringMap() |
197 | { |
198 | IntStringMap map; |
199 | map[1] = "1" ; |
200 | map[2] = "2" ; |
201 | map[-1231456] = "foo" ; |
202 | return map; |
203 | } |
204 | |
205 | MyStruct retrieveStruct() |
206 | { |
207 | return MyStruct(); |
208 | } |
209 | }; |
210 | |
211 | tst_QDBusReply::tst_QDBusReply() |
212 | { |
213 | adaptor = new TypesInterface(this); |
214 | QDBusConnection::sessionBus().registerObject(path: "/" , object: this); |
215 | |
216 | iface = new QDBusInterface(QDBusConnection::sessionBus().baseService(), "/" , |
217 | "org.qtproject.Qt.Autotests.TypesInterface" , |
218 | QDBusConnection::sessionBus(), |
219 | this); |
220 | } |
221 | |
222 | void tst_QDBusReply::init() |
223 | { |
224 | QVERIFY(iface); |
225 | QVERIFY(iface->isValid()); |
226 | } |
227 | |
228 | void tst_QDBusReply::unconnected() |
229 | { |
230 | QDBusConnection con("invalid stored connection" ); |
231 | QVERIFY(!con.isConnected()); |
232 | QDBusInterface iface("doesnt.matter" , "/" , "doesnt.matter" , con); |
233 | QVERIFY(!iface.isValid()); |
234 | |
235 | QDBusReply<void> rvoid = iface.asyncCall(method: "ReloadConfig" ); |
236 | QVERIFY(!rvoid.isValid()); |
237 | |
238 | QDBusReply<QString> rstring = iface.asyncCall(method: "GetId" ); |
239 | QVERIFY(!rstring.isValid()); |
240 | QVERIFY(rstring.value().isEmpty()); |
241 | } |
242 | |
243 | void tst_QDBusReply::simpleTypes() |
244 | { |
245 | QDBusReply<bool> rbool = iface->call(mode: QDBus::BlockWithGui, method: "retrieveBool" ); |
246 | QVERIFY(rbool.isValid()); |
247 | QCOMPARE(rbool.value(), adaptor->retrieveBool()); |
248 | |
249 | QDBusReply<uchar> ruchar = iface->call(mode: QDBus::BlockWithGui, method: "retrieveUChar" ); |
250 | QVERIFY(ruchar.isValid()); |
251 | QCOMPARE(ruchar.value(), adaptor->retrieveUChar()); |
252 | |
253 | QDBusReply<short> rshort = iface->call(mode: QDBus::BlockWithGui, method: "retrieveShort" ); |
254 | QVERIFY(rshort.isValid()); |
255 | QCOMPARE(rshort.value(), adaptor->retrieveShort()); |
256 | |
257 | QDBusReply<ushort> rushort = iface->call(mode: QDBus::BlockWithGui, method: "retrieveUShort" ); |
258 | QVERIFY(rushort.isValid()); |
259 | QCOMPARE(rushort.value(), adaptor->retrieveUShort()); |
260 | |
261 | QDBusReply<int> rint = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
262 | QVERIFY(rint.isValid()); |
263 | QCOMPARE(rint.value(), adaptor->retrieveInt()); |
264 | |
265 | QDBusReply<uint> ruint = iface->call(mode: QDBus::BlockWithGui, method: "retrieveUInt" ); |
266 | QVERIFY(ruint.isValid()); |
267 | QCOMPARE(ruint.value(), adaptor->retrieveUInt()); |
268 | |
269 | QDBusReply<qlonglong> rqlonglong = iface->call(mode: QDBus::BlockWithGui, method: "retrieveLongLong" ); |
270 | QVERIFY(rqlonglong.isValid()); |
271 | QCOMPARE(rqlonglong.value(), adaptor->retrieveLongLong()); |
272 | |
273 | QDBusReply<qulonglong> rqulonglong = iface->call(mode: QDBus::BlockWithGui, method: "retrieveULongLong" ); |
274 | QVERIFY(rqulonglong.isValid()); |
275 | QCOMPARE(rqulonglong.value(), adaptor->retrieveULongLong()); |
276 | |
277 | QDBusReply<double> rdouble = iface->call(mode: QDBus::BlockWithGui, method: "retrieveDouble" ); |
278 | QVERIFY(rdouble.isValid()); |
279 | QCOMPARE(rdouble.value(), adaptor->retrieveDouble()); |
280 | |
281 | QDBusReply<QString> rstring = iface->call(mode: QDBus::BlockWithGui, method: "retrieveString" ); |
282 | QVERIFY(rstring.isValid()); |
283 | QCOMPARE(rstring.value(), adaptor->retrieveString()); |
284 | |
285 | QDBusReply<QDBusObjectPath> robjectpath = iface->call(mode: QDBus::BlockWithGui, method: "retrieveObjectPath" ); |
286 | QVERIFY(robjectpath.isValid()); |
287 | QCOMPARE(robjectpath.value().path(), adaptor->retrieveObjectPath().path()); |
288 | |
289 | QDBusReply<QDBusSignature> rsignature = iface->call(mode: QDBus::BlockWithGui, method: "retrieveSignature" ); |
290 | QVERIFY(rsignature.isValid()); |
291 | QCOMPARE(rsignature.value().signature(), adaptor->retrieveSignature().signature()); |
292 | |
293 | QDBusReply<QDBusVariant> rdbusvariant = iface->call(mode: QDBus::BlockWithGui, method: "retrieveVariant" ); |
294 | QVERIFY(rdbusvariant.isValid()); |
295 | QCOMPARE(rdbusvariant.value().variant(), adaptor->retrieveVariant().variant()); |
296 | |
297 | QDBusReply<QVariant> rvariant = iface->call(mode: QDBus::BlockWithGui, method: "retrieveVariant" ); |
298 | QVERIFY(rvariant.isValid()); |
299 | QCOMPARE(rvariant.value(), adaptor->retrieveVariant().variant()); |
300 | |
301 | QDBusReply<QByteArray> rbytearray = iface->call(mode: QDBus::BlockWithGui, method: "retrieveByteArray" ); |
302 | QVERIFY(rbytearray.isValid()); |
303 | QCOMPARE(rbytearray.value(), adaptor->retrieveByteArray()); |
304 | |
305 | QDBusReply<QStringList> rstringlist = iface->call(mode: QDBus::BlockWithGui, method: "retrieveStringList" ); |
306 | QVERIFY(rstringlist.isValid()); |
307 | QCOMPARE(rstringlist.value(), adaptor->retrieveStringList()); |
308 | } |
309 | |
310 | void tst_QDBusReply::complexTypes() |
311 | { |
312 | QDBusReply<QVariantList> rlist = iface->call(mode: QDBus::BlockWithGui, method: "retrieveList" ); |
313 | QVERIFY(rlist.isValid()); |
314 | QCOMPARE(rlist.value(), adaptor->retrieveList()); |
315 | |
316 | QDBusReply<QList<QDBusObjectPath> > rolist = iface->call(mode: QDBus::BlockWithGui, method: "retrieveObjectPathList" ); |
317 | QVERIFY(rolist.isValid()); |
318 | QCOMPARE(rolist.value(), adaptor->retrieveObjectPathList()); |
319 | |
320 | QDBusReply<QVariantMap> rmap = iface->call(mode: QDBus::BlockWithGui, method: "retrieveMap" ); |
321 | QVERIFY(rmap.isValid()); |
322 | QCOMPARE(rmap.value(), adaptor->retrieveMap()); |
323 | |
324 | QDBusReply<IntStringMap> rismap = iface->call(mode: QDBus::BlockWithGui, method: "retrieveIntStringMap" ); |
325 | QVERIFY(rismap.isValid()); |
326 | QCOMPARE(rismap.value(), adaptor->retrieveIntStringMap()); |
327 | |
328 | QDBusReply<MyStruct> rstruct = iface->call(mode: QDBus::BlockWithGui, method: "retrieveStruct" ); |
329 | QVERIFY(rstruct.isValid()); |
330 | QCOMPARE(rstruct.value(), adaptor->retrieveStruct()); |
331 | } |
332 | |
333 | void tst_QDBusReply::wrongTypes() |
334 | { |
335 | QDBusReply<bool> rbool = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
336 | QVERIFY(!rbool.isValid()); |
337 | |
338 | rbool = iface->call(mode: QDBus::BlockWithGui, method: "retrieveShort" ); |
339 | QVERIFY(!rbool.isValid()); |
340 | |
341 | rbool = iface->call(mode: QDBus::BlockWithGui, method: "retrieveStruct" ); |
342 | QVERIFY(!rbool.isValid()); |
343 | |
344 | QDBusReply<short> rshort = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
345 | QVERIFY(!rshort.isValid()); |
346 | |
347 | rshort = iface->call(mode: QDBus::BlockWithGui, method: "retrieveBool" ); |
348 | QVERIFY(!rshort.isValid()); |
349 | |
350 | rshort = iface->call(mode: QDBus::BlockWithGui, method: "retrieveStruct" ); |
351 | QVERIFY(!rshort.isValid()); |
352 | |
353 | QDBusReply<MyStruct> rstruct = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
354 | QVERIFY(!rstruct.isValid()); |
355 | |
356 | rstruct = iface->call(mode: QDBus::BlockWithGui, method: "retrieveShort" ); |
357 | QVERIFY(!rstruct.isValid()); |
358 | |
359 | rstruct = iface->call(mode: QDBus::BlockWithGui, method: "retrieveIntStringMap" ); |
360 | QVERIFY(!rstruct.isValid()); |
361 | } |
362 | |
363 | void tst_QDBusReply::error() |
364 | { |
365 | { |
366 | // Wrong type |
367 | QDBusReply<bool> result = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
368 | QVERIFY(result.error().isValid()); |
369 | } |
370 | { |
371 | // Wrong type, const version |
372 | const QDBusReply<bool> result = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
373 | QVERIFY(result.error().isValid()); |
374 | } |
375 | { |
376 | // Ok type |
377 | QDBusReply<void> result = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
378 | QVERIFY(!result.error().isValid()); |
379 | } |
380 | { |
381 | // Ok type, const version |
382 | const QDBusReply<void> result = iface->call(mode: QDBus::BlockWithGui, method: "retrieveInt" ); |
383 | QVERIFY(!result.error().isValid()); |
384 | } |
385 | } |
386 | |
387 | QTEST_MAIN(tst_QDBusReply) |
388 | |
389 | #include "tst_qdbusreply.moc" |
390 | |