Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtest.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2020 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QTEST_H
6#define QTEST_H
7
8#if 0
9#pragma qt_class(QTest)
10#endif
11
12#include <QtTest/qttestglobal.h>
13#include <QtTest/qtestcase.h>
14#include <QtTest/qtestdata.h>
15#include <QtTest/qtesttostring.h>
16#include <QtTest/qbenchmark.h>
17
18#if defined(TESTCASE_LOWDPI)
19#include <QtCore/qcoreapplication.h>
20#endif
21
22#include <initializer_list>
23#include <memory>
24
26
27namespace QTest
28{
29
30template<>
31inline bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual,
32 const char *expected, const char *file, int line)
33{
34 return qCompare(t1, QString(t2), actual, expected, file, line);
35}
36template<>
37inline bool qCompare(QLatin1StringView const &t1, QString const &t2, const char *actual,
38 const char *expected, const char *file, int line)
39{
40 return qCompare(QString(t1), t2, actual, expected, file, line);
41}
42
43// Compare sequences of equal size
44template <typename ActualIterator, typename ExpectedIterator>
45bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd,
46 ExpectedIterator expectedBegin, ExpectedIterator expectedEnd,
47 const char *actual, const char *expected,
48 const char *file, int line)
49{
50 char msg[1024];
51 msg[0] = '\0';
52
53 const qsizetype actualSize = actualEnd - actualIt;
54 const qsizetype expectedSize = expectedEnd - expectedBegin;
55 bool isOk = actualSize == expectedSize;
56
57 if (!isOk) {
58 qsnprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
59 " Actual (%s) size: %zd\n"
60 " Expected (%s) size: %zd", actual, actualSize,
61 expected, expectedSize);
62 }
63
64 for (auto expectedIt = expectedBegin; isOk && expectedIt < expectedEnd; ++actualIt, ++expectedIt) {
65 if (!(*actualIt == *expectedIt)) {
66 const qsizetype i = qsizetype(expectedIt - expectedBegin);
67 char *val1 = toString(*actualIt);
68 char *val2 = toString(*expectedIt);
69
70 qsnprintf(msg, sizeof(msg), "Compared lists differ at index %zd.\n"
71 " Actual (%s): %s\n"
72 " Expected (%s): %s", i, actual, val1 ? val1 : "<null>",
73 expected, val2 ? val2 : "<null>");
74 isOk = false;
75
76 delete [] val1;
77 delete [] val2;
78 }
79 }
80 return compare_helper(isOk, msg, actual, expected, file, line);
81}
82
83namespace Internal {
84
85#if defined(TESTCASE_LOWDPI)
86void disableHighDpi()
87{
88 qputenv("QT_ENABLE_HIGHDPI_SCALING", "0");
89}
90Q_CONSTRUCTOR_FUNCTION(disableHighDpi);
91#endif
92
93} // namespace Internal
94
95template <typename T>
96inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const char *expected,
97 const char *file, int line)
98{
99 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
100 actual, expected, file, line);
101}
102
103template <typename T, int N>
104bool qCompare(QList<T> const &t1, std::initializer_list<T> t2,
105 const char *actual, const char *expected,
106 const char *file, int line)
107{
108 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
109 actual, expected, file, line);
110}
111
112// Compare QList against array
113template <typename T, int N>
114bool qCompare(QList<T> const &t1, const T (& t2)[N],
115 const char *actual, const char *expected,
116 const char *file, int line)
117{
118 return _q_compareSequence(t1.cbegin(), t1.cend(), t2, t2 + N,
119 actual, expected, file, line);
120}
121
122template <typename T>
123inline bool qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected,
124 const char *file, int line)
125{
126 using Int = typename QFlags<T>::Int;
127 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
128}
129
130template <typename T>
131inline bool qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected,
132 const char *file, int line)
133{
134 using Int = typename QFlags<T>::Int;
135 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
136}
137
138template<>
139inline bool qCompare(qint64 const &t1, qint32 const &t2, const char *actual,
140 const char *expected, const char *file, int line)
141{
142 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
143}
144
145template<>
146inline bool qCompare(qint64 const &t1, quint32 const &t2, const char *actual,
147 const char *expected, const char *file, int line)
148{
149 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
150}
151
152template<>
153inline bool qCompare(quint64 const &t1, quint32 const &t2, const char *actual,
154 const char *expected, const char *file, int line)
155{
156 return qCompare(t1, static_cast<quint64>(t2), actual, expected, file, line);
157}
158
159template<>
160inline bool qCompare(qint32 const &t1, qint64 const &t2, const char *actual,
161 const char *expected, const char *file, int line)
162{
163 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
164}
165
166template<>
167inline bool qCompare(quint32 const &t1, qint64 const &t2, const char *actual,
168 const char *expected, const char *file, int line)
169{
170 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
171}
172
173template<>
174inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual,
175 const char *expected, const char *file, int line)
176{
177 return qCompare(static_cast<quint64>(t1), t2, actual, expected, file, line);
178}
179namespace Internal {
180
181template <typename T>
182class HasInitMain // SFINAE test for the presence of initMain()
183{
184private:
185 using YesType = char[1];
186 using NoType = char[2];
187
188 template <typename C> static YesType& test( decltype(&C::initMain) ) ;
189 template <typename C> static NoType& test(...);
190
191public:
192 enum { value = sizeof(test<T>(nullptr)) == sizeof(YesType) };
193};
194
195template<typename T>
196typename std::enable_if<HasInitMain<T>::value, void>::type callInitMain()
197{
198 T::initMain();
199}
200
201template<typename T>
202typename std::enable_if<!HasInitMain<T>::value, void>::type callInitMain()
203{
204}
205
206} // namespace Internal
207
208} // namespace QTest
210
211#ifdef QT_TESTCASE_BUILDDIR
212# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
213#else
214# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
215#endif
216
217// Hooks for coverage-testing of QTestLib itself:
218#if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
219struct QtCoverageScanner
220{
221 QtCoverageScanner(const char *name)
222 {
223 __coveragescanner_clear();
224 __coveragescanner_testname(name);
225 }
226 ~QtCoverageScanner()
227 {
228 __coveragescanner_save();
229 __coveragescanner_testname("");
230 }
231};
232#define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
233#else
234#define TESTLIB_SELFCOVERAGE_START(name)
235#endif
236
237#if !defined(QTEST_BATCH_TESTS)
238// Internal (but used by some testlib selftests to hack argc and argv).
239// Tests should normally implement initMain() if they have set-up to do before
240// instantiating the test class.
241#define QTEST_MAIN_WRAPPER(TestObject, ...) \
242int main(int argc, char *argv[]) \
243{ \
244 TESTLIB_SELFCOVERAGE_START(#TestObject) \
245 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
246 __VA_ARGS__ \
247 TestObject tc; \
248 QTEST_SET_MAIN_SOURCE_PATH \
249 return QTest::qExec(&tc, argc, argv); \
250}
251#else
252// BATCHED_TEST_NAME is defined for each test in a batch in cmake. Some odd
253// targets, like snippets, don't define it though. Play safe by providing a
254// default value.
255#if !defined(BATCHED_TEST_NAME)
256#define BATCHED_TEST_NAME "other"
257#endif
258#define QTEST_MAIN_WRAPPER(TestObject, ...) \
259\
260void qRegister##TestObject() \
261{ \
262 auto runTest = [](int argc, char** argv) -> int { \
263 TESTLIB_SELFCOVERAGE_START(TestObject) \
264 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
265 __VA_ARGS__ \
266 TestObject tc; \
267 QTEST_SET_MAIN_SOURCE_PATH \
268 return QTest::qExec(&tc, argc, argv); \
269 }; \
270 QTest::qRegisterTestCase(QStringLiteral(BATCHED_TEST_NAME), runTest); \
271} \
272\
273Q_CONSTRUCTOR_FUNCTION(qRegister##TestObject)
274#endif
275
276// For when you don't even want a QApplication:
277#define QTEST_APPLESS_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject)
278
279#include <QtTest/qtestsystem.h>
280
281#if defined(QT_NETWORK_LIB)
282# include <QtTest/qtest_network.h>
283#endif
284
285// Internal
286#define QTEST_QAPP_SETUP(klaz) \
287 klaz app(argc, argv); \
288 app.setAttribute(Qt::AA_Use96Dpi, true);
289
290#if defined(QT_WIDGETS_LIB)
291# include <QtTest/qtest_widgets.h>
292# ifdef QT_KEYPAD_NAVIGATION
293# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
294# else
295# define QTEST_DISABLE_KEYPAD_NAVIGATION
296# endif
297// Internal
298# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QApplication) QTEST_DISABLE_KEYPAD_NAVIGATION
299#elif defined(QT_GUI_LIB)
300# include <QtTest/qtest_gui.h>
301// Internal
302# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QGuiApplication)
303#else
304// Internal
305# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QCoreApplication)
306#endif // QT_GUI_LIB
307
308// For most tests:
309#define QTEST_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject, QTEST_MAIN_SETUP())
310
311// For command-line tests
312#define QTEST_GUILESS_MAIN(TestObject) \
313 QTEST_MAIN_WRAPPER(TestObject, QTEST_QAPP_SETUP(QCoreApplication))
314
315#endif
std::conditional< std::is_unsigned< typenamestd::underlying_type< Enum >::type >::value, unsignedint, signedint >::type Int
Definition qflags.h:69
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QJSValue expected
Definition qjsengine.cpp:12
Combined button and popup list for selecting options.
std::enable_if< HasInitMain< T >::value, void >::type callInitMain()
Definition qtest.h:196
char * toString(const MyPoint &point)
bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd, ExpectedIterator expectedBegin, ExpectedIterator expectedEnd, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:45
bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:31
Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg, const void *actualPtr, const void *expectedPtr, const char *(*actualFormatter)(const void *), const char *(*expectedFormatter)(const void *), const char *actual, const char *expected, const char *file, int line)
Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt,...)
Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLenum type
GLuint name
#define t2
bool qputenv(const char *varName, QByteArrayView raw)
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
QFile file
[0]