1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30
31#include <QtTest/QtTest>
32
33#include <qobject.h>
34#include <qmetaobject.h>
35#include "wobjectimpl.h"
36
37class tst_QMetaMethod : public QObject
38{
39 W_OBJECT(tst_QMetaMethod)
40
41private slots:
42 void method_data(); W_SLOT(method_data, W_Access::Private)
43 void method(); W_SLOT(method, W_Access::Private)
44
45 void invalidMethod(); W_SLOT(invalidMethod, W_Access::Private)
46
47 void comparisonOperators(); W_SLOT(comparisonOperators, W_Access::Private)
48
49 void fromSignal(); W_SLOT(fromSignal, W_Access::Private)
50
51 void gadget(); W_SLOT(gadget, W_Access::Private)
52};
53
54struct CustomType { };
55Q_DECLARE_METATYPE(CustomType)
56W_REGISTER_ARGTYPE(CustomType)
57
58struct CustomUnregisteredType { };
59W_REGISTER_ARGTYPE(CustomUnregisteredType)
60
61Q_DECLARE_METATYPE(QMetaMethod::Access)
62Q_DECLARE_METATYPE(QMetaMethod::MethodType)
63
64class MethodTestObject : public QObject
65{
66 W_OBJECT(MethodTestObject)
67public:
68 MethodTestObject();
69 MethodTestObject(int constructorIntArg);
70 MethodTestObject(qreal constructorQRealArg);
71 MethodTestObject(const QString &constructorQStringArg);
72 MethodTestObject(CustomType constructorCustomTypeArg);
73 MethodTestObject(CustomUnregisteredType constructorCustomUnregisteredTypeArg);
74 MethodTestObject(bool boolArg, int intArg, uint uintArg,
75 qlonglong longlongArg, qulonglong ulonglongArg,
76 double doubleArg, long longArg, short shortArg,
77 char charArg, ulong ulongArg, ushort ushortArg,
78 uchar ucharArg, float floatArg);
79 MethodTestObject(bool, int);
80
81 W_CONSTRUCTOR();
82 W_CONSTRUCTOR(int);
83 W_CONSTRUCTOR(qreal);
84 W_CONSTRUCTOR(QString);
85 W_CONSTRUCTOR(CustomType);
86 W_CONSTRUCTOR(CustomUnregisteredType);
87 W_CONSTRUCTOR(bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float);
88 W_CONSTRUCTOR(bool, int);
89
90 void voidInvokable();
91 W_INVOKABLE(voidInvokable)
92 void voidInvokableInt(int voidInvokableIntArg);
93 W_INVOKABLE(voidInvokableInt)
94 void voidInvokableQReal(qreal voidInvokableQRealArg);
95 W_INVOKABLE(voidInvokableQReal)
96 void voidInvokableQString(const QString &voidInvokableQStringArg);
97 W_INVOKABLE(voidInvokableQString)
98 void voidInvokableCustomType(CustomType voidInvokableCustomTypeArg);
99 W_INVOKABLE(voidInvokableCustomType)
100 void voidInvokableCustomUnregisteredType(CustomUnregisteredType voidInvokableCustomUnregisteredTypeArg);
101 W_INVOKABLE(voidInvokableCustomUnregisteredType)
102 bool boolInvokable();
103 W_INVOKABLE(boolInvokable)
104 qreal qrealInvokable();
105 W_INVOKABLE(qrealInvokable)
106 QString qstringInvokable();
107 W_INVOKABLE(qstringInvokable)
108 CustomType customTypeInvokable();
109 W_INVOKABLE(customTypeInvokable)
110 CustomUnregisteredType customUnregisteredTypeInvokable();
111 W_INVOKABLE(customUnregisteredTypeInvokable)
112 QVariant qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
113 bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
114 long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg);
115 W_INVOKABLE(qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat)
116 void voidInvokableNoParameterNames(bool, int);
117 W_INVOKABLE(voidInvokableNoParameterNames)
118public slots:
119 void voidSlot();
120 W_SLOT(voidSlot)
121 void voidSlotInt(int voidSlotIntArg);
122 W_SLOT(voidSlotInt)
123 void voidSlotQReal(qreal voidSlotQRealArg);
124 W_SLOT(voidSlotQReal)
125 void voidSlotQString(const QString &voidSlotQStringArg);
126 W_SLOT(voidSlotQString)
127 void voidSlotCustomType(CustomType voidSlotCustomTypeArg);
128 W_SLOT(voidSlotCustomType)
129 void voidSlotCustomUnregisteredType(CustomUnregisteredType voidSlotCustomUnregisteredTypeArg);
130 W_SLOT(voidSlotCustomUnregisteredType)
131 bool boolSlot();
132 W_SLOT(boolSlot)
133 qreal qrealSlot();
134 W_SLOT(qrealSlot)
135 QString qstringSlot();
136 W_SLOT(qstringSlot)
137 CustomType customTypeSlot();
138 W_SLOT(customTypeSlot)
139 CustomUnregisteredType customUnregisteredTypeSlot();
140 W_SLOT(customUnregisteredTypeSlot)
141 QVariant qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
142 bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
143 long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg);
144 W_SLOT(qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat)
145 void voidSlotNoParameterNames(bool, int);
146 W_SLOT(voidSlotNoParameterNames)
147signals:
148 void voidSignal() W_SIGNAL(voidSignal)
149 void voidSignalVoid(void) W_SIGNAL(voidSignalVoid)
150 void voidSignalInt(int voidSignalIntArg) W_SIGNAL(voidSignalInt,voidSignalIntArg)
151 void voidSignalQReal(qreal voidSignalQRealArg) W_SIGNAL(voidSignalQReal,voidSignalQRealArg)
152 void voidSignalQString(const QString &voidSignalQStringArg) W_SIGNAL(voidSignalQString,voidSignalQStringArg)
153 void voidSignalCustomType(CustomType voidSignalCustomTypeArg) W_SIGNAL(voidSignalCustomType,voidSignalCustomTypeArg)
154 void voidSignalCustomUnregisteredType(CustomUnregisteredType voidSignalCustomUnregisteredTypeArg) W_SIGNAL(voidSignalCustomUnregisteredType,voidSignalCustomUnregisteredTypeArg)
155 bool boolSignal() W_SIGNAL(boolSignal)
156 qreal qrealSignal() W_SIGNAL(qrealSignal)
157 QString qstringSignal() W_SIGNAL(qstringSignal)
158 CustomType customTypeSignal() W_SIGNAL(customTypeSignal)
159 CustomUnregisteredType customUnregisteredTypeSignal() W_SIGNAL(customUnregisteredTypeSignal)
160 QVariant qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
161 bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
162 long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg)
163 W_SIGNAL(qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat,
164 boolArg, intArg, uintArg, longlongArg, ulonglongArg, doubleArg,
165 longArg, shortArg, charArg, ulongArg, ushortArg, ucharArg, floatArg)
166 void voidSignalNoParameterNames(bool _1, int _2) W_SIGNAL(voidSignalNoParameterNames, _1, _2)
167};
168
169MethodTestObject::MethodTestObject() {}
170MethodTestObject::MethodTestObject(int) {}
171MethodTestObject::MethodTestObject(qreal) {}
172MethodTestObject::MethodTestObject(const QString &) {}
173MethodTestObject::MethodTestObject(CustomType) {}
174MethodTestObject::MethodTestObject(CustomUnregisteredType) {}
175MethodTestObject::MethodTestObject(bool, int, uint, qlonglong, qulonglong,
176 double, long, short, char, ulong, ushort,
177 uchar, float) {}
178MethodTestObject::MethodTestObject(bool, int) {}
179
180void MethodTestObject::voidInvokable() {}
181void MethodTestObject::voidInvokableInt(int) {}
182void MethodTestObject::voidInvokableQReal(qreal) {}
183void MethodTestObject::voidInvokableQString(const QString &) {}
184void MethodTestObject::voidInvokableCustomType(CustomType) {}
185void MethodTestObject::voidInvokableCustomUnregisteredType(CustomUnregisteredType) {}
186bool MethodTestObject::boolInvokable() { return true; }
187qreal MethodTestObject::qrealInvokable() { return 1.0; }
188QString MethodTestObject::qstringInvokable() { return QString(); }
189CustomType MethodTestObject::customTypeInvokable() { return CustomType(); }
190CustomUnregisteredType MethodTestObject::customUnregisteredTypeInvokable()
191{
192 return CustomUnregisteredType();
193}
194QVariant MethodTestObject::qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
195 bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float)
196{
197 return QVariant();
198}
199void MethodTestObject::voidInvokableNoParameterNames(bool, int) {}
200
201void MethodTestObject::voidSlot() {}
202void MethodTestObject::voidSlotInt(int) {}
203void MethodTestObject::voidSlotQReal(qreal) {}
204void MethodTestObject::voidSlotQString(const QString &) {}
205void MethodTestObject::voidSlotCustomType(CustomType) {}
206void MethodTestObject::voidSlotCustomUnregisteredType(CustomUnregisteredType) {}
207bool MethodTestObject::boolSlot() { return true; }
208qreal MethodTestObject::qrealSlot() { return 1.0; }
209QString MethodTestObject::qstringSlot() { return QString(); }
210CustomType MethodTestObject::customTypeSlot() { return CustomType(); }
211CustomUnregisteredType MethodTestObject::customUnregisteredTypeSlot()
212{
213 return CustomUnregisteredType();
214}
215QVariant MethodTestObject::qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
216 bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float)
217{
218 return QVariant();
219}
220void MethodTestObject::voidSlotNoParameterNames(bool, int) {}
221
222void tst_QMetaMethod::method_data()
223{
224 QTest::addColumn<QByteArray>("signature");
225 QTest::addColumn<int>("returnType");
226 QTest::addColumn<QByteArray>("returnTypeName");
227 QTest::addColumn<QList<int> >("parameterTypes");
228 QTest::addColumn<QList<QByteArray> >("parameterTypeNames");
229 QTest::addColumn<QList<QByteArray> >("parameterNames");
230 QTest::addColumn<QMetaMethod::Access>("access");
231 QTest::addColumn<QMetaMethod::MethodType>("methodType");
232
233 QTest::newRow("voidSignal")
234 << QByteArray("voidSignal()")
235 << int(QMetaType::Void) << QByteArray("void")
236 << (QList<int>())
237 << (QList<QByteArray>())
238 << (QList<QByteArray>())
239 << QMetaMethod::Public
240 << QMetaMethod::Signal;
241
242 QTest::newRow("voidInvokable")
243 << QByteArray("voidInvokable()")
244 << int(QMetaType::Void) << QByteArray("void")
245 << (QList<int>())
246 << (QList<QByteArray>())
247 << (QList<QByteArray>())
248 << QMetaMethod::Public
249 << QMetaMethod::Method;
250
251 QTest::newRow("voidSlot")
252 << QByteArray("voidSlot()")
253 << int(QMetaType::Void) << QByteArray("void")
254 << (QList<int>())
255 << (QList<QByteArray>())
256 << (QList<QByteArray>())
257 << QMetaMethod::Public
258 << QMetaMethod::Slot;
259
260 QTest::newRow("MethodTestObject()")
261 << QByteArray("MethodTestObject()")
262 << int(QMetaType::UnknownType) << QByteArray("")
263 << (QList<int>())
264 << (QList<QByteArray>())
265 << (QList<QByteArray>())
266 << QMetaMethod::Public
267 << QMetaMethod::Constructor;
268
269 QTest::newRow("voidSignalVoid")
270 << QByteArray("voidSignalVoid()")
271 << int(QMetaType::Void) << QByteArray("void")
272 << QList<int>()
273 << QList<QByteArray>()
274 << QList<QByteArray>()
275 << QMetaMethod::Public
276 << QMetaMethod::Signal;
277
278 QTest::newRow("voidSignalInt")
279 << QByteArray("voidSignalInt(int)")
280 << int(QMetaType::Void) << QByteArray("void")
281 << (QList<int>() << int(QMetaType::Int))
282 << (QList<QByteArray>() << QByteArray("int"))
283 << (QList<QByteArray>() << QByteArray("voidSignalIntArg"))
284 << QMetaMethod::Public
285 << QMetaMethod::Signal;
286
287 QTest::newRow("voidInvokableInt")
288 << QByteArray("voidInvokableInt(int)")
289 << int(QMetaType::Void) << QByteArray("void")
290 << (QList<int>() << int(QMetaType::Int))
291 << (QList<QByteArray>() << QByteArray("int"))
292 << (QList<QByteArray>() << QByteArray("voidInvokableIntArg"))
293 << QMetaMethod::Public
294 << QMetaMethod::Method;
295
296 QTest::newRow("voidSlotInt")
297 << QByteArray("voidSlotInt(int)")
298 << int(QMetaType::Void) << QByteArray("void")
299 << (QList<int>() << int(QMetaType::Int))
300 << (QList<QByteArray>() << QByteArray("int"))
301 << (QList<QByteArray>() << QByteArray("voidSlotIntArg"))
302 << QMetaMethod::Public
303 << QMetaMethod::Slot;
304
305 QTest::newRow("MethodTestObject(int)")
306 << QByteArray("MethodTestObject(int)")
307 << int(QMetaType::UnknownType) << QByteArray("")
308 << (QList<int>() << int(QMetaType::Int))
309 << (QList<QByteArray>() << QByteArray("int"))
310 << (QList<QByteArray>() << QByteArray("constructorIntArg"))
311 << QMetaMethod::Public
312 << QMetaMethod::Constructor;
313
314 QTest::newRow("voidSignalQReal")
315 << QByteArray("voidSignalQReal(qreal)")
316 << int(QMetaType::Void) << QByteArray("void")
317 << (QList<int>() << qMetaTypeId<qreal>())
318 << (QList<QByteArray>() << QByteArray("qreal"))
319 << (QList<QByteArray>() << QByteArray("voidSignalQRealArg"))
320 << QMetaMethod::Public
321 << QMetaMethod::Signal;
322
323 QTest::newRow("voidInvokableQReal")
324 << QByteArray("voidInvokableQReal(qreal)")
325 << int(QMetaType::Void) << QByteArray("void")
326 << (QList<int>() << qMetaTypeId<qreal>())
327 << (QList<QByteArray>() << QByteArray("qreal"))
328 << (QList<QByteArray>() << QByteArray("voidInvokableQRealArg"))
329 << QMetaMethod::Public
330 << QMetaMethod::Method;
331
332 QTest::newRow("voidSlotQReal")
333 << QByteArray("voidSlotQReal(qreal)")
334 << int(QMetaType::Void) << QByteArray("void")
335 << (QList<int>() << qMetaTypeId<qreal>())
336 << (QList<QByteArray>() << QByteArray("qreal"))
337 << (QList<QByteArray>() << QByteArray("voidSlotQRealArg"))
338 << QMetaMethod::Public
339 << QMetaMethod::Slot;
340
341 QTest::newRow("MethodTestObject(qreal)")
342 << QByteArray("MethodTestObject(qreal)")
343 << int(QMetaType::UnknownType) << QByteArray("")
344 << (QList<int>() << qMetaTypeId<qreal>())
345 << (QList<QByteArray>() << QByteArray("qreal"))
346 << (QList<QByteArray>() << QByteArray("constructorQRealArg"))
347 << QMetaMethod::Public
348 << QMetaMethod::Constructor;
349
350 QTest::newRow("voidSignalQString")
351 << QByteArray("voidSignalQString(QString)")
352 << int(QMetaType::Void) << QByteArray("void")
353 << (QList<int>() << int(QMetaType::QString))
354 << (QList<QByteArray>() << QByteArray("QString"))
355 << (QList<QByteArray>() << QByteArray("voidSignalQStringArg"))
356 << QMetaMethod::Public
357 << QMetaMethod::Signal;
358
359 QTest::newRow("voidInvokableQString")
360 << QByteArray("voidInvokableQString(QString)")
361 << int(QMetaType::Void) << QByteArray("void")
362 << (QList<int>() << int(QMetaType::QString))
363 << (QList<QByteArray>() << QByteArray("QString"))
364 << (QList<QByteArray>() << QByteArray("voidInvokableQStringArg"))
365 << QMetaMethod::Public
366 << QMetaMethod::Method;
367
368 QTest::newRow("voidSlotQString")
369 << QByteArray("voidSlotQString(QString)")
370 << int(QMetaType::Void) << QByteArray("void")
371 << (QList<int>() << int(QMetaType::QString))
372 << (QList<QByteArray>() << QByteArray("QString"))
373 << (QList<QByteArray>() << QByteArray("voidSlotQStringArg"))
374 << QMetaMethod::Public
375 << QMetaMethod::Slot;
376
377 QTest::newRow("MethodTestObject(QString)")
378 << QByteArray("MethodTestObject(QString)")
379 << int(QMetaType::UnknownType) << QByteArray("")
380 << (QList<int>() << int(QMetaType::QString))
381 << (QList<QByteArray>() << QByteArray("QString"))
382 << (QList<QByteArray>() << QByteArray("constructorQStringArg"))
383 << QMetaMethod::Public
384 << QMetaMethod::Constructor;
385
386 QTest::newRow("voidSignalCustomType")
387 << QByteArray("voidSignalCustomType(CustomType)")
388 << int(QMetaType::Void) << QByteArray("void")
389 << (QList<int>() << qMetaTypeId<CustomType>())
390 << (QList<QByteArray>() << QByteArray("CustomType"))
391 << (QList<QByteArray>() << QByteArray("voidSignalCustomTypeArg"))
392 << QMetaMethod::Public
393 << QMetaMethod::Signal;
394
395 QTest::newRow("voidInvokableCustomType")
396 << QByteArray("voidInvokableCustomType(CustomType)")
397 << int(QMetaType::Void) << QByteArray("void")
398 << (QList<int>() << qMetaTypeId<CustomType>())
399 << (QList<QByteArray>() << QByteArray("CustomType"))
400 << (QList<QByteArray>() << QByteArray("voidInvokableCustomTypeArg"))
401 << QMetaMethod::Public
402 << QMetaMethod::Method;
403
404 QTest::newRow("voidSlotCustomType")
405 << QByteArray("voidSlotCustomType(CustomType)")
406 << int(QMetaType::Void) << QByteArray("void")
407 << (QList<int>() << qMetaTypeId<CustomType>())
408 << (QList<QByteArray>() << QByteArray("CustomType"))
409 << (QList<QByteArray>() << QByteArray("voidSlotCustomTypeArg"))
410 << QMetaMethod::Public
411 << QMetaMethod::Slot;
412
413 QTest::newRow("MethodTestObject(CustomType)")
414 << QByteArray("MethodTestObject(CustomType)")
415 << int(QMetaType::UnknownType) << QByteArray("")
416 << (QList<int>() << qMetaTypeId<CustomType>())
417 << (QList<QByteArray>() << QByteArray("CustomType"))
418 << (QList<QByteArray>() << QByteArray("constructorCustomTypeArg"))
419 << QMetaMethod::Public
420 << QMetaMethod::Constructor;
421
422 QTest::newRow("voidSignalCustomUnregisteredType")
423 << QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
424 << int(QMetaType::Void) << QByteArray("void")
425 << (QList<int>() << 0)
426 << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
427 << (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
428 << QMetaMethod::Public
429 << QMetaMethod::Signal;
430
431 QTest::newRow("voidInvokableCustomUnregisteredType")
432 << QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
433 << int(QMetaType::Void) << QByteArray("void")
434 << (QList<int>() << 0)
435 << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
436 << (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
437 << QMetaMethod::Public
438 << QMetaMethod::Method;
439
440 QTest::newRow("voidSlotCustomUnregisteredType")
441 << QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
442 << int(QMetaType::Void) << QByteArray("void")
443 << (QList<int>() << 0)
444 << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
445 << (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
446 << QMetaMethod::Public
447 << QMetaMethod::Slot;
448
449 QTest::newRow("MethodTestObject(CustomUnregisteredType)")
450 << QByteArray("MethodTestObject(CustomUnregisteredType)")
451 << int(QMetaType::UnknownType) << QByteArray("")
452 << (QList<int>() << 0)
453 << (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
454 << (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
455 << QMetaMethod::Public
456 << QMetaMethod::Constructor;
457
458 QTest::newRow("boolSignal")
459 << QByteArray("boolSignal()")
460 << int(QMetaType::Bool) << QByteArray("bool")
461 << (QList<int>())
462 << (QList<QByteArray>())
463 << (QList<QByteArray>())
464 << QMetaMethod::Public
465 << QMetaMethod::Signal;
466
467 QTest::newRow("boolInvokable")
468 << QByteArray("boolInvokable()")
469 << int(QMetaType::Bool) << QByteArray("bool")
470 << (QList<int>())
471 << (QList<QByteArray>())
472 << (QList<QByteArray>())
473 << QMetaMethod::Public
474 << QMetaMethod::Method;
475
476 QTest::newRow("boolSlot")
477 << QByteArray("boolSlot()")
478 << int(QMetaType::Bool) << QByteArray("bool")
479 << (QList<int>())
480 << (QList<QByteArray>())
481 << (QList<QByteArray>())
482 << QMetaMethod::Public
483 << QMetaMethod::Slot;
484
485 QTest::newRow("qrealSignal")
486 << QByteArray("qrealSignal()")
487 << int(QMetaType::QReal) << QByteArray("qreal")
488 << (QList<int>())
489 << (QList<QByteArray>())
490 << (QList<QByteArray>())
491 << QMetaMethod::Public
492 << QMetaMethod::Signal;
493
494 QTest::newRow("qrealInvokable")
495 << QByteArray("qrealInvokable()")
496 << int(QMetaType::QReal) << QByteArray("qreal")
497 << (QList<int>())
498 << (QList<QByteArray>())
499 << (QList<QByteArray>())
500 << QMetaMethod::Public
501 << QMetaMethod::Method;
502
503 QTest::newRow("qrealSlot")
504 << QByteArray("qrealSlot()")
505 << int(QMetaType::QReal) << QByteArray("qreal")
506 << (QList<int>())
507 << (QList<QByteArray>())
508 << (QList<QByteArray>())
509 << QMetaMethod::Public
510 << QMetaMethod::Slot;
511
512 QTest::newRow("qstringSignal")
513 << QByteArray("qstringSignal()")
514 << int(QMetaType::QString) << QByteArray("QString")
515 << (QList<int>())
516 << (QList<QByteArray>())
517 << (QList<QByteArray>())
518 << QMetaMethod::Public
519 << QMetaMethod::Signal;
520
521 QTest::newRow("qstringInvokable")
522 << QByteArray("qstringInvokable()")
523 << int(QMetaType::QString) << QByteArray("QString")
524 << (QList<int>())
525 << (QList<QByteArray>())
526 << (QList<QByteArray>())
527 << QMetaMethod::Public
528 << QMetaMethod::Method;
529
530 QTest::newRow("qstringSlot")
531 << QByteArray("qstringSlot()")
532 << int(QMetaType::QString) << QByteArray("QString")
533 << (QList<int>())
534 << (QList<QByteArray>())
535 << (QList<QByteArray>())
536 << QMetaMethod::Public
537 << QMetaMethod::Slot;
538
539 {
540 QList<int> parameterTypes = QList<int>()
541 << int(QMetaType::Bool) << int(QMetaType::Int) << int(QMetaType::UInt)
542 << int(QMetaType::LongLong) << int(QMetaType::ULongLong) << int(QMetaType::Double)
543 << int(QMetaType::Long) << int(QMetaType::Short) << int(QMetaType::Char)
544 << int(QMetaType::ULong) << int(QMetaType::UShort) << int(QMetaType::UChar)
545 << int(QMetaType::Float);
546 QList<QByteArray> parameterTypeNames = QList<QByteArray>()
547 << QByteArray("bool") << QByteArray("int") << QByteArray("uint")
548 << QByteArray("qlonglong") << QByteArray("qulonglong") << QByteArray("double")
549 << QByteArray("long") << QByteArray("short") << QByteArray("char") << QByteArray("ulong")
550 << QByteArray("ushort") << QByteArray("uchar") << QByteArray("float");
551 QList<QByteArray> parameterNames = QList<QByteArray>()
552 << QByteArray("boolArg") << QByteArray("intArg") << QByteArray("uintArg")
553 << QByteArray("longlongArg") << QByteArray("ulonglongArg") << QByteArray("doubleArg")
554 << QByteArray("longArg") << QByteArray("shortArg") << QByteArray("charArg")
555 << QByteArray("ulongArg") << QByteArray("ushortArg") << QByteArray("ucharArg")
556 << QByteArray("floatArg");
557
558 QTest::newRow("qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
559 << QByteArray("qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
560 "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
561 << int(QMetaType::QVariant) << QByteArray("QVariant")
562 << parameterTypes << parameterTypeNames << parameterNames
563 << QMetaMethod::Public
564 << QMetaMethod::Signal;
565
566 QTest::newRow("qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
567 << QByteArray("qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
568 "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
569 << int(QMetaType::QVariant) << QByteArray("QVariant")
570 << parameterTypes << parameterTypeNames << parameterNames
571 << QMetaMethod::Public
572 << QMetaMethod::Method;
573
574 QTest::newRow("qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
575 << QByteArray("qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
576 "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
577 << int(QMetaType::QVariant) << QByteArray("QVariant")
578 << parameterTypes << parameterTypeNames << parameterNames
579 << QMetaMethod::Public
580 << QMetaMethod::Slot;
581
582 QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
583 << QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
584 << int(QMetaType::UnknownType) << QByteArray("")
585 << parameterTypes << parameterTypeNames << parameterNames
586 << QMetaMethod::Public
587 << QMetaMethod::Constructor;
588 }
589
590 QTest::newRow("voidSignalNoParameterNames")
591 << QByteArray("voidSignalNoParameterNames(bool,int)")
592 << int(QMetaType::Void) << QByteArray("void")
593 << (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
594 << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
595 << (QList<QByteArray>() << QByteArray("") << QByteArray(""))
596 << QMetaMethod::Public
597 << QMetaMethod::Signal;
598
599 QTest::newRow("voidInvokableNoParameterNames")
600 << QByteArray("voidInvokableNoParameterNames(bool,int)")
601 << int(QMetaType::Void) << QByteArray("void")
602 << (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
603 << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
604 << (QList<QByteArray>() << QByteArray("") << QByteArray(""))
605 << QMetaMethod::Public
606 << QMetaMethod::Method;
607
608 QTest::newRow("voidSlotNoParameterNames")
609 << QByteArray("voidSlotNoParameterNames(bool,int)")
610 << int(QMetaType::Void) << QByteArray("void")
611 << (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
612 << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
613 << (QList<QByteArray>() << QByteArray("") << QByteArray(""))
614 << QMetaMethod::Public
615 << QMetaMethod::Slot;
616
617 QTest::newRow("MethodTestObject(bool,int)")
618 << QByteArray("MethodTestObject(bool,int)")
619 << int(QMetaType::UnknownType) << QByteArray("")
620 << (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
621 << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
622 << (QList<QByteArray>() << QByteArray("") << QByteArray(""))
623 << QMetaMethod::Public
624 << QMetaMethod::Constructor;
625}
626
627void tst_QMetaMethod::method()
628{
629 QFETCH(QByteArray, signature);
630 QFETCH(int, returnType);
631 QFETCH(QByteArray, returnTypeName);
632 QFETCH(QList<int>, parameterTypes);
633 QFETCH(QList<QByteArray>, parameterTypeNames);
634 QFETCH(QList<QByteArray>, parameterNames);
635 QFETCH(QMetaMethod::MethodType, methodType);
636 QFETCH(QMetaMethod::Access, access);
637
638 QCOMPARE(parameterTypes.size(), parameterTypeNames.size());
639 QCOMPARE(parameterTypes.size(), parameterNames.size());
640
641 const QMetaObject *mo = &MethodTestObject::staticMetaObject;
642 int index = (methodType == QMetaMethod::Constructor)
643 ? mo->indexOfConstructor(signature) : mo->indexOfMethod(signature);
644 QVERIFY(index != -1);
645 QMetaMethod method = (methodType == QMetaMethod::Constructor)
646 ? mo->constructor(index) : mo->method(index);
647 QVERIFY(method.isValid());
648 QCOMPARE(method.methodType(), methodType);
649 QCOMPARE(method.access(), access);
650
651 QVERIFY(!method.methodSignature().isEmpty());
652 if (method.methodSignature() != signature) {
653 // QMetaMethod should always produce a semantically equivalent signature
654 int signatureIndex = (methodType == QMetaMethod::Constructor)
655 ? mo->indexOfConstructor(method.methodSignature())
656 : mo->indexOfMethod(method.methodSignature());
657 QCOMPARE(signatureIndex, index);
658 }
659
660 QByteArray computedName = signature.left(signature.indexOf('('));
661 QCOMPARE(method.name(), computedName);
662
663 QCOMPARE(method.tag(), "");
664 QCOMPARE(method.returnType(), returnType);
665 QVERIFY(method.typeName() != 0);
666 if (QByteArray(method.typeName()) != returnTypeName) {
667 // QMetaMethod should always produce a semantically equivalent typename
668 QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName));
669 }
670
671 if (method.parameterTypes() != parameterTypeNames) {
672 // QMetaMethod should always produce semantically equivalent typenames
673 QList<QByteArray> actualTypeNames = method.parameterTypes();
674 QCOMPARE(actualTypeNames.size(), parameterTypeNames.size());
675 for (int i = 0; i < parameterTypeNames.size(); ++i) {
676 QCOMPARE(QMetaType::type(actualTypeNames.at(i)),
677 QMetaType::type(parameterTypeNames.at(i)));
678 }
679 }
680 //QCOMPARE(method.parameterNames(), parameterNames); // ### not supported by W_INVOKABLE
681
682 QCOMPARE(method.parameterCount(), parameterTypes.size());
683 for (int i = 0; i < parameterTypes.size(); ++i)
684 QCOMPARE(method.parameterType(i), parameterTypes.at(i));
685
686 {
687 QVector<int> actualParameterTypes(parameterTypes.size());
688 method.getParameterTypes(actualParameterTypes.data());
689 for (int i = 0; i < parameterTypes.size(); ++i)
690 QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i));
691 }
692
693 // Bogus indexes
694 QCOMPARE(method.parameterType(-1), 0);
695 QCOMPARE(method.parameterType(parameterTypes.size()), 0);
696}
697
698void tst_QMetaMethod::invalidMethod()
699{
700 QMetaMethod method;
701 QVERIFY(!method.isValid());
702
703 QMetaMethod method2 = staticMetaObject.method(staticMetaObject.methodCount());
704 QVERIFY(!method2.isValid());
705
706 QMetaMethod method3 = staticMetaObject.method(-1);
707 QVERIFY(!method3.isValid());
708}
709
710void tst_QMetaMethod::comparisonOperators()
711{
712 static const QMetaObject *mo = &MethodTestObject::staticMetaObject;
713 for (int x = 0; x < 2; ++x) {
714 int count = x ? mo->constructorCount() : mo->methodCount();
715 for (int i = 0; i < count; ++i) {
716 QMetaMethod method = x ? mo->constructor(i) : mo->method(i);
717 const QMetaObject *methodMo = method.enclosingMetaObject();
718 for (int j = 0; j < count; ++j) {
719 QMetaMethod other = x ? mo->constructor(j) : mo->method(j);
720 bool expectedEqual = ((methodMo == other.enclosingMetaObject())
721 && (i == j));
722 QCOMPARE(method == other, expectedEqual);
723 QCOMPARE(method != other, !expectedEqual);
724 QCOMPARE(other == method, expectedEqual);
725 QCOMPARE(other != method, !expectedEqual);
726 }
727
728 QVERIFY(method != QMetaMethod());
729 QVERIFY(QMetaMethod() != method);
730 QVERIFY(!(method == QMetaMethod()));
731 QVERIFY(!(QMetaMethod() == method));
732 }
733 }
734
735 // Constructors and normal methods with identical index should not
736 // compare equal
737 for (int i = 0; i < qMin(mo->methodCount(), mo->constructorCount()); ++i) {
738 QMetaMethod method = mo->method(i);
739 QMetaMethod constructor = mo->constructor(i);
740 QVERIFY(method != constructor);
741 QVERIFY(!(method == constructor));
742 }
743}
744
745void tst_QMetaMethod::fromSignal()
746{
747#define FROMSIGNAL_HELPER(ObjectType, Name, Arguments) { \
748 const QMetaObject *signalMeta = &ObjectType::staticMetaObject; \
749 QCOMPARE(QMetaMethod::fromSignal(&ObjectType::Name), \
750 signalMeta->method(signalMeta->indexOfSignal(QMetaObject::normalizedSignature(#Name #Arguments)))); \
751 }
752
753 FROMSIGNAL_HELPER(MethodTestObject, voidSignal, ())
754 FROMSIGNAL_HELPER(MethodTestObject, voidSignalQString, (const QString&))
755 FROMSIGNAL_HELPER(QObject, destroyed, (QObject*))
756 FROMSIGNAL_HELPER(QObject, objectNameChanged, (const QString &))
757
758 // Inherited from QObject
759 FROMSIGNAL_HELPER(MethodTestObject, destroyed, (QObject*))
760 FROMSIGNAL_HELPER(MethodTestObject, objectNameChanged, (const QString &))
761
762 // Methods that are not signals; fromSignal should return invalid method
763 FROMSIGNAL_HELPER(MethodTestObject, voidSlot, ())
764 FROMSIGNAL_HELPER(QObject, deleteLater, ())
765
766#undef FROMSIGNAL_HELPER
767}
768
769class MyGadget {
770 W_GADGET(MyGadget)
771public:
772 QString m_value;
773 void setValue(const QString &value) { m_value = value; }
774 W_INVOKABLE(setValue)
775 QString getValue() { return m_value; }
776 W_INVOKABLE(getValue)
777};
778
779void tst_QMetaMethod::gadget()
780{
781 int idx;
782
783 idx = MyGadget::staticMetaObject.indexOfMethod("setValue(QString)");
784 QVERIFY(idx >= 0);
785 QMetaMethod setValueMethod = MyGadget::staticMetaObject.method(idx);
786 QVERIFY(setValueMethod.isValid());
787
788 idx = MyGadget::staticMetaObject.indexOfMethod("getValue()");
789 QVERIFY(idx >= 0);
790 QMetaMethod getValueMethod = MyGadget::staticMetaObject.method(idx);
791 QVERIFY(getValueMethod.isValid());
792
793 {
794 MyGadget gadget;
795 QString string;
796
797 QVERIFY(getValueMethod.invokeOnGadget(&gadget, Q_RETURN_ARG(QString, string)));
798 QCOMPARE(string, gadget.m_value);
799
800 QVERIFY(setValueMethod.invokeOnGadget(&gadget, Q_ARG(QString, QLatin1String("hello"))));
801 QCOMPARE(gadget.m_value, QLatin1String("hello"));
802
803 QVERIFY(getValueMethod.invokeOnGadget(&gadget, Q_RETURN_ARG(QString, string)));
804 QCOMPARE(string, gadget.m_value);
805 }
806
807 {
808 // Call with null should not crash
809 MyGadget *gadget = nullptr;
810 QString string;
811 QVERIFY(!setValueMethod.invokeOnGadget(gadget, Q_ARG(QString, QLatin1String("hi"))));
812 QVERIFY(!getValueMethod.invokeOnGadget(gadget, Q_RETURN_ARG(QString, string)));
813 }
814}
815
816W_OBJECT_IMPL(tst_QMetaMethod)
817W_OBJECT_IMPL(MethodTestObject)
818W_GADGET_IMPL(MyGadget)
819
820
821QTEST_MAIN(tst_QMetaMethod)
822