Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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 <cstdio>
23#include <initializer_list>
24#include <memory>
25
26QT_BEGIN_NAMESPACE
27
28namespace QTest
29{
30
31template<>
32inline bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual,
33 const char *expected, const char *file, int line)
34{
35 return qCompare(t1, QString(t2), actual, expected, file, line);
36}
37template<>
38inline bool qCompare(QLatin1StringView const &t1, QString const &t2, const char *actual,
39 const char *expected, const char *file, int line)
40{
41 return qCompare(QString(t1), t2, actual, expected, file, line);
42}
43
44// Compare sequences of equal size
45template <typename ActualIterator, typename ExpectedIterator>
46bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd,
47 ExpectedIterator expectedBegin, ExpectedIterator expectedEnd,
48 const char *actual, const char *expected,
49 const char *file, int line)
50{
51 Q_DECL_UNINITIALIZED
52 char msg[1024];
53 msg[0] = '\0';
54
55 const qsizetype actualSize = actualEnd - actualIt;
56 const qsizetype expectedSize = expectedEnd - expectedBegin;
57 bool isOk = actualSize == expectedSize;
58
59 if (!isOk) {
60 std::snprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
61 " Actual (%s) size: %lld\n"
62 " Expected (%s) size: %lld",
63 actual, qlonglong(actualSize),
64 expected, qlonglong(expectedSize));
65 }
66
67 for (auto expectedIt = expectedBegin; isOk && expectedIt < expectedEnd; ++actualIt, ++expectedIt) {
68 if (!(*actualIt == *expectedIt)) {
69 const qsizetype i = qsizetype(expectedIt - expectedBegin);
70 char *val1 = toString(*actualIt);
71 char *val2 = toString(*expectedIt);
72
73 std::snprintf(msg, sizeof(msg), "Compared lists differ at index %lld.\n"
74 " Actual (%s): %s\n"
75 " Expected (%s): %s",
76 qlonglong(i), actual, val1 ? val1 : "<null>",
77 expected, val2 ? val2 : "<null>");
78 isOk = false;
79
80 delete [] val1;
81 delete [] val2;
82 }
83 }
84 return compare_helper(isOk, msg, actual, expected, file, line);
85}
86
87namespace Internal {
88
89#if defined(TESTCASE_LOWDPI)
90void disableHighDpi()
91{
92 qputenv("QT_ENABLE_HIGHDPI_SCALING", "0");
93}
95#endif
96
97} // namespace Internal
98
99template <typename T>
100inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const char *expected,
101 const char *file, int line)
102{
103 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
104 actual, expected, file, line);
105}
106
107template <typename T, int N>
108bool qCompare(QList<T> const &t1, std::initializer_list<T> t2,
109 const char *actual, const char *expected,
110 const char *file, int line)
111{
112 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
113 actual, expected, file, line);
114}
115
116// Compare QList against array
117template <typename T, int N>
118bool qCompare(QList<T> const &t1, const T (& t2)[N],
119 const char *actual, const char *expected,
120 const char *file, int line)
121{
122 return _q_compareSequence(t1.cbegin(), t1.cend(), t2, t2 + N,
123 actual, expected, file, line);
124}
125
126template <typename T>
127inline bool qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected,
128 const char *file, int line)
129{
130 using Int = typename QFlags<T>::Int;
131 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
132}
133
134template <typename T>
135inline bool qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected,
136 const char *file, int line)
137{
138 using Int = typename QFlags<T>::Int;
139 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
140}
141
142template<>
143inline bool qCompare(qint64 const &t1, qint32 const &t2, const char *actual,
144 const char *expected, const char *file, int line)
145{
146 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
147}
148
149template<>
150inline bool qCompare(qint64 const &t1, quint32 const &t2, const char *actual,
151 const char *expected, const char *file, int line)
152{
153 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
154}
155
156template<>
157inline bool qCompare(quint64 const &t1, quint32 const &t2, const char *actual,
158 const char *expected, const char *file, int line)
159{
160 return qCompare(t1, static_cast<quint64>(t2), actual, expected, file, line);
161}
162
163template<>
164inline bool qCompare(qint32 const &t1, qint64 const &t2, const char *actual,
165 const char *expected, const char *file, int line)
166{
167 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
168}
169
170template<>
171inline bool qCompare(quint32 const &t1, qint64 const &t2, const char *actual,
172 const char *expected, const char *file, int line)
173{
174 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
175}
176
177template<>
178inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual,
179 const char *expected, const char *file, int line)
180{
181 return qCompare(static_cast<quint64>(t1), t2, actual, expected, file, line);
182}
183namespace Internal {
184
185template <typename T>
186using InitMainTest = decltype(&T::initMain);
187
188template <typename T>
189constexpr inline bool hasInitMain = qxp::is_detected_v<InitMainTest, T>;
190
191template<typename T>
193{
194 if constexpr (hasInitMain<T>)
195 T::initMain();
196}
197
198} // namespace Internal
199
200} // namespace QTest
201QT_END_NAMESPACE
202
203#ifdef QT_TESTCASE_BUILDDIR
204# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
205#else
206# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
207#endif
208
209// Hooks for coverage-testing of QTestLib itself:
210#if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
211struct QtCoverageScanner
212{
213 QtCoverageScanner(const char *name)
214 {
215 __coveragescanner_clear();
216 __coveragescanner_testname(name);
217 }
218 ~QtCoverageScanner()
219 {
220 __coveragescanner_save();
221 __coveragescanner_testname("");
222 }
223};
224#define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
225#else
226#define TESTLIB_SELFCOVERAGE_START(name)
227#endif
228
229#if !defined(QTEST_BATCH_TESTS)
230// Internal (but used by some testlib selftests to hack argc and argv).
231// Tests should normally implement initMain() if they have set-up to do before
232// instantiating the test class.
233#define QTEST_MAIN_WRAPPER(TestObject, ...) int
234 main(int argc, char *argv[]) \
235{
236 TESTLIB_SELFCOVERAGE_START(#TestObject)
237 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>();
238 __VA_ARGS__
239 TestObject tc;
241 return QTest::qExec(&tc, argc, argv); \
242}
243#else
244// BATCHED_TEST_NAME is defined for each test in a batch in cmake. Some odd
245// targets, like snippets, don't define it though. Play safe by providing a
246// default value.
247#if !defined(BATCHED_TEST_NAME)
248#define BATCHED_TEST_NAME "other"
249#endif
250#define QTEST_MAIN_WRAPPER(TestObject, ...) void
251
252 qRegister##TestObject() \
253{
254 auto runTest = [](int argc, char** argv) -> int {
255 TESTLIB_SELFCOVERAGE_START(TestObject)
256 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>();
257 __VA_ARGS__
258 TestObject tc;
259 QTEST_SET_MAIN_SOURCE_PATH
260 return QTest::qExec(&tc, argc, argv);
261 };
262 QTest::qRegisterTestCase(QStringLiteral(BATCHED_TEST_NAME), runTest); \
263}Q_CONSTRUCTOR_FUNCTION
264
265 (qRegister##TestObject)
266#endif
267
268// For when you don't even want a QApplication:
269#define QTEST_APPLESS_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject)
270
271#include <QtTest/qtestsystem.h>
272
273#if defined(QT_NETWORK_LIB)
274# include <QtTest/qtest_network.h>
275#endif
276
277// Internal
278#define QTEST_QAPP_SETUP(klaz)
279 klaz app(argc, argv);
280 app.setAttribute(Qt::AA_Use96Dpi, true);
281
282#if defined(QT_WIDGETS_LIB)
283# include <QtTest/qtest_widgets.h>
284// Internal
285# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QApplication)
286#elif defined(QT_GUI_LIB)
287# include <QtTest/qtest_gui.h>
288// Internal
289# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QGuiApplication)
290#else
291// Internal
292# define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QCoreApplication)
293#endif // QT_GUI_LIB
294
295// For most tests:
296#define QTEST_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject, QTEST_MAIN_SETUP())
297
298// For command-line tests
299#define QTEST_GUILESS_MAIN(TestObject)
300 QTEST_MAIN_WRAPPER(TestObject, QTEST_QAPP_SETUP(QCoreApplication))
301
302#endif
decltype(&T::initMain) InitMainTest
Definition qtest.h:186
void callInitMain()
Definition qtest.h:192
constexpr bool hasInitMain
Definition qtest.h:189
bool qCompare(QList< T > const &t1, const T(&t2)[N], const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:118
bool qCompare(QList< T > const &t1, std::initializer_list< T > t2, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:108
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:46
bool qCompare(QFlags< T > const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:127
bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:32
bool qCompare(QList< T > const &t1, QList< T > const &t2, const char *actual, const char *expected, const char *file, int line)
Definition qtest.h:100
#define TESTLIB_SELFCOVERAGE_START(name)
Definition qtest.h:226
#define QTEST_SET_MAIN_SOURCE_PATH
Definition qtest.h:206
#define QTEST_MAIN_WRAPPER(TestObject,...)
Definition qtest.h:233
#define QTEST_MAIN_SETUP()
Definition qtest.h:292
#define QTEST_QAPP_SETUP(klaz)
Definition qtest.h:278