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 | |
36 | class tst_QMetaMethod : public QObject |
37 | { |
38 | Q_OBJECT |
39 | |
40 | private 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 | |
53 | struct CustomType { }; |
54 | Q_DECLARE_METATYPE(CustomType) |
55 | |
56 | struct CustomUnregisteredType { }; |
57 | |
58 | Q_DECLARE_METATYPE(QMetaMethod::Access) |
59 | Q_DECLARE_METATYPE(QMetaMethod::MethodType) |
60 | |
61 | class MethodTestObject : public QObject |
62 | { |
63 | Q_OBJECT |
64 | public: |
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); |
93 | public 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); |
109 | signals: |
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 | |
128 | MethodTestObject::MethodTestObject() {} |
129 | MethodTestObject::MethodTestObject(int) {} |
130 | MethodTestObject::MethodTestObject(qreal) {} |
131 | MethodTestObject::MethodTestObject(const QString &) {} |
132 | MethodTestObject::MethodTestObject(CustomType) {} |
133 | MethodTestObject::MethodTestObject(CustomUnregisteredType) {} |
134 | MethodTestObject::MethodTestObject(bool, int, uint, qlonglong, qulonglong, |
135 | double, long, short, char, ulong, ushort, |
136 | uchar, float) {} |
137 | MethodTestObject::MethodTestObject(bool, int) {} |
138 | |
139 | void MethodTestObject::voidInvokable() {} |
140 | void MethodTestObject::voidInvokableInt(int) {} |
141 | void MethodTestObject::voidInvokableQReal(qreal) {} |
142 | void MethodTestObject::voidInvokableQString(const QString &) {} |
143 | void MethodTestObject::voidInvokableCustomType(CustomType) {} |
144 | void MethodTestObject::voidInvokableCustomUnregisteredType(CustomUnregisteredType) {} |
145 | bool MethodTestObject::boolInvokable() { return true; } |
146 | qreal MethodTestObject::qrealInvokable() { return 1.0; } |
147 | QString MethodTestObject::qstringInvokable() { return QString(); } |
148 | CustomType MethodTestObject::customTypeInvokable() { return CustomType(); } |
149 | CustomUnregisteredType MethodTestObject::customUnregisteredTypeInvokable() |
150 | { |
151 | return CustomUnregisteredType(); |
152 | } |
153 | QVariant MethodTestObject::qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat( |
154 | bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float) |
155 | { |
156 | return QVariant(); |
157 | } |
158 | void MethodTestObject::voidInvokableNoParameterNames(bool, int) {} |
159 | |
160 | void MethodTestObject::voidSlot() {} |
161 | void MethodTestObject::voidSlotInt(int) {} |
162 | void MethodTestObject::voidSlotQReal(qreal) {} |
163 | void MethodTestObject::voidSlotQString(const QString &) {} |
164 | void MethodTestObject::voidSlotCustomType(CustomType) {} |
165 | void MethodTestObject::voidSlotCustomUnregisteredType(CustomUnregisteredType) {} |
166 | bool MethodTestObject::boolSlot() { return true; } |
167 | qreal MethodTestObject::qrealSlot() { return 1.0; } |
168 | QString MethodTestObject::qstringSlot() { return QString(); } |
169 | CustomType MethodTestObject::customTypeSlot() { return CustomType(); } |
170 | CustomUnregisteredType MethodTestObject::customUnregisteredTypeSlot() |
171 | { |
172 | return CustomUnregisteredType(); |
173 | } |
174 | QVariant MethodTestObject::qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat( |
175 | bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float) |
176 | { |
177 | return QVariant(); |
178 | } |
179 | void MethodTestObject::voidSlotNoParameterNames(bool, int) {} |
180 | |
181 | void 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 | |
586 | void 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 | |
657 | void 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 | |
669 | void 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 | |
704 | void 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 | |
728 | class MyGadget { |
729 | Q_GADGET |
730 | public: |
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 | |
736 | void 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 | |
774 | QTEST_MAIN(tst_QMetaMethod) |
775 | #include "tst_qmetamethod.moc" |
776 | |