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 <QTest>
27#include <QtCrypto>
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 {
42 }
43 TestClass1(const TestClass1 &)
44 : QObject(nullptr)
45 {
46 }
47
48public Q_SLOTS:
49 void voidMethod()
50 {
51 }
52 QString qstringMethod()
53 {
54 return QString();
55 };
56 bool boolMethod(const QString &)
57 {
58 return true;
59 };
60 QString returnArg(const QString &s)
61 {
62 return s;
63 };
64 QByteArray returnArg(const QByteArray &a)
65 {
66 return a;
67 };
68 QString returnRepeatArg(const QString &s)
69 {
70 return QString(s + s);
71 };
72 QString tenArgs(const QString &s, int, int, int, int, int, int, int, int, int)
73 {
74 return QString(s);
75 };
76 QString elevenArgs(const QString &s, int, int, int, int, int, int, int, int, int, int)
77 {
78 return QString(s);
79 };
80};
81
82Q_DECLARE_METATYPE(TestClass1)
83
84class MetaTypeUnitTest : public QObject
85{
86 Q_OBJECT
87
88private Q_SLOTS:
89 void initTestCase();
90 void cleanupTestCase();
91 void returnTypeTest();
92 void invokeMethodTest();
93
94private:
95 QCA::Initializer *m_init;
96};
97
98void MetaTypeUnitTest::initTestCase()
99{
100 m_init = new QCA::Initializer;
101}
102
103void MetaTypeUnitTest::cleanupTestCase()
104{
105 QCA::unloadAllPlugins();
106 delete m_init;
107}
108
109void MetaTypeUnitTest::returnTypeTest()
110{
111 TestClass1 testClass1;
112 QList<QByteArray> args;
113
114#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
115 // returns a null type name because that is what void does...
116 QCOMPARE(QMetaType::Void, QCA::methodReturnType(testClass1.metaObject(), QByteArray("voidMethod"), args));
117 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("qstringMethod"), args));
118
119 // returns a null type, because args don't match
120 QCOMPARE(QMetaType::UnknownType, QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
121
122 args << "QString";
123 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
124 QCOMPARE(QMetaType::Bool, QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
125 args.clear();
126
127 args << "QByteArray";
128 QCOMPARE(QMetaType::QByteArray, QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
129 args.clear();
130
131 args << "QString"
132 << "int"
133 << "int"
134 << "int"
135 << "int"
136 << "int"
137 << "int"
138 << "int"
139 << "int";
140
141 // wrong number of arguments - has 9, needs 10
142 QCOMPARE(QMetaType::UnknownType, QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
143
144 // match
145 args << "int";
146 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
147
148 args << "int";
149 QCOMPARE(QMetaType::QString, QCA::methodReturnType(testClass1.metaObject(), QByteArray("elevenArgs"), args));
150#else
151 // returns a null type name because that is what void does...
152 QCOMPARE(QByteArray("void"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("voidMethod"), args));
153 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("qstringMethod"), args));
154
155 // returns a null type, because args don't match
156 QCOMPARE(QByteArray(""), QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
157
158 args << "QString";
159 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
160 QCOMPARE(QByteArray("bool"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("boolMethod"), args));
161 args.clear();
162
163 args << "QByteArray";
164 QCOMPARE(QByteArray("QByteArray"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("returnArg"), args));
165 args.clear();
166
167 args << "QString"
168 << "int"
169 << "int"
170 << "int"
171 << "int"
172 << "int"
173 << "int"
174 << "int"
175 << "int";
176
177 // wrong number of arguments - has 9, needs 10
178 QCOMPARE(QByteArray(""), QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
179
180 // match
181 args << "int";
182 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("tenArgs"), args));
183
184 args << "int";
185 QCOMPARE(QByteArray("QString"), QCA::methodReturnType(testClass1.metaObject(), QByteArray("elevenArgs"), args));
186#endif
187}
188
189void MetaTypeUnitTest::invokeMethodTest()
190{
191 TestClass1 *testClass1 = new TestClass1;
192 QVariantList args;
193
194 bool ret;
195 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("voidMethod"), args, ret: nullptr);
196 QVERIFY(ret);
197
198 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("noSuchMethod"), args, ret: nullptr);
199 QVERIFY(ret == false);
200
201 QVariant stringRes;
202 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("qstringMethod"), args, ret: &stringRes);
203 QVERIFY(ret);
204 QVERIFY(stringRes.isValid());
205
206 QVariant result(false);
207 QString fakeArg;
208 args << fakeArg;
209 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("boolMethod"), args, ret: &result);
210 QVERIFY(ret);
211 QCOMPARE(result.toBool(), true);
212
213 result = QByteArray();
214 args.clear();
215 QByteArray myArray("array");
216 args << myArray;
217 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnArg"), args, ret: &result);
218 QVERIFY(ret);
219 QCOMPARE(result.toByteArray(), myArray);
220
221 result = QString();
222 args.clear();
223 QString myString = QStringLiteral("test words");
224 args << myString;
225 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnArg"), args, ret: &result);
226 QVERIFY(ret);
227 QCOMPARE(result.toString(), myString);
228
229 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("returnRepeatArg"), args, ret: &result);
230 QVERIFY(ret);
231 QCOMPARE(result.toString(), QString(myString + myString));
232
233 // 9 arguments - no matching method
234 result = QStringLiteral("unchanged");
235 args << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0;
236 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("tenArgs"), args, ret: &result);
237 QVERIFY(ret == false);
238 QCOMPARE(result.toString(), QStringLiteral("unchanged"));
239
240 // 10 args
241 args << 0;
242 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("tenArgs"), args, ret: &result);
243 QVERIFY(ret);
244 QCOMPARE(result.toString(), myString);
245
246 // 11 args
247 result = QStringLiteral("unchanged");
248 args << 0;
249 ret = QCA::invokeMethodWithVariants(obj: testClass1, method: QByteArray("elevenArgs"), args, ret: &result);
250 QVERIFY(ret == false);
251 QCOMPARE(result.toString(), QStringLiteral("unchanged"));
252
253 delete testClass1;
254}
255
256QTEST_MAIN(MetaTypeUnitTest)
257
258#include "metatype.moc"
259

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