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
34class tst_QDBusMetaType: public QObject
35{
36 Q_OBJECT
37public:
38 int intStringMap;
39 int stringStringMap;
40 int stringStruct1Map;
41
42private 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
52typedef QPair<QString,QString> StringPair;
53
54struct Struct1 { }; // (s)
55struct Struct2 { }; // (sos)
56struct Struct3 { }; // (sas)
57struct 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};
67struct 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};
73struct 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
81struct Invalid0 { }; // empty
82struct Invalid1 { }; // s
83struct Invalid2 { }; // o
84struct Invalid3 { }; // as
85struct Invalid4 { }; // ay
86struct Invalid5 { }; // ii
87struct Invalid6 { }; // <invalid>
88struct Invalid7 { }; // (<invalid>)
89
90Q_DECLARE_METATYPE(Struct1)
91Q_DECLARE_METATYPE(Struct2)
92Q_DECLARE_METATYPE(Struct3)
93Q_DECLARE_METATYPE(Struct4)
94Q_DECLARE_METATYPE(StringPair)
95Q_DECLARE_METATYPE(Struct5)
96Q_DECLARE_METATYPE(Struct6)
97
98Q_DECLARE_METATYPE(Invalid0)
99Q_DECLARE_METATYPE(Invalid1)
100Q_DECLARE_METATYPE(Invalid2)
101Q_DECLARE_METATYPE(Invalid3)
102Q_DECLARE_METATYPE(Invalid4)
103Q_DECLARE_METATYPE(Invalid5)
104Q_DECLARE_METATYPE(Invalid6)
105Q_DECLARE_METATYPE(Invalid7)
106
107typedef QMap<int, QString> IntStringMap;
108typedef QMap<QString, QString> StringStringMap;
109typedef QMap<QString, Struct1> StringStruct1Map;
110
111Q_DECLARE_METATYPE(QVariant::Type)
112
113QT_BEGIN_NAMESPACE
114QDBusArgument &operator<<(QDBusArgument &arg, const Struct1 &)
115{
116 arg.beginStructure();
117 arg << QString();
118 arg.endStructure();
119 return arg;
120}
121
122QDBusArgument &operator<<(QDBusArgument &arg, const Struct2 &)
123{
124 arg.beginStructure();
125 arg << QString() << QDBusObjectPath() << QString();
126 arg.endStructure();
127 return arg;
128}
129
130QDBusArgument &operator<<(QDBusArgument &arg, const Struct3 &)
131{
132 arg.beginStructure();
133 arg << QString() << QStringList();
134 arg.endStructure();
135 return arg;
136}
137
138QDBusArgument &operator<<(QDBusArgument &arg, const StringPair &s)
139{
140 arg.beginStructure();
141 arg << s.first << s.second;
142 arg.endStructure();
143 return arg;
144}
145
146QDBusArgument &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
154QDBusArgument &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
174QDBusArgument &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
182QDBusArgument &operator<<(QDBusArgument &arg, const Invalid0 &)
183{
184 return arg;
185}
186
187QDBusArgument &operator<<(QDBusArgument &arg, const Invalid1 &)
188{
189 arg << QString();
190 return arg;
191}
192
193QDBusArgument &operator<<(QDBusArgument &arg, const Invalid2 &)
194{
195 arg << QDBusObjectPath();
196 return arg;
197}
198
199QDBusArgument &operator<<(QDBusArgument &arg, const Invalid3 &)
200{
201 arg << QStringList();
202 return arg;
203}
204
205QDBusArgument &operator<<(QDBusArgument &arg, const Invalid4 &)
206{
207 arg << QByteArray();
208 return arg;
209}
210
211QDBusArgument &operator<<(QDBusArgument &arg, const Invalid5 &)
212{
213 arg << 1 << 2;
214 return arg;
215}
216
217// no Invalid6
218
219QDBusArgument &operator<<(QDBusArgument &arg, const Invalid7 &)
220{
221 arg.beginStructure();
222 arg << Invalid0();
223 arg.endStructure();
224 return arg;
225}
226
227const QDBusArgument &operator>>(const QDBusArgument &arg, Struct1 &)
228{ return arg; }
229const QDBusArgument &operator>>(const QDBusArgument &arg, Struct2 &)
230{ return arg; }
231const QDBusArgument &operator>>(const QDBusArgument &arg, Struct3 &)
232{ return arg; }
233const QDBusArgument &operator>>(const QDBusArgument &arg, Struct4 &)
234{ return arg; }
235const QDBusArgument &operator>>(const QDBusArgument &arg, Struct5 &)
236{ return arg; }
237const QDBusArgument &operator>>(const QDBusArgument &arg, Struct6 &)
238{ return arg; }
239const QDBusArgument &operator>>(const QDBusArgument &arg, StringPair &)
240{ return arg; }
241const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid0 &)
242{ return arg; }
243const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid1 &)
244{ return arg; }
245const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid2 &)
246{ return arg; }
247const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid3 &)
248{ return arg; }
249const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid4 &)
250{ return arg; }
251const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid5 &)
252{ return arg; }
253const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid6 &)
254{ return arg; }
255const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid7 &)
256{ return arg; }
257QT_END_NAMESPACE
258
259void 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
290void 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
313void 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
353void tst_QDBusMetaType::staticTypes()
354{
355 QFETCH(QVariant::Type, typeId);
356
357 QString result = QDBusMetaType::typeToSignature(type: typeId);
358 QTEST(result, "signature");
359}
360
361void tst_QDBusMetaType::dynamicTypes()
362{
363 // same test
364 staticTypes();
365}
366
367void 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
387void 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
411QTEST_MAIN(tst_QDBusMetaType)
412
413#include "tst_qdbusmetatype.moc"
414

source code of qtbase/tests/auto/dbus/qdbusmetatype/tst_qdbusmetatype.cpp