1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qcoreapplication.h>
42 #include <qmetatype.h>
43 #include <QtTest/QtTest>
44 
45 #include <QtDBus/QtDBus>
46 #include <private/qdbusmetaobject_p.h>
47 
48 class tst_QDBusMetaObject: public QObject
49 {
50     Q_OBJECT
51 
52     QHash<QString, QDBusMetaObject *> map;
53 public slots:
54     void init();
55 
56 private slots:
57     void initTestCase();
58     void types_data();
59     void types();
60     void methods_data();
61     void methods();
62     void _signals_data();
63     void _signals();
64     void properties_data();
65     void properties();
66 };
67 
68 typedef QPair<QString,QString> StringPair;
69 
70 struct Struct1 { };             // (s)
71 struct Struct4                  // (ssa(ss)sayasx)
72 {
73     QString m1;
74     QString m2;
75     QList<StringPair> m3;
76     QString m4;
77     QByteArray m5;
78     QStringList m6;
79     qlonglong m7;
80 };
81 
82 Q_DECLARE_METATYPE(Struct1)
83 Q_DECLARE_METATYPE(Struct4)
84 Q_DECLARE_METATYPE(StringPair)
85 
86 Q_DECLARE_METATYPE(QList<Struct1>)
87 Q_DECLARE_METATYPE(QList<Struct4>)
88 
89 Q_DECLARE_METATYPE(const QMetaObject*)
90 
91 QT_BEGIN_NAMESPACE
92 QDBusArgument &operator<<(QDBusArgument &arg, const Struct1 &)
93 {
94     arg.beginStructure();
95     arg << QString();
96     arg.endStructure();
97     return arg;
98 }
99 
operator <<(QDBusArgument & arg,const StringPair & s)100 QDBusArgument &operator<<(QDBusArgument &arg, const StringPair &s)
101 {
102     arg.beginStructure();
103     arg << s.first << s.second;
104     arg.endStructure();
105     return arg;
106 }
107 
operator <<(QDBusArgument & arg,const Struct4 & s)108 QDBusArgument &operator<<(QDBusArgument &arg, const Struct4 &s)
109 {
110     arg.beginStructure();
111     arg << s.m1 << s.m2 << s.m3 << s.m4 << s.m5 << s.m6 << s.m7;
112     arg.endStructure();
113     return arg;
114 }
115 
operator >>(const QDBusArgument & arg,Struct1 &)116 const QDBusArgument &operator>>(const QDBusArgument &arg, Struct1 &)
117 { return arg; }
operator >>(const QDBusArgument & arg,Struct4 &)118 const QDBusArgument &operator>>(const QDBusArgument &arg, Struct4 &)
119 { return arg; }
operator >>(const QDBusArgument & arg,StringPair &)120 const QDBusArgument &operator>>(const QDBusArgument &arg, StringPair &)
121 { return arg; }
122 QT_END_NAMESPACE
123 
initTestCase()124 void tst_QDBusMetaObject::initTestCase()
125 {
126     qDBusRegisterMetaType<Struct1>();
127     qDBusRegisterMetaType<Struct4>();
128     qDBusRegisterMetaType<StringPair>();
129 
130     qDBusRegisterMetaType<QList<Struct1> >();
131     qDBusRegisterMetaType<QList<Struct4> >();
132 }
133 
init()134 void tst_QDBusMetaObject::init()
135 {
136     qDeleteAll(map);
137     map.clear();
138 }
139 
140 // test classes
141 class TypesTest1: public QObject
142 {
143     Q_OBJECT
144 
145 signals:
146     void signal(uchar);
147 };
148 const char TypesTest1_xml[] =
149     "<signal name=\"signal\"><arg type=\"y\"/></signal>";
150 
151 class TypesTest2: public QObject
152 {
153     Q_OBJECT
154 
155 signals:
156     void signal(bool);
157 };
158 const char TypesTest2_xml[] =
159     "<signal name=\"signal\"><arg type=\"b\"/></signal>";
160 
161 class TypesTest3: public QObject
162 {
163     Q_OBJECT
164 
165 signals:
166     void signal(short);
167 };
168 const char TypesTest3_xml[] =
169     "<signal name=\"signal\"><arg type=\"n\"/></signal>";
170 
171 class TypesTest4: public QObject
172 {
173     Q_OBJECT
174 
175 signals:
176     void signal(ushort);
177 };
178 const char TypesTest4_xml[] =
179     "<signal name=\"signal\"><arg type=\"q\"/></signal>";
180 
181 class TypesTest5: public QObject
182 {
183     Q_OBJECT
184 
185 signals:
186     void signal(int);
187 };
188 const char TypesTest5_xml[] =
189     "<signal name=\"signal\"><arg type=\"i\"/></signal>";
190 
191 class TypesTest6: public QObject
192 {
193     Q_OBJECT
194 
195 signals:
196     void signal(uint);
197 };
198 const char TypesTest6_xml[] =
199     "<signal name=\"signal\"><arg type=\"u\"/></signal>";
200 
201 class TypesTest7: public QObject
202 {
203     Q_OBJECT
204 
205 signals:
206     void signal(qlonglong);
207 };
208 const char TypesTest7_xml[] =
209     "<signal name=\"signal\"><arg type=\"x\"/></signal>";
210 
211 class TypesTest8: public QObject
212 {
213     Q_OBJECT
214 
215 signals:
216     void signal(qulonglong);
217 };
218 const char TypesTest8_xml[] =
219     "<signal name=\"signal\"><arg type=\"t\"/></signal>";
220 
221 class TypesTest9: public QObject
222 {
223     Q_OBJECT
224 
225 signals:
226     void signal(double);
227 };
228 const char TypesTest9_xml[] =
229     "<signal name=\"signal\"><arg type=\"d\"/></signal>";
230 
231 class TypesTest10: public QObject
232 {
233     Q_OBJECT
234 
235 signals:
236     void signal(QString);
237 };
238 const char TypesTest10_xml[] =
239     "<signal name=\"signal\"><arg type=\"s\"/></signal>";
240 
241 class TypesTest11: public QObject
242 {
243     Q_OBJECT
244 
245 signals:
246     void signal(QDBusObjectPath);
247 };
248 const char TypesTest11_xml[] =
249     "<signal name=\"signal\"><arg type=\"o\"/></signal>";
250 
251 class TypesTest12: public QObject
252 {
253     Q_OBJECT
254 
255 signals:
256     void signal(QDBusSignature);
257 };
258 const char TypesTest12_xml[] =
259     "<signal name=\"signal\"><arg type=\"g\"/></signal>";
260 
261 class TypesTest13: public QObject
262 {
263     Q_OBJECT
264 
265 signals:
266     void signal(QDBusVariant);
267 };
268 const char TypesTest13_xml[] =
269     "<signal name=\"signal\"><arg type=\"v\"/></signal>";
270 
271 class TypesTest14: public QObject
272 {
273     Q_OBJECT
274 
275 signals:
276     void signal(QStringList);
277 };
278 const char TypesTest14_xml[] =
279     "<signal name=\"signal\"><arg type=\"as\"/></signal>";
280 
281 class TypesTest15: public QObject
282 {
283     Q_OBJECT
284 
285 signals:
286     void signal(QByteArray);
287 };
288 const char TypesTest15_xml[] =
289     "<signal name=\"signal\"><arg type=\"ay\"/></signal>";
290 
291 class TypesTest16: public QObject
292 {
293     Q_OBJECT
294 
295 signals:
296     void signal(StringPair);
297 };
298 const char TypesTest16_xml[] =
299     "<signal name=\"signal\"><arg type=\"(ss)\"/>"
300     "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"StringPair\"></signal>";
301 
302 class TypesTest17: public QObject
303 {
304     Q_OBJECT
305 
306 signals:
307     void signal(Struct1);
308 };
309 const char TypesTest17_xml[] =
310     "<signal name=\"signal\"><arg type=\"(s)\"/>"
311     "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"Struct1\"></signal>";
312 
313 class TypesTest18: public QObject
314 {
315     Q_OBJECT
316 
317 signals:
318     void signal(Struct4);
319 };
320 const char TypesTest18_xml[] =
321     "<signal name=\"signal\"><arg type=\"(ssa(ss)sayasx)\"/>"
322     "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"Struct4\"></signal>";
323 
324 class TypesTest19: public QObject
325 {
326     Q_OBJECT
327 
328 signals:
329     void signal(QVariantList);
330 };
331 const char TypesTest19_xml[] =
332     "<signal name=\"signal\"><arg type=\"av\"/>"
333     "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QVariantList\"></signal>";
334 
335 class TypesTest20: public QObject
336 {
337     Q_OBJECT
338 
339 signals:
340     void signal(QVariantMap);
341 };
342 const char TypesTest20_xml[] =
343     "<signal name=\"signal\"><arg type=\"a{sv}\"/>"
344     "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"></signal>";
345 
types_data()346 void tst_QDBusMetaObject::types_data()
347 {
348     QTest::addColumn<const QMetaObject *>("metaobject");
349     QTest::addColumn<QString>("xml");
350 
351     QTest::newRow("byte") << &TypesTest1::staticMetaObject << QString(TypesTest1_xml);
352     QTest::newRow("bool") << &TypesTest2::staticMetaObject << QString(TypesTest2_xml);
353     QTest::newRow("short") << &TypesTest3::staticMetaObject << QString(TypesTest3_xml);
354     QTest::newRow("ushort") << &TypesTest4::staticMetaObject << QString(TypesTest4_xml);
355     QTest::newRow("int") << &TypesTest5::staticMetaObject << QString(TypesTest5_xml);
356     QTest::newRow("uint") << &TypesTest6::staticMetaObject << QString(TypesTest6_xml);
357     QTest::newRow("qlonglong") << &TypesTest7::staticMetaObject << QString(TypesTest7_xml);
358     QTest::newRow("qulonglong") << &TypesTest8::staticMetaObject << QString(TypesTest8_xml);
359     QTest::newRow("double") << &TypesTest9::staticMetaObject << QString(TypesTest9_xml);
360     QTest::newRow("QString") << &TypesTest10::staticMetaObject << QString(TypesTest10_xml);
361     QTest::newRow("QDBusObjectPath") << &TypesTest11::staticMetaObject << QString(TypesTest11_xml);
362     QTest::newRow("QDBusSignature") << &TypesTest12::staticMetaObject << QString(TypesTest12_xml);
363     QTest::newRow("QDBusVariant") << &TypesTest13::staticMetaObject << QString(TypesTest13_xml);
364     QTest::newRow("QStringList") << &TypesTest14::staticMetaObject << QString(TypesTest14_xml);
365     QTest::newRow("QByteArray") << &TypesTest15::staticMetaObject << QString(TypesTest15_xml);
366     QTest::newRow("StringPair") << &TypesTest16::staticMetaObject << QString(TypesTest16_xml);
367     QTest::newRow("Struct1") << &TypesTest17::staticMetaObject << QString(TypesTest17_xml);
368     QTest::newRow("Struct4") << &TypesTest18::staticMetaObject << QString(TypesTest18_xml);
369     QTest::newRow("QVariantList") << &TypesTest19::staticMetaObject << QString(TypesTest19_xml);
370     QTest::newRow("QVariantMap") << &TypesTest20::staticMetaObject << QString(TypesTest20_xml);
371 }
372 
types()373 void tst_QDBusMetaObject::types()
374 {
375     QFETCH(const QMetaObject*, metaobject);
376     QFETCH(QString, xml);
377 
378     // add the rest of the XML tags
379     xml = QString("<node><interface name=\"local.Interface\">%1</interface></node>")
380           .arg(xml);
381 
382     QDBusError error;
383 
384     QMetaObject *result = QDBusMetaObject::createMetaObject("local.Interface", xml,
385                                                             map, error);
386     QVERIFY2(result, qPrintable(error.message()));
387 
388     QCOMPARE(result->enumeratorCount(), 0);
389     QCOMPARE(result->classInfoCount(), 0);
390 
391     // compare the meta objects
392     QCOMPARE(result->methodCount() - result->methodOffset(),
393              metaobject->methodCount() - metaobject->methodOffset());
394     QCOMPARE(result->propertyCount() - result->propertyOffset(),
395              metaobject->propertyCount() - metaobject->propertyOffset());
396 
397     for (int i = metaobject->methodOffset(); i < metaobject->methodCount(); ++i) {
398         QMetaMethod expected = metaobject->method(i);
399 
400         int methodIdx = result->indexOfMethod(expected.signature());
401         QVERIFY(methodIdx != -1);
402         QMetaMethod constructed = result->method(methodIdx);
403 
404         QCOMPARE(int(constructed.access()), int(expected.access()));
405         QCOMPARE(int(constructed.methodType()), int(expected.methodType()));
406         QCOMPARE(constructed.parameterNames(), expected.parameterNames());
407         QCOMPARE(constructed.parameterTypes(), expected.parameterTypes());
408         QCOMPARE(constructed.tag(), expected.tag());
409         QCOMPARE(constructed.typeName(), expected.typeName());
410     }
411 
412     for (int i = metaobject->propertyOffset(); i < metaobject->propertyCount(); ++i) {
413         QMetaProperty expected = metaobject->property(i);
414 
415         int propIdx = result->indexOfProperty(expected.name());
416         QVERIFY(propIdx != -1);
417         QMetaProperty constructed = result->property(propIdx);
418 
419         QCOMPARE(constructed.isDesignable(), expected.isDesignable());
420         QCOMPARE(constructed.isEditable(), expected.isEditable());
421         QCOMPARE(constructed.isEnumType(), expected.isEnumType());
422         QCOMPARE(constructed.isFlagType(), expected.isFlagType());
423         QCOMPARE(constructed.isReadable(), expected.isReadable());
424         QCOMPARE(constructed.isResettable(), expected.isResettable());
425         QCOMPARE(constructed.isScriptable(), expected.isScriptable());
426         QCOMPARE(constructed.isStored(), expected.isStored());
427         QCOMPARE(constructed.isUser(), expected.isUser());
428         QCOMPARE(constructed.isWritable(), expected.isWritable());
429         QCOMPARE(constructed.typeName(), expected.typeName());
430     }
431 }
432 
433 class MethodTest1: public QObject
434 {
435     Q_OBJECT
436 
437 public slots:
method()438     void method() { }
439 };
440 const char MethodTest1_xml[] =
441     "<method name=\"method\" />";
442 
443 class MethodTest2: public QObject
444 {
445     Q_OBJECT
446 
447 public slots:
method(int)448     void method(int) { }
449 };
450 const char MethodTest2_xml[] =
451     "<method name=\"method\"><arg direction=\"in\" type=\"i\"/></method>";
452 
453 class MethodTest3: public QObject
454 {
455     Q_OBJECT
456 
457 public slots:
method(int input0)458     void method(int input0) { Q_UNUSED(input0); }
459 };
460 const char MethodTest3_xml[] =
461     "<method name=\"method\"><arg direction=\"in\" type=\"i\" name=\"input0\"/></method>";
462 
463 class MethodTest4: public QObject
464 {
465     Q_OBJECT
466 
467 public slots:
method()468     int method() { return 0; }
469 };
470 const char MethodTest4_xml[] =
471     "<method name=\"method\"><arg direction=\"out\" type=\"i\"/></method>";
472 const char MethodTest4_xml2[] =
473     "<method name=\"method\"><arg direction=\"out\" type=\"i\" name=\"thisShouldNeverBeSeen\"/></method>";
474 
475 class MethodTest5: public QObject
476 {
477     Q_OBJECT
478 
479 public slots:
method(int input0)480     int method(int input0) { return input0; }
481 };
482 const char MethodTest5_xml[] =
483     "<method name=\"method\">"
484     "<arg direction=\"in\" type=\"i\" name=\"input0\"/>"
485     "<arg direction=\"out\" type=\"i\"/>"
486     "</method>";
487 
488 class MethodTest6: public QObject
489 {
490     Q_OBJECT
491 
492 public slots:
method(int input0,int input1)493     int method(int input0, int input1) { Q_UNUSED(input0); return input1; }
494 };
495 const char MethodTest6_xml[] =
496     "<method name=\"method\">"
497     "<arg direction=\"in\" type=\"i\" name=\"input0\"/>"
498     "<arg direction=\"out\" type=\"i\"/>"
499     "<arg direction=\"in\" type=\"i\" name=\"input1\"/>"
500     "</method>";
501 
502 class MethodTest7: public QObject
503 {
504     Q_OBJECT
505 
506 public slots:
method(int input0,int input1,int & output1)507     int method(int input0, int input1, int &output1) { output1 = input1; return input0; }
508 };
509 const char MethodTest7_xml[] =
510     "<method name=\"method\">"
511     "<arg direction=\"in\" type=\"i\" name=\"input0\"/>"
512     "<arg direction=\"in\" type=\"i\" name=\"input1\"/>"
513     "<arg direction=\"out\" type=\"i\"/>"
514     "<arg direction=\"out\" type=\"i\" name=\"output1\"/>"
515     "</method>";
516 
517 class MethodTest8: public QObject
518 {
519     Q_OBJECT
520 
521 public slots:
method(int input0,int input1,int & output1,int & output2)522     int method(int input0, int input1, int &output1, int &output2) { output1 = output2 = input1; return input0; }
523 };
524 const char MethodTest8_xml[] =
525     "<method name=\"method\">"
526     "<arg direction=\"in\" type=\"i\" name=\"input0\"/>"
527     "<arg direction=\"in\" type=\"i\" name=\"input1\"/>"
528     "<arg direction=\"out\" type=\"i\"/>"
529     "<arg direction=\"out\" type=\"i\" name=\"output1\"/>"
530     "<arg direction=\"out\" type=\"i\" name=\"output2\"/>"
531     "</method>";
532 
533 class MethodTest9: public QObject
534 {
535     Q_OBJECT
536 
537 public slots:
method(int)538     Q_NOREPLY void method(int) { }
539 };
540 const char MethodTest9_xml[] =
541     "<method name=\"method\">"
542     "<arg direction=\"in\" type=\"i\"/>"
543     "<annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>"
544     "</method>";
545 
methods_data()546 void tst_QDBusMetaObject::methods_data()
547 {
548     QTest::addColumn<const QMetaObject *>("metaobject");
549     QTest::addColumn<QString>("xml");
550 
551     QTest::newRow("void-void") << &MethodTest1::staticMetaObject << QString(MethodTest1_xml);
552     QTest::newRow("void-int") << &MethodTest2::staticMetaObject << QString(MethodTest2_xml);
553     QTest::newRow("void-int-with-name") << &MethodTest3::staticMetaObject << QString(MethodTest3_xml);
554     QTest::newRow("int-void") << &MethodTest4::staticMetaObject << QString(MethodTest4_xml);
555     QTest::newRow("int-void2") << &MethodTest4::staticMetaObject << QString(MethodTest4_xml2);
556     QTest::newRow("int-int") << &MethodTest5::staticMetaObject << QString(MethodTest5_xml);
557     QTest::newRow("int-int,int") << &MethodTest6::staticMetaObject << QString(MethodTest6_xml);
558     QTest::newRow("int,int-int,int") << &MethodTest7::staticMetaObject << QString(MethodTest7_xml);
559     QTest::newRow("int,int,int-int,int") << &MethodTest8::staticMetaObject << QString(MethodTest8_xml);
560     QTest::newRow("Q_ASYNC") << &MethodTest9::staticMetaObject << QString(MethodTest9_xml);
561 }
562 
methods()563 void tst_QDBusMetaObject::methods()
564 {
565     types();
566 }
567 
568 class SignalTest1: public QObject
569 {
570     Q_OBJECT
571 
572 signals:
573     void signal();
574 };
575 const char SignalTest1_xml[] =
576     "<signal name=\"signal\" />";
577 
578 class SignalTest2: public QObject
579 {
580     Q_OBJECT
581 
582 signals:
583     void signal(int);
584 };
585 const char SignalTest2_xml[] =
586     "<signal name=\"signal\"><arg type=\"i\"/></signal>";
587 
588 class SignalTest3: public QObject
589 {
590     Q_OBJECT
591 
592 signals:
593     void signal(int output0);
594 };
595 const char SignalTest3_xml[] =
596     "<signal name=\"signal\"><arg type=\"i\" name=\"output0\"/></signal>";
597 
598 class SignalTest4: public QObject
599 {
600     Q_OBJECT
601 
602 signals:
603     void signal(int output0, int);
604 };
605 const char SignalTest4_xml[] =
606     "<signal name=\"signal\"><arg type=\"i\" name=\"output0\"/><arg type=\"i\"/></signal>";
607 
_signals_data()608 void tst_QDBusMetaObject::_signals_data()
609 {
610     QTest::addColumn<const QMetaObject *>("metaobject");
611     QTest::addColumn<QString>("xml");
612 
613     QTest::newRow("empty") << &SignalTest1::staticMetaObject << QString(SignalTest1_xml);
614     QTest::newRow("int") << &SignalTest2::staticMetaObject << QString(SignalTest2_xml);
615     QTest::newRow("int output0") << &SignalTest3::staticMetaObject << QString(SignalTest3_xml);
616     QTest::newRow("int output0,int") << &SignalTest4::staticMetaObject << QString(SignalTest4_xml);
617 }
618 
_signals()619 void tst_QDBusMetaObject::_signals()
620 {
621     types();
622 }
623 
624 class PropertyTest1: public QObject
625 {
626     Q_OBJECT
627     Q_PROPERTY(int property READ property)
628 public:
property()629     int property() { return 0; }
setProperty(int)630     void setProperty(int) { }
631 };
632 const char PropertyTest1_xml[] =
633     "<property name=\"property\" type=\"i\" access=\"read\"/>";
634 
635 class PropertyTest2: public QObject
636 {
637     Q_OBJECT
638     Q_PROPERTY(int property READ property WRITE setProperty)
639 public:
property()640     int property() { return 0; }
setProperty(int)641     void setProperty(int) { }
642 };
643 const char PropertyTest2_xml[] =
644     "<property name=\"property\" type=\"i\" access=\"readwrite\"/>";
645 
646 class PropertyTest3: public QObject
647 {
648     Q_OBJECT
649     Q_PROPERTY(int property WRITE setProperty)
650 public:
property()651     int property() { return 0; }
setProperty(int)652     void setProperty(int) { }
653 };
654 const char PropertyTest3_xml[] =
655     "<property name=\"property\" type=\"i\" access=\"write\"/>";
656 
657 class PropertyTest4: public QObject
658 {
659     Q_OBJECT
660     Q_PROPERTY(Struct1 property WRITE setProperty)
661 public:
property()662     Struct1 property() { return Struct1(); }
setProperty(Struct1)663     void setProperty(Struct1) { }
664 };
665 const char PropertyTest4_xml[] =
666     "<property name=\"property\" type=\"(s)\" access=\"write\">"
667     "<annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"Struct1\"/>"
668     "</property>";
669 
properties_data()670 void tst_QDBusMetaObject::properties_data()
671 {
672     QTest::addColumn<const QMetaObject *>("metaobject");
673     QTest::addColumn<QString>("xml");
674 
675     QTest::newRow("read") << &PropertyTest1::staticMetaObject << QString(PropertyTest1_xml);
676     QTest::newRow("readwrite") << &PropertyTest2::staticMetaObject << QString(PropertyTest2_xml);
677     QTest::newRow("write") << &PropertyTest3::staticMetaObject << QString(PropertyTest3_xml);
678     QTest::newRow("customtype") << &PropertyTest4::staticMetaObject << QString(PropertyTest4_xml);
679 }
680 
properties()681 void tst_QDBusMetaObject::properties()
682 {
683     types();
684 }
685 
686 
687 QTEST_MAIN(tst_QDBusMetaObject)
688 #include "tst_qdbusmetaobject.moc"
689