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

source code of qtbase/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp