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 <qmetatype.h> |
30 | #include <QtTest/QtTest> |
31 | |
32 | #include <QtDBus/QtDBus> |
33 | |
34 | class tst_QDBusMetaType: public QObject |
35 | { |
36 | Q_OBJECT |
37 | public: |
38 | int intStringMap; |
39 | int stringStringMap; |
40 | int stringStruct1Map; |
41 | |
42 | private slots: |
43 | void initTestCase(); |
44 | void staticTypes_data(); |
45 | void staticTypes(); |
46 | void dynamicTypes_data(); |
47 | void dynamicTypes(); |
48 | void invalidTypes_data(); |
49 | void invalidTypes(); |
50 | }; |
51 | |
52 | typedef QPair<QString,QString> StringPair; |
53 | |
54 | struct Struct1 { }; // (s) |
55 | struct Struct2 { }; // (sos) |
56 | struct Struct3 { }; // (sas) |
57 | struct Struct4 // (ssa(ss)sayasx) |
58 | { |
59 | QString m1; |
60 | QString m2; |
61 | QList<StringPair> m3; |
62 | QString m4; |
63 | QByteArray m5; |
64 | QStringList m6; |
65 | qlonglong m7; |
66 | }; |
67 | struct Struct5 // a{sa{sv}} - non-standard outer struct is used as a local |
68 | { // container, see marshalling operator below. |
69 | QVariantMap m1; |
70 | QVariantMap m2; |
71 | QVariantMap m3; |
72 | }; |
73 | struct Struct6 // av - non-standard outer struct is used as a local container, |
74 | { // see marshalling operator below. |
75 | QVariant v1; |
76 | QVariant v2; |
77 | QVariant v3; |
78 | }; |
79 | |
80 | |
81 | struct Invalid0 { }; // empty |
82 | struct Invalid1 { }; // s |
83 | struct Invalid2 { }; // o |
84 | struct Invalid3 { }; // as |
85 | struct Invalid4 { }; // ay |
86 | struct Invalid5 { }; // ii |
87 | struct Invalid6 { }; // <invalid> |
88 | struct Invalid7 { }; // (<invalid>) |
89 | |
90 | Q_DECLARE_METATYPE(Struct1) |
91 | Q_DECLARE_METATYPE(Struct2) |
92 | Q_DECLARE_METATYPE(Struct3) |
93 | Q_DECLARE_METATYPE(Struct4) |
94 | Q_DECLARE_METATYPE(StringPair) |
95 | Q_DECLARE_METATYPE(Struct5) |
96 | Q_DECLARE_METATYPE(Struct6) |
97 | |
98 | Q_DECLARE_METATYPE(Invalid0) |
99 | Q_DECLARE_METATYPE(Invalid1) |
100 | Q_DECLARE_METATYPE(Invalid2) |
101 | Q_DECLARE_METATYPE(Invalid3) |
102 | Q_DECLARE_METATYPE(Invalid4) |
103 | Q_DECLARE_METATYPE(Invalid5) |
104 | Q_DECLARE_METATYPE(Invalid6) |
105 | Q_DECLARE_METATYPE(Invalid7) |
106 | |
107 | typedef QMap<int, QString> IntStringMap; |
108 | typedef QMap<QString, QString> StringStringMap; |
109 | typedef QMap<QString, Struct1> StringStruct1Map; |
110 | |
111 | Q_DECLARE_METATYPE(QVariant::Type) |
112 | |
113 | QT_BEGIN_NAMESPACE |
114 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct1 &) |
115 | { |
116 | arg.beginStructure(); |
117 | arg << QString(); |
118 | arg.endStructure(); |
119 | return arg; |
120 | } |
121 | |
122 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct2 &) |
123 | { |
124 | arg.beginStructure(); |
125 | arg << QString() << QDBusObjectPath() << QString(); |
126 | arg.endStructure(); |
127 | return arg; |
128 | } |
129 | |
130 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct3 &) |
131 | { |
132 | arg.beginStructure(); |
133 | arg << QString() << QStringList(); |
134 | arg.endStructure(); |
135 | return arg; |
136 | } |
137 | |
138 | QDBusArgument &operator<<(QDBusArgument &arg, const StringPair &s) |
139 | { |
140 | arg.beginStructure(); |
141 | arg << s.first << s.second; |
142 | arg.endStructure(); |
143 | return arg; |
144 | } |
145 | |
146 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct4 &s) |
147 | { |
148 | arg.beginStructure(); |
149 | arg << s.m1 << s.m2 << s.m3 << s.m4 << s.m5 << s.m6 << s.m7; |
150 | arg.endStructure(); |
151 | return arg; |
152 | } |
153 | |
154 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct5 &s) |
155 | { |
156 | arg.beginMap(keyMetaTypeId: qMetaTypeId<QString>(), valueMetaTypeId: qMetaTypeId<QVariantMap>()); |
157 | |
158 | arg.beginMapEntry(); |
159 | arg << QStringLiteral("map1" ) << s.m1; |
160 | arg.endMapEntry(); |
161 | |
162 | arg.beginMapEntry(); |
163 | arg << QStringLiteral("map2" ) << s.m2; |
164 | arg.endMapEntry(); |
165 | |
166 | arg.beginMapEntry(); |
167 | arg << QStringLiteral("map3" ) << s.m3; |
168 | arg.endMapEntry(); |
169 | |
170 | arg.endMap(); |
171 | return arg; |
172 | } |
173 | |
174 | QDBusArgument &operator<<(QDBusArgument &arg, const Struct6 &s) |
175 | { |
176 | arg.beginArray(elementMetaTypeId: qMetaTypeId<QDBusVariant>()); |
177 | arg << QDBusVariant(s.v1) << QDBusVariant(s.v2) << QDBusVariant(s.v3); |
178 | arg.endArray(); |
179 | return arg; |
180 | } |
181 | |
182 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid0 &) |
183 | { |
184 | return arg; |
185 | } |
186 | |
187 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid1 &) |
188 | { |
189 | arg << QString(); |
190 | return arg; |
191 | } |
192 | |
193 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid2 &) |
194 | { |
195 | arg << QDBusObjectPath(); |
196 | return arg; |
197 | } |
198 | |
199 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid3 &) |
200 | { |
201 | arg << QStringList(); |
202 | return arg; |
203 | } |
204 | |
205 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid4 &) |
206 | { |
207 | arg << QByteArray(); |
208 | return arg; |
209 | } |
210 | |
211 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid5 &) |
212 | { |
213 | arg << 1 << 2; |
214 | return arg; |
215 | } |
216 | |
217 | // no Invalid6 |
218 | |
219 | QDBusArgument &operator<<(QDBusArgument &arg, const Invalid7 &) |
220 | { |
221 | arg.beginStructure(); |
222 | arg << Invalid0(); |
223 | arg.endStructure(); |
224 | return arg; |
225 | } |
226 | |
227 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct1 &) |
228 | { return arg; } |
229 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct2 &) |
230 | { return arg; } |
231 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct3 &) |
232 | { return arg; } |
233 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct4 &) |
234 | { return arg; } |
235 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct5 &) |
236 | { return arg; } |
237 | const QDBusArgument &operator>>(const QDBusArgument &arg, Struct6 &) |
238 | { return arg; } |
239 | const QDBusArgument &operator>>(const QDBusArgument &arg, StringPair &) |
240 | { return arg; } |
241 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid0 &) |
242 | { return arg; } |
243 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid1 &) |
244 | { return arg; } |
245 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid2 &) |
246 | { return arg; } |
247 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid3 &) |
248 | { return arg; } |
249 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid4 &) |
250 | { return arg; } |
251 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid5 &) |
252 | { return arg; } |
253 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid6 &) |
254 | { return arg; } |
255 | const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid7 &) |
256 | { return arg; } |
257 | QT_END_NAMESPACE |
258 | |
259 | void tst_QDBusMetaType::initTestCase() |
260 | { |
261 | qDBusRegisterMetaType<Struct1>(); |
262 | qDBusRegisterMetaType<Struct2>(); |
263 | qDBusRegisterMetaType<Struct3>(); |
264 | qDBusRegisterMetaType<Struct4>(); |
265 | qDBusRegisterMetaType<Struct5>(); |
266 | qDBusRegisterMetaType<Struct6>(); |
267 | qDBusRegisterMetaType<StringPair>(); |
268 | |
269 | qDBusRegisterMetaType<QList<Struct1> >(); |
270 | qDBusRegisterMetaType<QList<Struct2> >(); |
271 | qDBusRegisterMetaType<QList<Struct3> >(); |
272 | qDBusRegisterMetaType<QList<Struct4> >(); |
273 | |
274 | qDBusRegisterMetaType<Invalid0>(); |
275 | qDBusRegisterMetaType<Invalid1>(); |
276 | qDBusRegisterMetaType<Invalid2>(); |
277 | qDBusRegisterMetaType<Invalid3>(); |
278 | qDBusRegisterMetaType<Invalid4>(); |
279 | qDBusRegisterMetaType<Invalid5>(); |
280 | // don't register Invalid6 |
281 | qDBusRegisterMetaType<Invalid7>(); |
282 | |
283 | qDBusRegisterMetaType<QList<Invalid0> >(); |
284 | |
285 | intStringMap = qDBusRegisterMetaType<QMap<int, QString> >(); |
286 | stringStringMap = qDBusRegisterMetaType<QMap<QString, QString> >(); |
287 | stringStruct1Map = qDBusRegisterMetaType<QMap<QString, Struct1> >(); |
288 | } |
289 | |
290 | void tst_QDBusMetaType::staticTypes_data() |
291 | { |
292 | QTest::addColumn<QVariant::Type>(name: "typeId" ); |
293 | QTest::addColumn<QString>(name: "signature" ); |
294 | |
295 | QTest::newRow(dataTag: "uchar" ) << QVariant::Type(QMetaType::UChar) << "y" ; |
296 | QTest::newRow(dataTag: "bool" ) << QVariant::Bool << "b" ; |
297 | QTest::newRow(dataTag: "short" ) << QVariant::Type(QMetaType::Short) << "n" ; |
298 | QTest::newRow(dataTag: "ushort" ) << QVariant::Type(QMetaType::UShort) << "q" ; |
299 | QTest::newRow(dataTag: "int" ) << QVariant::Int << "i" ; |
300 | QTest::newRow(dataTag: "uint" ) << QVariant::UInt << "u" ; |
301 | QTest::newRow(dataTag: "qlonglong" ) << QVariant::LongLong << "x" ; |
302 | QTest::newRow(dataTag: "qulonglong" ) << QVariant::ULongLong << "t" ; |
303 | QTest::newRow(dataTag: "double" ) << QVariant::Double << "d" ; |
304 | QTest::newRow(dataTag: "QString" ) << QVariant::String << "s" ; |
305 | QTest::newRow(dataTag: "QDBusObjectPath" ) << QVariant::Type(qMetaTypeId<QDBusObjectPath>()) << "o" ; |
306 | QTest::newRow(dataTag: "QDBusSignature" ) << QVariant::Type(qMetaTypeId<QDBusSignature>()) << "g" ; |
307 | QTest::newRow(dataTag: "QDBusVariant" ) << QVariant::Type(qMetaTypeId<QDBusVariant>()) << "v" ; |
308 | |
309 | QTest::newRow(dataTag: "QByteArray" ) << QVariant::ByteArray << "ay" ; |
310 | QTest::newRow(dataTag: "QStringList" ) << QVariant::StringList << "as" ; |
311 | } |
312 | |
313 | void tst_QDBusMetaType::dynamicTypes_data() |
314 | { |
315 | QTest::addColumn<QVariant::Type>(name: "typeId" ); |
316 | QTest::addColumn<QString>(name: "signature" ); |
317 | |
318 | QTest::newRow(dataTag: "QVariantList" ) << QVariant::List << "av" ; |
319 | QTest::newRow(dataTag: "QVariantMap" ) << QVariant::Map << "a{sv}" ; |
320 | QTest::newRow(dataTag: "QDate" ) << QVariant::Date << "(iii)" ; |
321 | QTest::newRow(dataTag: "QTime" ) << QVariant::Time << "(iiii)" ; |
322 | QTest::newRow(dataTag: "QDateTime" ) << QVariant::DateTime << "((iii)(iiii)i)" ; |
323 | QTest::newRow(dataTag: "QRect" ) << QVariant::Rect << "(iiii)" ; |
324 | QTest::newRow(dataTag: "QRectF" ) << QVariant::RectF << "(dddd)" ; |
325 | QTest::newRow(dataTag: "QSize" ) << QVariant::Size << "(ii)" ; |
326 | QTest::newRow(dataTag: "QSizeF" ) << QVariant::SizeF << "(dd)" ; |
327 | QTest::newRow(dataTag: "QPoint" ) << QVariant::Point << "(ii)" ; |
328 | QTest::newRow(dataTag: "QPointF" ) << QVariant::PointF << "(dd)" ; |
329 | QTest::newRow(dataTag: "QLine" ) << QVariant::Line << "((ii)(ii))" ; |
330 | QTest::newRow(dataTag: "QLineF" ) << QVariant::LineF << "((dd)(dd))" ; |
331 | |
332 | QTest::newRow(dataTag: "Struct1" ) << QVariant::Type(qMetaTypeId<Struct1>()) << "(s)" ; |
333 | QTest::newRow(dataTag: "QList<Struct1>" ) << QVariant::Type(qMetaTypeId<QList<Struct1> >()) << "a(s)" ; |
334 | |
335 | QTest::newRow(dataTag: "Struct2" ) << QVariant::Type(qMetaTypeId<Struct2>()) << "(sos)" ; |
336 | QTest::newRow(dataTag: "QList<Struct2>" ) << QVariant::Type(qMetaTypeId<QList<Struct2> >()) << "a(sos)" ; |
337 | |
338 | QTest::newRow(dataTag: "QList<Struct3>" ) << QVariant::Type(qMetaTypeId<QList<Struct3> >()) << "a(sas)" ; |
339 | QTest::newRow(dataTag: "Struct3" ) << QVariant::Type(qMetaTypeId<Struct3>()) << "(sas)" ; |
340 | |
341 | QTest::newRow(dataTag: "Struct4" ) << QVariant::Type(qMetaTypeId<Struct4>()) << "(ssa(ss)sayasx)" ; |
342 | QTest::newRow(dataTag: "QList<Struct4>" ) << QVariant::Type(qMetaTypeId<QList<Struct4> >()) << "a(ssa(ss)sayasx)" ; |
343 | |
344 | QTest::newRow(dataTag: "Struct5" ) << QVariant::Type(qMetaTypeId<Struct5>()) << "a{sa{sv}}" ; |
345 | |
346 | QTest::newRow(dataTag: "Struct6" ) << QVariant::Type(qMetaTypeId<Struct6>()) << "av" ; |
347 | |
348 | QTest::newRow(dataTag: "QMap<int,QString>" ) << QVariant::Type(intStringMap) << "a{is}" ; |
349 | QTest::newRow(dataTag: "QMap<QString,QString>" ) << QVariant::Type(stringStringMap) << "a{ss}" ; |
350 | QTest::newRow(dataTag: "QMap<QString,Struct1>" ) << QVariant::Type(stringStruct1Map) << "a{s(s)}" ; |
351 | } |
352 | |
353 | void tst_QDBusMetaType::staticTypes() |
354 | { |
355 | QFETCH(QVariant::Type, typeId); |
356 | |
357 | QString result = QDBusMetaType::typeToSignature(type: typeId); |
358 | QTEST(result, "signature" ); |
359 | } |
360 | |
361 | void tst_QDBusMetaType::dynamicTypes() |
362 | { |
363 | // same test |
364 | staticTypes(); |
365 | } |
366 | |
367 | void tst_QDBusMetaType::invalidTypes_data() |
368 | { |
369 | QTest::addColumn<QVariant::Type>(name: "typeId" ); |
370 | QTest::addColumn<QString>(name: "signature" ); |
371 | |
372 | QTest::newRow(dataTag: "Invalid0" ) << QVariant::Type(qMetaTypeId<Invalid0>()) << "" ; |
373 | QTest::newRow(dataTag: "Invalid1" ) << QVariant::Type(qMetaTypeId<Invalid1>()) << "" ; |
374 | QTest::newRow(dataTag: "Invalid2" ) << QVariant::Type(qMetaTypeId<Invalid2>()) << "" ; |
375 | QTest::newRow(dataTag: "Invalid3" ) << QVariant::Type(qMetaTypeId<Invalid3>()) << "" ; |
376 | QTest::newRow(dataTag: "Invalid4" ) << QVariant::Type(qMetaTypeId<Invalid4>()) << "" ; |
377 | QTest::newRow(dataTag: "Invalid5" ) << QVariant::Type(qMetaTypeId<Invalid5>()) << "" ; |
378 | QTest::newRow(dataTag: "Invalid6" ) << QVariant::Type(qMetaTypeId<Invalid6>()) << "" ; |
379 | QTest::newRow(dataTag: "Invalid7" ) << QVariant::Type(qMetaTypeId<Invalid7>()) << "" ; |
380 | |
381 | QTest::newRow(dataTag: "QList<Invalid0>" ) << QVariant::Type(qMetaTypeId<QList<Invalid0> >()) << "" ; |
382 | |
383 | QTest::newRow(dataTag: "long" ) << QVariant::Type(QMetaType::Long) << "" ; |
384 | QTest::newRow(dataTag: "void*" ) << QVariant::Type(QMetaType::VoidStar) << "" ; |
385 | } |
386 | |
387 | void tst_QDBusMetaType::invalidTypes() |
388 | { |
389 | // same test |
390 | if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid0" ) == 0) |
391 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid0' produces invalid D-BUS signature `<empty>' (Did you forget to call beginStructure() ?)" ); |
392 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid1" ) == 0) |
393 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid1' attempts to redefine basic D-BUS type 's' (QString) (Did you forget to call beginStructure() ?)" ); |
394 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid2" ) == 0) |
395 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid2' attempts to redefine basic D-BUS type 'o' (QDBusObjectPath) (Did you forget to call beginStructure() ?)" ); |
396 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid3" ) == 0) |
397 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid3' attempts to redefine basic D-BUS type 'as' (QStringList) (Did you forget to call beginStructure() ?)" ); |
398 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid4" ) == 0) |
399 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid4' attempts to redefine basic D-BUS type 'ay' (QByteArray) (Did you forget to call beginStructure() ?)" ); |
400 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid5" ) == 0) |
401 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid5' produces invalid D-BUS signature `ii' (Did you forget to call beginStructure() ?)" ); |
402 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "Invalid7" ) == 0) |
403 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `Invalid7' produces invalid D-BUS signature `()' (Did you forget to call beginStructure() ?)" ); |
404 | else if (qstrcmp(str1: QTest::currentDataTag(), str2: "QList<Invalid0>" ) == 0) |
405 | QTest::ignoreMessage(type: QtWarningMsg, message: "QDBusMarshaller: type `QList<Invalid0>' produces invalid D-BUS signature `a' (Did you forget to call beginStructure() ?)" ); |
406 | |
407 | staticTypes(); |
408 | staticTypes(); // run twice: the error messages should be printed once only |
409 | } |
410 | |
411 | QTEST_MAIN(tst_QDBusMetaType) |
412 | |
413 | #include "tst_qdbusmetatype.moc" |
414 | |