Line data Source code
1 : /****************************************************************************
2 : **
3 : ** Copyright (C) 2016 The Qt Company Ltd.
4 : ** Copyright (C) 2016 Intel Corporation.
5 : ** Contact: https://www.qt.io/licensing/
6 : **
7 : ** This file is part of the QtTest module of the Qt Toolkit.
8 : **
9 : ** $QT_BEGIN_LICENSE:LGPL$
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 Lesser General Public License Usage
19 : ** Alternatively, this file may be used under the terms of the GNU Lesser
20 : ** General Public License version 3 as published by the Free Software
21 : ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 : ** packaging of this file. Please review the following information to
23 : ** ensure the GNU Lesser General Public License version 3 requirements
24 : ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 : **
26 : ** GNU General Public License Usage
27 : ** Alternatively, this file may be used under the terms of the GNU
28 : ** General Public License version 2.0 or (at your option) the GNU General
29 : ** Public license version 3 or any later version approved by the KDE Free
30 : ** Qt Foundation. The licenses are as published by the Free Software
31 : ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 : ** included in the packaging of this file. Please review the following
33 : ** information to ensure the GNU General Public License requirements will
34 : ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 : ** https://www.gnu.org/licenses/gpl-3.0.html.
36 : **
37 : ** $QT_END_LICENSE$
38 : **
39 : ****************************************************************************/
40 :
41 : #ifndef QTEST_H
42 : #define QTEST_H
43 :
44 : #include <QtTest/qtest_global.h>
45 : #include <QtTest/qtestcase.h>
46 : #include <QtTest/qtestdata.h>
47 : #include <QtTest/qbenchmark.h>
48 :
49 : #include <QtCore/qbytearray.h>
50 : #include <QtCore/qstring.h>
51 : #include <QtCore/qstringlist.h>
52 : #include <QtCore/qdatetime.h>
53 : #include <QtCore/qobject.h>
54 : #include <QtCore/qvariant.h>
55 : #include <QtCore/qurl.h>
56 :
57 : #include <QtCore/qpoint.h>
58 : #include <QtCore/qsize.h>
59 : #include <QtCore/qrect.h>
60 :
61 : #ifdef QT_NETWORK_LIB
62 : # include <QtNetwork/qhostaddress.h>
63 : #endif
64 :
65 : QT_BEGIN_NAMESPACE
66 :
67 :
68 : namespace QTest
69 : {
70 :
71 40 : template<> inline char *toString(const QString &str)
72 : {
73 40 : return QTest::toPrettyUnicode(reinterpret_cast<const ushort *>(str.constData()), str.length());
74 : }
75 :
76 : template<> inline char *toString(const QLatin1String &str)
77 : {
78 : return toString(QString(str));
79 : }
80 :
81 : template<> inline char *toString(const QByteArray &ba)
82 : {
83 : return QTest::toPrettyCString(ba.constData(), ba.length());
84 : }
85 :
86 : #ifndef QT_NO_DATESTRING
87 : template<> inline char *toString(const QTime &time)
88 : {
89 : return time.isValid()
90 : ? qstrdup(qPrintable(time.toString(QLatin1String("hh:mm:ss.zzz"))))
91 : : qstrdup("Invalid QTime");
92 : }
93 :
94 : template<> inline char *toString(const QDate &date)
95 : {
96 : return date.isValid()
97 : ? qstrdup(qPrintable(date.toString(QLatin1String("yyyy/MM/dd"))))
98 : : qstrdup("Invalid QDate");
99 : }
100 :
101 : template<> inline char *toString(const QDateTime &dateTime)
102 : {
103 : return dateTime.isValid()
104 : ? qstrdup(qPrintable(dateTime.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz[t]"))))
105 : : qstrdup("Invalid QDateTime");
106 : }
107 : #endif // QT_NO_DATESTRING
108 :
109 : template<> inline char *toString(const QChar &c)
110 : {
111 : const ushort uc = c.unicode();
112 : if (uc < 128) {
113 : char msg[32] = {'\0'};
114 : qsnprintf(msg, sizeof(msg), "QChar: '%c' (0x%x)", char(uc), unsigned(uc));
115 : return qstrdup(msg);
116 : }
117 : return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast<int>(c.unicode()), 16))));
118 : }
119 :
120 : template<> inline char *toString(const QPoint &p)
121 : {
122 : char msg[128] = {'\0'};
123 : qsnprintf(msg, sizeof(msg), "QPoint(%d,%d)", p.x(), p.y());
124 : return qstrdup(msg);
125 : }
126 :
127 : template<> inline char *toString(const QSize &s)
128 : {
129 : char msg[128] = {'\0'};
130 : qsnprintf(msg, sizeof(msg), "QSize(%dx%d)", s.width(), s.height());
131 : return qstrdup(msg);
132 : }
133 :
134 : template<> inline char *toString(const QRect &s)
135 : {
136 : char msg[256] = {'\0'};
137 : qsnprintf(msg, sizeof(msg), "QRect(%d,%d %dx%d) (bottomright %d,%d)",
138 : s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom());
139 : return qstrdup(msg);
140 : }
141 :
142 : template<> inline char *toString(const QPointF &p)
143 : {
144 : char msg[64] = {'\0'};
145 : qsnprintf(msg, sizeof(msg), "QPointF(%g,%g)", p.x(), p.y());
146 : return qstrdup(msg);
147 : }
148 :
149 : template<> inline char *toString(const QSizeF &s)
150 : {
151 : char msg[64] = {'\0'};
152 : qsnprintf(msg, sizeof(msg), "QSizeF(%gx%g)", s.width(), s.height());
153 : return qstrdup(msg);
154 : }
155 :
156 : template<> inline char *toString(const QRectF &s)
157 : {
158 : char msg[256] = {'\0'};
159 : qsnprintf(msg, sizeof(msg), "QRectF(%g,%g %gx%g) (bottomright %g,%g)",
160 : s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom());
161 : return qstrdup(msg);
162 : }
163 :
164 : template<> inline char *toString(const QUrl &uri)
165 : {
166 : if (!uri.isValid())
167 : return qstrdup(qPrintable(QLatin1String("Invalid URL: ") + uri.errorString()));
168 : return qstrdup(uri.toEncoded().constData());
169 : }
170 :
171 : template<> inline char *toString(const QVariant &v)
172 : {
173 : QByteArray vstring("QVariant(");
174 : if (v.isValid()) {
175 : QByteArray type(v.typeName());
176 : if (type.isEmpty()) {
177 : type = QByteArray::number(v.userType());
178 : }
179 : vstring.append(type);
180 : if (!v.isNull()) {
181 : vstring.append(',');
182 : if (v.canConvert(QVariant::String)) {
183 : vstring.append(v.toString().toLocal8Bit());
184 : }
185 : else {
186 : vstring.append("<value not representable as string>");
187 : }
188 : }
189 : }
190 : vstring.append(')');
191 :
192 : return qstrdup(vstring.constData());
193 : }
194 :
195 : #ifdef QT_NETWORK_LIB
196 : /*!
197 : \internal
198 : */
199 : template<> inline char *toString(const QHostAddress &addr)
200 : {
201 : switch (addr.protocol()) {
202 : case QAbstractSocket::UnknownNetworkLayerProtocol:
203 : return qstrdup("<unknown address (parse error)>");
204 : case QAbstractSocket::AnyIPProtocol:
205 : return qstrdup("QHostAddress::Any");
206 : case QAbstractSocket::IPv4Protocol:
207 : case QAbstractSocket::IPv6Protocol:
208 : break;
209 : }
210 :
211 : return qstrdup(addr.toString().toLatin1().constData());
212 : }
213 : #endif
214 :
215 : template<>
216 : inline bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual,
217 : const char *expected, const char *file, int line)
218 : {
219 : return qCompare(t1, QString(t2), actual, expected, file, line);
220 : }
221 : template<>
222 : inline bool qCompare(QLatin1String const &t1, QString const &t2, const char *actual,
223 : const char *expected, const char *file, int line)
224 : {
225 : return qCompare(QString(t1), t2, actual, expected, file, line);
226 : }
227 :
228 : template <typename T>
229 : inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const char *expected,
230 : const char *file, int line)
231 : {
232 : char msg[1024];
233 : msg[0] = '\0';
234 : bool isOk = true;
235 : const int actualSize = t1.count();
236 : const int expectedSize = t2.count();
237 : if (actualSize != expectedSize) {
238 : qsnprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
239 : " Actual (%s) size: %d\n"
240 : " Expected (%s) size: %d", actual, actualSize, expected, expectedSize);
241 : isOk = false;
242 : }
243 : for (int i = 0; isOk && i < actualSize; ++i) {
244 : if (!(t1.at(i) == t2.at(i))) {
245 : char *val1 = toString(t1.at(i));
246 : char *val2 = toString(t2.at(i));
247 :
248 : qsnprintf(msg, sizeof(msg), "Compared lists differ at index %d.\n"
249 : " Actual (%s): %s\n"
250 : " Expected (%s): %s", i, actual, val1 ? val1 : "<null>",
251 : expected, val2 ? val2 : "<null>");
252 : isOk = false;
253 :
254 : delete [] val1;
255 : delete [] val2;
256 : }
257 : }
258 : return compare_helper(isOk, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line);
259 : }
260 :
261 : template <>
262 : inline bool qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected,
263 : const char *file, int line)
264 : {
265 : return qCompare<QString>(t1, t2, actual, expected, file, line);
266 : }
267 :
268 : template <typename T>
269 : inline bool qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected,
270 : const char *file, int line)
271 : {
272 : return qCompare(int(t1), int(t2), actual, expected, file, line);
273 : }
274 :
275 : template <typename T>
276 : inline bool qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected,
277 : const char *file, int line)
278 : {
279 : return qCompare(int(t1), t2, actual, expected, file, line);
280 : }
281 :
282 : template<>
283 : inline bool qCompare(qint64 const &t1, qint32 const &t2, const char *actual,
284 : const char *expected, const char *file, int line)
285 : {
286 : return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
287 : }
288 :
289 : template<>
290 : inline bool qCompare(qint64 const &t1, quint32 const &t2, const char *actual,
291 : const char *expected, const char *file, int line)
292 : {
293 : return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
294 : }
295 :
296 : template<>
297 : inline bool qCompare(quint64 const &t1, quint32 const &t2, const char *actual,
298 : const char *expected, const char *file, int line)
299 : {
300 : return qCompare(t1, static_cast<quint64>(t2), actual, expected, file, line);
301 : }
302 :
303 : template<>
304 : inline bool qCompare(qint32 const &t1, qint64 const &t2, const char *actual,
305 : const char *expected, const char *file, int line)
306 : {
307 : return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
308 : }
309 :
310 : template<>
311 : inline bool qCompare(quint32 const &t1, qint64 const &t2, const char *actual,
312 : const char *expected, const char *file, int line)
313 : {
314 : return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
315 : }
316 :
317 : template<>
318 : inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual,
319 : const char *expected, const char *file, int line)
320 : {
321 : return qCompare(static_cast<quint64>(t1), t2, actual, expected, file, line);
322 : }
323 :
324 : }
325 : QT_END_NAMESPACE
326 :
327 : #ifdef QT_TESTCASE_BUILDDIR
328 : # define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
329 : #else
330 : # define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
331 : #endif
332 :
333 : #define QTEST_APPLESS_MAIN(TestObject) \
334 : int main(int argc, char *argv[]) \
335 : { \
336 : TestObject tc; \
337 : QTEST_SET_MAIN_SOURCE_PATH \
338 : return QTest::qExec(&tc, argc, argv); \
339 : }
340 :
341 : #include <QtTest/qtestsystem.h>
342 : #include <set>
343 :
344 : #ifndef QT_NO_OPENGL
345 : # define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
346 : extern Q_TESTLIB_EXPORT std::set<QByteArray> *(*qgpu_features_ptr)(const QString &); \
347 : extern Q_GUI_EXPORT std::set<QByteArray> *qgpu_features(const QString &);
348 : # define QTEST_ADD_GPU_BLACKLIST_SUPPORT \
349 : qgpu_features_ptr = qgpu_features;
350 : #else
351 : # define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
352 : # define QTEST_ADD_GPU_BLACKLIST_SUPPORT
353 : #endif
354 :
355 : #if defined(QT_WIDGETS_LIB)
356 :
357 : #include <QtTest/qtest_widgets.h>
358 :
359 : #ifdef QT_KEYPAD_NAVIGATION
360 : # define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
361 : #else
362 : # define QTEST_DISABLE_KEYPAD_NAVIGATION
363 : #endif
364 :
365 : #define QTEST_MAIN(TestObject) \
366 : QT_BEGIN_NAMESPACE \
367 : QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
368 : QT_END_NAMESPACE \
369 : int main(int argc, char *argv[]) \
370 : { \
371 : QApplication app(argc, argv); \
372 : app.setAttribute(Qt::AA_Use96Dpi, true); \
373 : QTEST_DISABLE_KEYPAD_NAVIGATION \
374 : QTEST_ADD_GPU_BLACKLIST_SUPPORT \
375 : TestObject tc; \
376 : QTEST_SET_MAIN_SOURCE_PATH \
377 : return QTest::qExec(&tc, argc, argv); \
378 : }
379 :
380 : #elif defined(QT_GUI_LIB)
381 :
382 : #include <QtTest/qtest_gui.h>
383 :
384 : #define QTEST_MAIN(TestObject) \
385 : QT_BEGIN_NAMESPACE \
386 : QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
387 : QT_END_NAMESPACE \
388 : int main(int argc, char *argv[]) \
389 : { \
390 : QGuiApplication app(argc, argv); \
391 : app.setAttribute(Qt::AA_Use96Dpi, true); \
392 : QTEST_ADD_GPU_BLACKLIST_SUPPORT \
393 : TestObject tc; \
394 : QTEST_SET_MAIN_SOURCE_PATH \
395 : return QTest::qExec(&tc, argc, argv); \
396 : }
397 :
398 : #else
399 :
400 : #define QTEST_MAIN(TestObject) \
401 : int main(int argc, char *argv[]) \
402 : { \
403 : QCoreApplication app(argc, argv); \
404 : app.setAttribute(Qt::AA_Use96Dpi, true); \
405 : TestObject tc; \
406 : QTEST_SET_MAIN_SOURCE_PATH \
407 : return QTest::qExec(&tc, argc, argv); \
408 : }
409 :
410 : #endif // QT_GUI_LIB
411 :
412 : #define QTEST_GUILESS_MAIN(TestObject) \
413 : int main(int argc, char *argv[]) \
414 : { \
415 : QCoreApplication app(argc, argv); \
416 : app.setAttribute(Qt::AA_Use96Dpi, true); \
417 : TestObject tc; \
418 : QTEST_SET_MAIN_SOURCE_PATH \
419 : return QTest::qExec(&tc, argc, argv); \
420 : }
421 :
422 : #endif
|