File indexing completed on 2026-09-01 09:23:49
0001
0002
0003
0004
0005 #ifndef QTEST_H
0006 #define QTEST_H
0007
0008 #if 0
0009 #pragma qt_class(QTest)
0010 #endif
0011
0012 #include <QtTest/qttestglobal.h>
0013 #include <QtTest/qtestcase.h>
0014 #include <QtTest/qtestdata.h>
0015 #include <QtTest/qtesttostring.h>
0016 #include <QtTest/qbenchmark.h>
0017
0018 #if defined(TESTCASE_LOWDPI)
0019 #include <QtCore/qcoreapplication.h>
0020 #endif
0021
0022 #include <cstdio>
0023 #include <initializer_list>
0024 #include <memory>
0025
0026 QT_BEGIN_NAMESPACE
0027
0028 namespace QTest
0029 {
0030
0031 template<>
0032 inline bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual,
0033 const char *expected, const char *file, int line)
0034 {
0035 return qCompare(t1, QString(t2), actual, expected, file, line);
0036 }
0037 template<>
0038 inline bool qCompare(QLatin1StringView const &t1, QString const &t2, const char *actual,
0039 const char *expected, const char *file, int line)
0040 {
0041 return qCompare(QString(t1), t2, actual, expected, file, line);
0042 }
0043
0044
0045 template <typename ActualIterator, typename ExpectedIterator>
0046 bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd,
0047 ExpectedIterator expectedBegin, ExpectedIterator expectedEnd,
0048 const char *actual, const char *expected,
0049 const char *file, int line)
0050 {
0051 char msg[1024];
0052 msg[0] = '\0';
0053
0054 const qsizetype actualSize = actualEnd - actualIt;
0055 const qsizetype expectedSize = expectedEnd - expectedBegin;
0056 bool isOk = actualSize == expectedSize;
0057
0058 if (!isOk) {
0059 std::snprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
0060 " Actual (%s) size: %lld\n"
0061 " Expected (%s) size: %lld",
0062 actual, qlonglong(actualSize),
0063 expected, qlonglong(expectedSize));
0064 }
0065
0066 for (auto expectedIt = expectedBegin; isOk && expectedIt < expectedEnd; ++actualIt, ++expectedIt) {
0067 if (!(*actualIt == *expectedIt)) {
0068 const qsizetype i = qsizetype(expectedIt - expectedBegin);
0069 char *val1 = toString(*actualIt);
0070 char *val2 = toString(*expectedIt);
0071
0072 std::snprintf(msg, sizeof(msg), "Compared lists differ at index %lld.\n"
0073 " Actual (%s): %s\n"
0074 " Expected (%s): %s",
0075 qlonglong(i), actual, val1 ? val1 : "<null>",
0076 expected, val2 ? val2 : "<null>");
0077 isOk = false;
0078
0079 delete [] val1;
0080 delete [] val2;
0081 }
0082 }
0083 return compare_helper(isOk, msg, actual, expected, file, line);
0084 }
0085
0086 namespace Internal {
0087
0088 #if defined(TESTCASE_LOWDPI)
0089 void disableHighDpi()
0090 {
0091 qputenv("QT_ENABLE_HIGHDPI_SCALING", "0");
0092 }
0093 Q_CONSTRUCTOR_FUNCTION(disableHighDpi);
0094 #endif
0095
0096 }
0097
0098 template <typename T>
0099 inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const char *expected,
0100 const char *file, int line)
0101 {
0102 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
0103 actual, expected, file, line);
0104 }
0105
0106 template <typename T, int N>
0107 bool qCompare(QList<T> const &t1, std::initializer_list<T> t2,
0108 const char *actual, const char *expected,
0109 const char *file, int line)
0110 {
0111 return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
0112 actual, expected, file, line);
0113 }
0114
0115
0116 template <typename T, int N>
0117 bool qCompare(QList<T> const &t1, const T (& t2)[N],
0118 const char *actual, const char *expected,
0119 const char *file, int line)
0120 {
0121 return _q_compareSequence(t1.cbegin(), t1.cend(), t2, t2 + N,
0122 actual, expected, file, line);
0123 }
0124
0125 template <typename T>
0126 inline bool qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected,
0127 const char *file, int line)
0128 {
0129 using Int = typename QFlags<T>::Int;
0130 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
0131 }
0132
0133 template <typename T>
0134 inline bool qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected,
0135 const char *file, int line)
0136 {
0137 using Int = typename QFlags<T>::Int;
0138 return qCompare(Int(t1), Int(t2), actual, expected, file, line);
0139 }
0140
0141 template<>
0142 inline bool qCompare(qint64 const &t1, qint32 const &t2, const char *actual,
0143 const char *expected, const char *file, int line)
0144 {
0145 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
0146 }
0147
0148 template<>
0149 inline bool qCompare(qint64 const &t1, quint32 const &t2, const char *actual,
0150 const char *expected, const char *file, int line)
0151 {
0152 return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
0153 }
0154
0155 template<>
0156 inline bool qCompare(quint64 const &t1, quint32 const &t2, const char *actual,
0157 const char *expected, const char *file, int line)
0158 {
0159 return qCompare(t1, static_cast<quint64>(t2), actual, expected, file, line);
0160 }
0161
0162 template<>
0163 inline bool qCompare(qint32 const &t1, qint64 const &t2, const char *actual,
0164 const char *expected, const char *file, int line)
0165 {
0166 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
0167 }
0168
0169 template<>
0170 inline bool qCompare(quint32 const &t1, qint64 const &t2, const char *actual,
0171 const char *expected, const char *file, int line)
0172 {
0173 return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
0174 }
0175
0176 template<>
0177 inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual,
0178 const char *expected, const char *file, int line)
0179 {
0180 return qCompare(static_cast<quint64>(t1), t2, actual, expected, file, line);
0181 }
0182 namespace Internal {
0183
0184 template <typename T>
0185 using InitMainTest = decltype(&T::initMain);
0186
0187 template <typename T>
0188 constexpr inline bool hasInitMain = qxp::is_detected_v<InitMainTest, T>;
0189
0190 template<typename T>
0191 void callInitMain()
0192 {
0193 if constexpr (hasInitMain<T>)
0194 T::initMain();
0195 }
0196
0197 }
0198
0199 }
0200 QT_END_NAMESPACE
0201
0202 #ifdef QT_TESTCASE_BUILDDIR
0203 # define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
0204 #else
0205 # define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
0206 #endif
0207
0208
0209 #if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
0210 struct QtCoverageScanner
0211 {
0212 QtCoverageScanner(const char *name)
0213 {
0214 __coveragescanner_clear();
0215 __coveragescanner_testname(name);
0216 }
0217 ~QtCoverageScanner()
0218 {
0219 __coveragescanner_save();
0220 __coveragescanner_testname("");
0221 }
0222 };
0223 #define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
0224 #else
0225 #define TESTLIB_SELFCOVERAGE_START(name)
0226 #endif
0227
0228 #if !defined(QTEST_BATCH_TESTS)
0229
0230
0231
0232 #define QTEST_MAIN_WRAPPER(TestObject, ...) \
0233 int main(int argc, char *argv[]) \
0234 { \
0235 TESTLIB_SELFCOVERAGE_START(#TestObject) \
0236 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
0237 __VA_ARGS__ \
0238 TestObject tc; \
0239 QTEST_SET_MAIN_SOURCE_PATH \
0240 return QTest::qExec(&tc, argc, argv); \
0241 }
0242 #else
0243
0244
0245
0246 #if !defined(BATCHED_TEST_NAME)
0247 #define BATCHED_TEST_NAME "other"
0248 #endif
0249 #define QTEST_MAIN_WRAPPER(TestObject, ...) \
0250 \
0251 void qRegister##TestObject() \
0252 { \
0253 auto runTest = [](int argc, char** argv) -> int { \
0254 TESTLIB_SELFCOVERAGE_START(TestObject) \
0255 QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
0256 __VA_ARGS__ \
0257 TestObject tc; \
0258 QTEST_SET_MAIN_SOURCE_PATH \
0259 return QTest::qExec(&tc, argc, argv); \
0260 }; \
0261 QTest::qRegisterTestCase(QStringLiteral(BATCHED_TEST_NAME), runTest); \
0262 } \
0263 \
0264 Q_CONSTRUCTOR_FUNCTION(qRegister##TestObject)
0265 #endif
0266
0267
0268 #define QTEST_APPLESS_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject)
0269
0270 #include <QtTest/qtestsystem.h>
0271
0272 #if defined(QT_NETWORK_LIB)
0273 # include <QtTest/qtest_network.h>
0274 #endif
0275
0276
0277 #define QTEST_QAPP_SETUP(klaz) \
0278 klaz app(argc, argv); \
0279 app.setAttribute(Qt::AA_Use96Dpi, true);
0280
0281 #if defined(QT_WIDGETS_LIB)
0282 # include <QtTest/qtest_widgets.h>
0283 # ifdef QT_KEYPAD_NAVIGATION
0284 # define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
0285 # else
0286 # define QTEST_DISABLE_KEYPAD_NAVIGATION
0287 # endif
0288
0289 # define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QApplication) QTEST_DISABLE_KEYPAD_NAVIGATION
0290 #elif defined(QT_GUI_LIB)
0291 # include <QtTest/qtest_gui.h>
0292
0293 # define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QGuiApplication)
0294 #else
0295
0296 # define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QCoreApplication)
0297 #endif
0298
0299
0300 #define QTEST_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject, QTEST_MAIN_SETUP())
0301
0302
0303 #define QTEST_GUILESS_MAIN(TestObject) \
0304 QTEST_MAIN_WRAPPER(TestObject, QTEST_QAPP_SETUP(QCoreApplication))
0305
0306 #endif