1/**
2 * Copyright (C) 2007 Brad Hards <bradh@frogmouth.net>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <QtCrypto>
27#include <QtTest/QtTest>
28
29#include <limits>
30
31#ifdef QT_STATICPLUGIN
32#include "import_plugins.h"
33#endif
34
35class TestClass1 : public QObject
36{
37 Q_OBJECT
38
39public:
40 TestClass1() {};
41 TestClass1(const TestClass1 &)
42 : QObject(nullptr) {};
43
44public Q_SLOTS:
45 void voidMethod() {};
46 QString qstringMethod()
47 {
48 return QString();
49 };
50 bool boolMethod(const QString &)
51 {
52 return true;
53 };
54 QString returnArg(const QString &s)
55 {
56 return s;
57 };
58 QByteArray returnArg(const QByteArray &a)
59 {
60 return a;
61 };
62 QString returnRepeatArg(const QString &s)
63 {
64 return QString(s + s);
65 };
66 QString tenArgs(const QString &s, int, int, int, int, int, int, int, int, int)
67 {
68 return QString(s);
69 };
70 QString elevenArgs(const QString &s, int, int, int, int, int, int, int, int, int, int)
71 {
72 return QString(s);
73 };
74};
75
76Q_DECLARE_METATYPE(TestClass1)
77
78class MetaTypeUnitTest : public QObject
79{
80 Q_OBJECT
81
82private Q_SLOTS:
83 void initTestCase();
84 void cleanupTestCase();
85 void returnTypeTest();
86 void invokeMethodTest();
87
88private:
89 QCA::Initializer *m_init;
90};
91
92void MetaTypeUnitTest::initTestCase()
93{
94 m_init = new QCA::Initializer;
95}
96
97void MetaTypeUnitTest::cleanupTestCase()
98{
99 QCA::unloadAllPlugins();
100 delete m_init;
101}
102
103void MetaTypeUnitTest::returnTypeTest()
104{
105 TestClass1 testClass1;
106 QList<QByteArray> args;
107
108#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
109 // returns a null type name because that is what void does...
110 QCOMPARE(QMetaType::Void, QCA::methodReturnType(testClass1.metaObject(), QByteArray("voidMethod"), args));
111 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("qstringMethod"), args));
112
113 // returns a null type, because args don't match
114 QCOMPARE(QMetaType::UnknownType, QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
115
116 args << "QString";
117 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
118 QCOMPARE(QMetaType::Bool, QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
119 args.clear();
120
121 args << "QByteArray";
122 QCOMPARE(QMetaType::QByteArray, QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
123 args.clear();
124
125 args << "QString"
126 << "int"
127 << "int"
128 << "int"
129 << "int"
130 << "int"
131 << "int"
132 << "int"
133 << "int";
134
135 // wrong number of arguments - has 9, needs 10
136 QCOMPARE(QMetaType::UnknownType, QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
137
138 // match
139 args << "int";
140 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
141
142 args << "int";
143 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("elevenArgs"), args));
144#else
145 // returns a null type name because that is what void does...
146 QCOMPARE(QByteArray("void"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("voidMethod"), args));
147 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("qstringMethod"), args));
148
149 // returns a null type, because args don't match
150 QCOMPARE(QByteArray(""), QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
151
152 args << "QString";
153 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
154 QCOMPARE(QByteArray("bool"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
155 args.clear();
156
157 args << "QByteArray";
158 QCOMPARE(QByteArray("QByteArray"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
159 args.clear();
160
161 args << "QString"
162 << "int"
163 << "int"
164 << "int"
165 << "int"
166 << "int"
167 << "int"
168 << "int"
169 << "int";
170
171 // wrong number of arguments - has 9, needs 10
172 QCOMPARE(QByteArray(""), QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
173
174 // match
175 args << "int";
176 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
177
178 args << "int";
179 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("elevenArgs"), args));
180#endif
181}
182
183void MetaTypeUnitTest::invokeMethodTest()
184{
185 TestClass1 *testClass1 = new TestClass1;
186 QVariantList args;
187
188 bool ret;
189 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("voidMethod"), args, ret: nullptr);
190 QVERIFY(ret);
191
192 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("noSuchMethod"), args, ret: nullptr);
193 QVERIFY(ret == false);
194
195 QVariant stringRes;
196 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("qstringMethod"), args, ret: &stringRes);
197 QVERIFY(ret);
198 QVERIFY(stringRes.isValid());
199
200 QVariant result(false);
201 QString fakeArg;
202 args << fakeArg;
203 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("boolMethod"), args, ret: &result);
204 QVERIFY(ret);
205 QCOMPARE(result.toBool(), true);
206
207 result = QByteArray();
208 args.clear();
209 QByteArray myArray("array");
210 args << myArray;
211 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnArg"), args, ret: &result);
212 QVERIFY(ret);
213 QCOMPARE(result.toByteArray(), myArray);
214
215 result = QString();
216 args.clear();
217 QString myString = QStringLiteral("test words");
218 args << myString;
219 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnArg"), args, ret: &result);
220 QVERIFY(ret);
221 QCOMPARE(result.toString(), myString);
222
223 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnRepeatArg"), args, ret: &result);
224 QVERIFY(ret);
225 QCOMPARE(result.toString(), QString(myString + myString));
226
227 // 9 arguments - no matching method
228 result = QStringLiteral("unchanged");
229 args << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0;
230 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("tenArgs"), args, ret: &result);
231 QVERIFY(ret == false);
232 QCOMPARE(result.toString(), QStringLiteral("unchanged"));
233
234 // 10 args
235 args << 0;
236 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("tenArgs"), args, ret: &result);
237 QVERIFY(ret);
238 QCOMPARE(result.toString(), myString);
239
240 // 11 args
241 result = QStringLiteral("unchanged");
242 args << 0;
243 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("elevenArgs"), args, ret: &result);
244 QVERIFY(ret == false);
245 QCOMPARE(result.toString(), QStringLiteral("unchanged"));
246
247 delete testClass1;
248}
249
250QTEST_MAIN(MetaTypeUnitTest)
251
252#include "metatype.moc"
253

source code of qca/unittest/metatype/metatype.cpp