Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-03 09:26:49

0001 // Copyright (C) 2021 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 
0004 #ifndef QTESTCASE_H
0005 #define QTESTCASE_H
0006 
0007 #include <QtTest/qttestglobal.h>
0008 #include <QtTest/qtesttostring.h>
0009 
0010 #include <QtCore/qstring.h>
0011 #include <QtCore/qnamespace.h>
0012 #include <QtCore/qmetatype.h>
0013 #include <QtCore/qmetaobject.h>
0014 #include <QtCore/qsharedpointer.h>
0015 #include <QtCore/qtemporarydir.h>
0016 #include <QtCore/qthread.h>
0017 
0018 #include <chrono>
0019 #ifdef __cpp_concepts
0020 #include <concepts>
0021 #endif
0022 #include <QtCore/qxpfunctional.h>
0023 #include <QtCore/qxptype_traits.h>
0024 #include <QtCore/q20utility.h>
0025 
0026 #include <string.h>
0027 
0028 #ifndef QT_NO_EXCEPTIONS
0029 #  include <exception>
0030 #endif // QT_NO_EXCEPTIONS
0031 
0032 QT_BEGIN_NAMESPACE
0033 
0034 #ifndef QT_NO_EXCEPTIONS
0035 
0036 #ifdef QTEST_THROW_ON_FAIL
0037 # define QTEST_FAIL_ACTION QTest::Internal::throwOnFail()
0038 #else
0039 # define QTEST_FAIL_ACTION do { QTest::Internal::maybeThrowOnFail(); return; } while (false)
0040 #endif
0041 
0042 #ifdef QTEST_THROW_ON_SKIP
0043 # define QTEST_SKIP_ACTION QTest::Internal::throwOnSkip()
0044 #else
0045 # define QTEST_SKIP_ACTION do { QTest::Internal::maybeThrowOnSkip(); return; } while (false)
0046 #endif
0047 
0048 #else
0049 # if defined(QTEST_THROW_ON_FAIL) || defined(QTEST_THROW_ON_SKIP)
0050 #  error QTEST_THROW_ON_FAIL/SKIP require exception support enabled.
0051 # endif
0052 #endif // QT_NO_EXCEPTIONS
0053 
0054 #ifndef QTEST_FAIL_ACTION
0055 # define QTEST_FAIL_ACTION return
0056 #endif
0057 
0058 #ifndef QTEST_SKIP_ACTION
0059 # define QTEST_SKIP_ACTION return
0060 #endif
0061 
0062 class qfloat16;
0063 class QRegularExpression;
0064 
0065 #define QVERIFY(statement) \
0066 do {\
0067     if (!QTest::qVerify(static_cast<bool>(statement), #statement, "", __FILE__, __LINE__))\
0068         QTEST_FAIL_ACTION; \
0069 } while (false)
0070 
0071 #define QFAIL(message) \
0072 do {\
0073     QTest::qFail(static_cast<const char *>(message), __FILE__, __LINE__);\
0074     QTEST_FAIL_ACTION; \
0075 } while (false)
0076 
0077 #define QVERIFY2(statement, description) \
0078 do {\
0079     if (statement) {\
0080         if (!QTest::qVerify(true, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
0081             QTEST_FAIL_ACTION; \
0082     } else {\
0083         if (!QTest::qVerify(false, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
0084             QTEST_FAIL_ACTION; \
0085     }\
0086 } while (false)
0087 
0088 #define QCOMPARE(actual, expected) \
0089 do {\
0090     if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
0091         QTEST_FAIL_ACTION; \
0092 } while (false)
0093 
0094 #define QCOMPARE_OP_IMPL(lhs, rhs, op, opId) \
0095 do { \
0096     if (!QTest::qCompareOp<QTest::ComparisonOperation::opId>(lhs, rhs, #lhs, #rhs, __FILE__, __LINE__)) \
0097         QTEST_FAIL_ACTION; \
0098 } while (false)
0099 
0100 #define QCOMPARE_EQ(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, ==, Equal)
0101 #define QCOMPARE_NE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, !=, NotEqual)
0102 #define QCOMPARE_LT(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, <, LessThan)
0103 #define QCOMPARE_LE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, <=, LessThanOrEqual)
0104 #define QCOMPARE_GT(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, >, GreaterThan)
0105 #define QCOMPARE_GE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, >=, GreaterThanOrEqual)
0106 
0107 #ifndef QT_NO_EXCEPTIONS
0108 
0109 #  define QVERIFY_THROWS_NO_EXCEPTION(...) \
0110     do { \
0111         QT_TRY { \
0112             __VA_ARGS__; \
0113             /* success */ \
0114         } QT_CATCH (...) { \
0115             QTest::qCaught(nullptr, __FILE__, __LINE__); \
0116             QTEST_FAIL_ACTION; \
0117         } \
0118     } while (false) \
0119     /* end */
0120 
0121 #if QT_DEPRECATED_SINCE(6, 3)
0122 namespace QTest {
0123 QT_DEPRECATED_VERSION_X_6_3("Don't use QVERIFY_EXCEPTION_THROWN(expr, type) anymore, "
0124                             "use QVERIFY_THROWS_EXCEPTION(type, expr...) instead")
0125 inline void useVerifyThrowsException() {}
0126 } // namespace QTest
0127 #  define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
0128     QVERIFY_THROWS_EXCEPTION(exceptiontype, QTest::useVerifyThrowsException(); expression)
0129 #endif
0130 
0131 #  define QVERIFY_THROWS_EXCEPTION(exceptiontype, ...) \
0132     do {\
0133         bool qverify_throws_exception_did_not_throw = false; \
0134         QT_TRY {\
0135             __VA_ARGS__; \
0136             QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
0137                          " but no exception caught", __FILE__, __LINE__); \
0138             qverify_throws_exception_did_not_throw = true; \
0139         } QT_CATCH (const exceptiontype &) { \
0140             /* success */ \
0141         } QT_CATCH (...) {\
0142             QTest::qCaught(#exceptiontype, __FILE__, __LINE__); \
0143             QTEST_FAIL_ACTION; \
0144         }\
0145         if (qverify_throws_exception_did_not_throw) \
0146             QTEST_FAIL_ACTION; \
0147     } while (false)
0148 
0149 #else // QT_NO_EXCEPTIONS
0150 
0151 /*
0152  * These macros check whether the expression passed throws exceptions, but we can't
0153  * catch them to check because Qt has been compiled without exception support. We can't
0154  * skip the expression because it may have side effects and must be executed.
0155  * So, users must use Qt with exception support enabled if they use exceptions
0156  * in their code.
0157  */
0158 #  define QVERIFY_THROWS_EXCEPTION(...) \
0159     static_assert(false, "Support for exceptions is disabled")
0160 #  define QVERIFY_THROWS_NO_EXCEPTION(...) \
0161     static_assert(false, "Support for exceptions is disabled")
0162 
0163 #endif // !QT_NO_EXCEPTIONS
0164 
0165 /* Ideally we would adapt qWaitFor(), or a variant on it, to implement roughly
0166  * what the following provides as QTRY_LOOP_IMPL(); however, for now, the
0167  * reporting of how much to increase the timeout to (if within a factor of two)
0168  * on failure and the check for (QTest::runningTest() &&
0169  * QTest::currentTestResolved()) go beyond qWaitFor(). (We no longer care about
0170  * the bug in MSVC < 2017 that precluded using qWaitFor() in the implementation
0171  * here, see QTBUG-59096.)
0172  */
0173 
0174 // NB: not do {...} while (0) wrapped, as qt_test_i is accessed after it
0175 #define QTRY_LOOP_IMPL(expr, timeoutValue, step) \
0176     if (!(expr)) { \
0177         QTest::qWait(0); \
0178     } \
0179     std::chrono::milliseconds timeoutValueMs(timeoutValue); \
0180     std::chrono::milliseconds stepMs(step); \
0181     auto qt_test_i = std::chrono::milliseconds(0); \
0182     for (; qt_test_i < timeoutValueMs && !(QTest::runningTest() && QTest::currentTestResolved()) \
0183              && !(expr); qt_test_i += stepMs) { \
0184         QTest::qWait(stepMs); \
0185     }
0186 // Ends in a for-block, so doesn't want a following semicolon.
0187 
0188 #define QTRY_TIMEOUT_DEBUG_IMPL(expr, timeoutValue, step) \
0189     if (!(QTest::runningTest() && QTest::currentTestResolved()) && !(expr)) { \
0190         QTRY_LOOP_IMPL(expr, 2 * (timeoutValue), step) \
0191         if ((expr)) { \
0192             QFAIL(qPrintable(QTest::Internal::formatTryTimeoutDebugMessage(\
0193                                  u8"" #expr, timeoutValue, timeoutValue + qt_test_i))); \
0194         } \
0195     }
0196 
0197 #define QTRY_IMPL(expr, timeoutAsGiven)\
0198     const auto qt_test_timeoutAsMs = [&] { \
0199             /* make 5s work w/o user action: */ \
0200             using namespace std::chrono_literals; \
0201             return std::chrono::milliseconds{timeoutAsGiven}; \
0202         }(); \
0203     const auto qt_test_step = qt_test_timeoutAsMs < std::chrono::milliseconds(350) \
0204                               ? qt_test_timeoutAsMs / 7 + std::chrono::milliseconds(1) \
0205                               : std::chrono::milliseconds(50); \
0206     { QTRY_LOOP_IMPL(expr, qt_test_timeoutAsMs, qt_test_step) } \
0207     QTRY_TIMEOUT_DEBUG_IMPL(expr, qt_test_timeoutAsMs, qt_test_step)
0208 // Ends with an if-block, so doesn't want a following semicolon.
0209 
0210 // Will try to wait for the expression to become true while allowing event processing
0211 #define QTRY_VERIFY_WITH_TIMEOUT(expr, timeout) \
0212 do { \
0213     QTRY_IMPL(expr, timeout) \
0214     QVERIFY(expr); \
0215 } while (false)
0216 
0217 #define QTRY_VERIFY(expr) QTRY_VERIFY_WITH_TIMEOUT( \
0218     expr, QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0219 
0220 // Will try to wait for the expression to become true while allowing event processing
0221 #define QTRY_VERIFY2_WITH_TIMEOUT(expr, messageExpression, timeout) \
0222 do { \
0223     QTRY_IMPL(expr, timeout) \
0224     QVERIFY2(expr, messageExpression); \
0225 } while (false)
0226 
0227 #define QTRY_VERIFY2(expr, messageExpression) \
0228     QTRY_VERIFY2_WITH_TIMEOUT(expr, messageExpression, \
0229         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0230 
0231 // Will try to wait for the comparison to become successful while allowing event processing
0232 #define QTRY_COMPARE_WITH_TIMEOUT(expr, expected, timeout) \
0233 do { \
0234     QTRY_IMPL((expr) == (expected), timeout) \
0235     QCOMPARE(expr, expected); \
0236 } while (false)
0237 
0238 #define QTRY_COMPARE(expr, expected) \
0239     QTRY_COMPARE_WITH_TIMEOUT(expr, expected, \
0240         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0241 
0242 #define QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, op, opId, timeout) \
0243 do { \
0244     using Q_Cmp = QTest::Internal::Compare<QTest::ComparisonOperation::opId>; \
0245     QTRY_IMPL(Q_Cmp::compare((computed), (baseline)), timeout) \
0246     QCOMPARE_OP_IMPL(computed, baseline, op, opId); \
0247 } while (false)
0248 
0249 #define QTRY_COMPARE_EQ_WITH_TIMEOUT(computed, baseline, timeout) \
0250     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, ==, Equal, timeout)
0251 
0252 #define QTRY_COMPARE_EQ(computed, baseline) \
0253     QTRY_COMPARE_EQ_WITH_TIMEOUT(computed, baseline, \
0254         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0255 
0256 #define QTRY_COMPARE_NE_WITH_TIMEOUT(computed, baseline, timeout) \
0257     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, !=, NotEqual, timeout)
0258 
0259 #define QTRY_COMPARE_NE(computed, baseline) \
0260     QTRY_COMPARE_NE_WITH_TIMEOUT(computed, baseline, \
0261         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0262 
0263 #define QTRY_COMPARE_LT_WITH_TIMEOUT(computed, baseline, timeout) \
0264     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, <, LessThan, timeout)
0265 
0266 #define QTRY_COMPARE_LT(computed, baseline) \
0267     QTRY_COMPARE_LT_WITH_TIMEOUT(computed, baseline, \
0268         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0269 
0270 #define QTRY_COMPARE_LE_WITH_TIMEOUT(computed, baseline, timeout) \
0271     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, <=, LessThanOrEqual, timeout)
0272 
0273 #define QTRY_COMPARE_LE(computed, baseline) \
0274     QTRY_COMPARE_LE_WITH_TIMEOUT(computed, baseline, \
0275         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0276 
0277 #define QTRY_COMPARE_GT_WITH_TIMEOUT(computed, baseline, timeout) \
0278     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, >, GreaterThan, timeout)
0279 
0280 #define QTRY_COMPARE_GT(computed, baseline) \
0281     QTRY_COMPARE_GT_WITH_TIMEOUT(computed, baseline, \
0282         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0283 
0284 #define QTRY_COMPARE_GE_WITH_TIMEOUT(computed, baseline, timeout) \
0285     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, >=, GreaterThanOrEqual, timeout)
0286 
0287 #define QTRY_COMPARE_GE(computed, baseline) \
0288     QTRY_COMPARE_GE_WITH_TIMEOUT(computed, baseline, \
0289         QTest::defaultTryTimeout.load(std::memory_order_relaxed))
0290 
0291 #define QSKIP_INTERNAL(statement) \
0292 do {\
0293     QTest::qSkip(static_cast<const char *>(statement), __FILE__, __LINE__);\
0294     QTEST_SKIP_ACTION; \
0295 } while (false)
0296 
0297 #define QSKIP(statement, ...) QSKIP_INTERNAL(statement)
0298 
0299 #define QEXPECT_FAIL(dataIndex, comment, mode)\
0300 do {\
0301     if (!QTest::qExpectFail(dataIndex, static_cast<const char *>(comment), QTest::mode, __FILE__, __LINE__))\
0302         QTEST_FAIL_ACTION; \
0303 } while (false)
0304 
0305 #define QFETCH(Type, name)\
0306     Type name = *static_cast<Type *>(QTest::qData(#name, ::qMetaTypeId<typename std::remove_cv<Type >::type>()))
0307 
0308 #define QFETCH_GLOBAL(Type, name)\
0309     Type name = *static_cast<Type *>(QTest::qGlobalData(#name, ::qMetaTypeId<typename std::remove_cv<Type >::type>()))
0310 
0311 #define QTEST(actual, testElement)\
0312 do {\
0313     if (!QTest::qTest(actual, testElement, #actual, #testElement, __FILE__, __LINE__))\
0314         QTEST_FAIL_ACTION; \
0315 } while (false)
0316 
0317 #ifdef __cpp_lib_three_way_comparison
0318 #define QCOMPARE_3WAY(lhs, rhs, order) \
0319 do { \
0320         if (!QTest::qCompare3Way(lhs, rhs, order, #lhs, #rhs, #order, __FILE__, __LINE__)) \
0321             QTEST_FAIL_ACTION; \
0322 } while (false)
0323 #else
0324 #define QCOMPARE_3WAY(...) \
0325     static_assert(false, "QCOMPARE_3WAY test requires C++20 operator<=>()")
0326 #endif // __cpp_lib_three_way_comparison
0327 
0328 #ifdef QT_TESTCASE_BUILDDIR
0329 
0330 #ifndef QT_TESTCASE_SOURCEDIR
0331 #define QT_TESTCASE_SOURCEDIR nullptr
0332 #endif
0333 
0334 # define QFINDTESTDATA(basepath)\
0335     QTest::qFindTestData(basepath, __FILE__, __LINE__, QT_TESTCASE_BUILDDIR, QT_TESTCASE_SOURCEDIR)
0336 #else
0337 # define QFINDTESTDATA(basepath)\
0338     QTest::qFindTestData(basepath, __FILE__, __LINE__)
0339 #endif
0340 
0341 # define QEXTRACTTESTDATA(resourcePath) \
0342     QTest::qExtractTestData(resourcePath)
0343 
0344 class QObject;
0345 class QTestData;
0346 
0347 namespace QTest
0348 {
0349     namespace Internal {
0350 
0351     [[noreturn]] Q_TESTLIB_EXPORT void throwOnFail();
0352     [[noreturn]] Q_TESTLIB_EXPORT void throwOnSkip();
0353     Q_TESTLIB_EXPORT void maybeThrowOnFail();
0354     Q_TESTLIB_EXPORT void maybeThrowOnSkip();
0355 
0356     Q_DECL_COLD_FUNCTION
0357     Q_TESTLIB_EXPORT QString formatTryTimeoutDebugMessage(q_no_char8_t::QUtf8StringView expr,
0358                                                           std::chrono::milliseconds timeout,
0359                                                           std::chrono::milliseconds actual);
0360     Q_TESTLIB_EXPORT Q_DECL_COLD_FUNCTION
0361     const char *formatPropertyTestHelperFailure(char *msg, size_t maxMsgLen,
0362                                                 const char *actual, const char *expected,
0363                                                 const char *actualExpr,
0364                                                 const char *expectedExpr);
0365 
0366     template <ComparisonOperation> struct Compare;
0367     template <> struct Compare<ComparisonOperation::Equal>
0368     {
0369         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0370         { return std::forward<T1>(lhs) == std::forward<T2>(rhs); }
0371     };
0372     template <> struct Compare<ComparisonOperation::NotEqual>
0373     {
0374         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0375         { return std::forward<T1>(lhs) != std::forward<T2>(rhs); }
0376     };
0377     template <> struct Compare<ComparisonOperation::LessThan>
0378     {
0379         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0380         { return std::forward<T1>(lhs) < std::forward<T2>(rhs); }
0381     };
0382     template <> struct Compare<ComparisonOperation::LessThanOrEqual>
0383     {
0384         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0385         { return std::forward<T1>(lhs) <= std::forward<T2>(rhs); }
0386     };
0387     template <> struct Compare<ComparisonOperation::GreaterThan>
0388     {
0389         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0390         { return std::forward<T1>(lhs) > std::forward<T2>(rhs); }
0391     };
0392     template <> struct Compare<ComparisonOperation::GreaterThanOrEqual>
0393     {
0394         template <typename T1, typename T2> static bool compare(T1 &&lhs, T2 &&rhs)
0395         { return std::forward<T1>(lhs) >= std::forward<T2>(rhs); }
0396     };
0397 
0398     template <typename T1> const char *genericToString(const void *arg)
0399     {
0400         using QTest::toString;
0401         return toString(*static_cast<const T1 *>(arg));
0402     }
0403 
0404     template <> inline const char *genericToString<char *>(const void *arg)
0405     {
0406         using QTest::toString;
0407         return toString(static_cast<const char *>(arg));
0408     }
0409 
0410     template <> inline const char *genericToString<std::nullptr_t>(const void *)
0411     {
0412         return QTest::toString(nullptr);
0413     }
0414 
0415     template <typename T> const char *pointerToString(const void *arg)
0416     {
0417         using QTest::toString;
0418         return toString(static_cast<const T *>(arg));
0419     }
0420 
0421     // Exported so Qt Quick Test can also use it for generating backtraces upon crashes.
0422     Q_TESTLIB_EXPORT extern bool noCrashHandler;
0423 
0424     } // namespace Internal
0425 
0426     Q_TESTLIB_EXPORT void qInit(QObject *testObject, int argc = 0, char **argv = nullptr);
0427     Q_TESTLIB_EXPORT int qRun();
0428     Q_TESTLIB_EXPORT void qCleanup();
0429 
0430     Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = nullptr);
0431     Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments);
0432 
0433 #if QT_CONFIG(batch_test_support) || defined(Q_QDOC)
0434     using TestEntryFunction = std::function<int(int, char **)>;
0435     Q_TESTLIB_EXPORT void qRegisterTestCase(const QString &name, TestEntryFunction entryFunction);
0436 #endif  // QT_CONFIG(batch_test_support)
0437 
0438     Q_TESTLIB_EXPORT void setMainSourcePath(const char *file, const char *builddir = nullptr);
0439     Q_TESTLIB_EXPORT void setThrowOnFail(bool enable) noexcept;
0440     Q_TESTLIB_EXPORT void setThrowOnSkip(bool enable) noexcept;
0441 
0442     class ThrowOnFailEnabler {
0443         Q_DISABLE_COPY_MOVE(ThrowOnFailEnabler)
0444     public:
0445         ThrowOnFailEnabler() { setThrowOnFail(true); }
0446         ~ThrowOnFailEnabler() { setThrowOnFail(false); }
0447     };
0448 
0449     class ThrowOnSkipEnabler {
0450         Q_DISABLE_COPY_MOVE(ThrowOnSkipEnabler)
0451     public:
0452         ThrowOnSkipEnabler() { setThrowOnSkip(true); }
0453         ~ThrowOnSkipEnabler() { setThrowOnSkip(false); }
0454     };
0455 
0456     class ThrowOnFailDisabler {
0457         Q_DISABLE_COPY_MOVE(ThrowOnFailDisabler)
0458     public:
0459         ThrowOnFailDisabler() { setThrowOnFail(false); }
0460         ~ThrowOnFailDisabler() { setThrowOnFail(true); }
0461     };
0462 
0463     class ThrowOnSkipDisabler {
0464         Q_DISABLE_COPY_MOVE(ThrowOnSkipDisabler)
0465     public:
0466         ThrowOnSkipDisabler() { setThrowOnSkip(false); }
0467         ~ThrowOnSkipDisabler() { setThrowOnSkip(true); }
0468     };
0469 
0470     Q_TESTLIB_EXPORT bool qVerify(bool statement, const char *statementStr, const char *description,
0471                                  const char *file, int line);
0472     Q_DECL_COLD_FUNCTION
0473     Q_TESTLIB_EXPORT void qFail(const char *message, const char *file, int line);
0474     Q_TESTLIB_EXPORT void qSkip(const char *message, const char *file, int line);
0475     Q_TESTLIB_EXPORT bool qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode,
0476                            const char *file, int line);
0477     Q_DECL_COLD_FUNCTION
0478     Q_TESTLIB_EXPORT void qCaught(const char *expected, const char *what, const char *file, int line);
0479     Q_DECL_COLD_FUNCTION
0480     Q_TESTLIB_EXPORT void qCaught(const char *expected, const char *file, int line);
0481 #if QT_DEPRECATED_SINCE(6, 3)
0482     QT_DEPRECATED_VERSION_X_6_3("Use qWarning() instead")
0483     Q_TESTLIB_EXPORT void qWarn(const char *message, const char *file = nullptr, int line = 0);
0484 #endif
0485     Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message);
0486 #if QT_CONFIG(regularexpression)
0487     Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const QRegularExpression &messagePattern);
0488 #endif
0489     Q_TESTLIB_EXPORT void failOnWarning();
0490     Q_TESTLIB_EXPORT void failOnWarning(const char *message);
0491 #if QT_CONFIG(regularexpression)
0492     Q_TESTLIB_EXPORT void failOnWarning(const QRegularExpression &messagePattern);
0493 #endif
0494 
0495 #if QT_CONFIG(temporaryfile)
0496     Q_TESTLIB_EXPORT QSharedPointer<QTemporaryDir> qExtractTestData(const QString &dirName);
0497 #endif
0498     Q_TESTLIB_EXPORT QString qFindTestData(const char* basepath, const char* file = nullptr, int line = 0, const char* builddir = nullptr, const char* sourcedir = nullptr);
0499     Q_TESTLIB_EXPORT QString qFindTestData(const QString& basepath, const char* file = nullptr, int line = 0, const char* builddir = nullptr, const char *sourcedir = nullptr);
0500 
0501     Q_TESTLIB_EXPORT void *qData(const char *tagName, int typeId);
0502     Q_TESTLIB_EXPORT void *qGlobalData(const char *tagName, int typeId);
0503     Q_TESTLIB_EXPORT void *qElementData(const char *elementName, int metaTypeId);
0504     Q_TESTLIB_EXPORT QObject *testObject();
0505 
0506     Q_TESTLIB_EXPORT const char *currentAppName();
0507 
0508     Q_TESTLIB_EXPORT const char *currentTestFunction();
0509     Q_TESTLIB_EXPORT const char *currentDataTag();
0510     Q_TESTLIB_EXPORT const char *currentGlobalDataTag();
0511     Q_TESTLIB_EXPORT bool currentTestFailed();
0512     Q_TESTLIB_EXPORT bool currentTestResolved();
0513     Q_TESTLIB_EXPORT bool runningTest(); // Internal, for use by macros and QTestEventLoop.
0514 
0515     Q_TESTLIB_EXPORT Qt::Key asciiToKey(char ascii);
0516     Q_TESTLIB_EXPORT char keyToAscii(Qt::Key key);
0517 
0518 #if QT_DEPRECATED_SINCE(6, 4)
0519     QT_DEPRECATED_VERSION_X_6_4("use an overload that takes a formatter callback, "
0520                                 "or an overload that takes only failure message, if you "
0521                                 "do not need to stringify the values")
0522     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0523                                          char *actualVal, char *expectedVal,
0524                                          const char *actual, const char *expected,
0525                                          const char *file, int line);
0526 #endif // QT_DEPRECATED_SINCE(6, 4)
0527 #if QT_DEPRECATED_SINCE(6, 8)
0528     QT_DEPRECATED_VERSION_X_6_8("use an overload that takes a formatter callback, "
0529                                 "or an overload that takes only failure message, if you "
0530                                 "do not need to stringify the values")
0531     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0532                                          qxp::function_ref<const char*()> actualVal,
0533                                          qxp::function_ref<const char*()> expectedVal,
0534                                          const char *actual, const char *expected,
0535                                          const char *file, int line);
0536 #endif // QT_DEPRECATED_SINCE(6, 8)
0537     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0538                                          const void *actualPtr, const void *expectedPtr,
0539                                          const char *(*actualFormatter)(const void *),
0540                                          const char *(*expectedFormatter)(const void *),
0541                                          const char *actual, const char *expected,
0542                                          const char *file, int line);
0543     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0544                                          const char *actual, const char *expected,
0545                                          const char *file, int line);
0546 
0547     Q_TESTLIB_EXPORT bool compare_3way_helper(bool success, const char *failureMsg,
0548                                               const void *lhsPtr, const void *rhsPtr,
0549                                               const char *(*lhsFormatter)(const void*),
0550                                               const char *(*rhsFormatter)(const void*),
0551                                               const char *lhsStr, const char *rhsStr,
0552                                               const char *(*actualOrderFormatter)(const void *),
0553                                               const char *(*expectedOrderFormatter)(const void *),
0554                                               const void *actualOrderPtr,
0555                                               const void *expectedOrderPtr,
0556                                               const char *expectedExpression,
0557                                               const char *file, int line);
0558 
0559     Q_TESTLIB_EXPORT void addColumnInternal(int id, const char *name);
0560 
0561     template <typename T>
0562     inline void addColumn(const char *name, T * = nullptr)
0563     {
0564         using QIsSameTConstChar = std::is_same<T, const char*>;
0565         static_assert(!QIsSameTConstChar::value, "const char* is not allowed as a test data format.");
0566         addColumnInternal(qMetaTypeId<T>(), name);
0567     }
0568     Q_TESTLIB_EXPORT QTestData &newRow(const char *dataTag);
0569     Q_TESTLIB_EXPORT QTestData &addRow(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
0570 
0571     Q_TESTLIB_EXPORT bool qCompare(qfloat16 const &t1, qfloat16 const &t2,
0572                     const char *actual, const char *expected, const char *file, int line);
0573 
0574     Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2,
0575                     const char *actual, const char *expected, const char *file, int line);
0576 
0577     Q_TESTLIB_EXPORT bool qCompare(double const &t1, double const &t2,
0578                     const char *actual, const char *expected, const char *file, int line);
0579 
0580     Q_TESTLIB_EXPORT bool qCompare(int t1, int t2, const char *actual, const char *expected,
0581                                    const char *file, int line);
0582 
0583 #if QT_POINTER_SIZE == 8
0584     Q_TESTLIB_EXPORT bool qCompare(qsizetype t1, qsizetype t2, const char *actual, const char *expected,
0585                                    const char *file, int line);
0586 #endif
0587 
0588     Q_TESTLIB_EXPORT bool qCompare(unsigned t1, unsigned t2, const char *actual, const char *expected,
0589                                    const char *file, int line);
0590 
0591     Q_TESTLIB_EXPORT bool qCompare(QStringView t1, QStringView t2,
0592                                    const char *actual, const char *expected,
0593                                    const char *file, int line);
0594     Q_TESTLIB_EXPORT bool qCompare(QStringView t1, const QLatin1StringView &t2,
0595                                    const char *actual, const char *expected,
0596                                    const char *file, int line);
0597     Q_TESTLIB_EXPORT bool qCompare(const QLatin1StringView &t1, QStringView t2,
0598                                    const char *actual, const char *expected,
0599                                    const char *file, int line);
0600     inline bool qCompare(const QString &t1, const QString &t2,
0601                          const char *actual, const char *expected,
0602                          const char *file, int line)
0603     {
0604         return qCompare(QStringView(t1), QStringView(t2), actual, expected, file, line);
0605     }
0606     inline bool qCompare(const QString &t1, const QLatin1StringView &t2,
0607                          const char *actual, const char *expected,
0608                          const char *file, int line)
0609     {
0610         return qCompare(QStringView(t1), t2, actual, expected, file, line);
0611     }
0612     inline bool qCompare(const QLatin1StringView &t1, const QString &t2,
0613                          const char *actual, const char *expected,
0614                          const char *file, int line)
0615     {
0616         return qCompare(t1, QStringView(t2), actual, expected, file, line);
0617     }
0618 
0619     inline bool compare_ptr_helper(const volatile void *t1, const volatile void *t2, const char *actual,
0620                                    const char *expected, const char *file, int line)
0621     {
0622         auto formatter = Internal::pointerToString<void>;
0623         return compare_helper(t1 == t2, "Compared pointers are not the same",
0624                               const_cast<const void *>(t1), const_cast<const void *>(t2),
0625                               formatter, formatter, actual, expected, file, line);
0626     }
0627 
0628     inline bool compare_ptr_helper(const volatile QObject *t1, const volatile QObject *t2, const char *actual,
0629                                    const char *expected, const char *file, int line)
0630     {
0631         auto formatter = Internal::pointerToString<QObject>;
0632         return compare_helper(t1 == t2, "Compared QObject pointers are not the same",
0633                               const_cast<const QObject *>(t1), const_cast<const QObject *>(t2),
0634                               formatter, formatter, actual, expected, file, line);
0635     }
0636 
0637     inline bool compare_ptr_helper(const volatile QObject *t1, std::nullptr_t, const char *actual,
0638                                    const char *expected, const char *file, int line)
0639     {
0640         auto lhsFormatter = Internal::pointerToString<QObject>;
0641         auto rhsFormatter = Internal::genericToString<std::nullptr_t>;
0642         return compare_helper(t1 == nullptr, "Compared QObject pointers are not the same",
0643                               const_cast<const QObject *>(t1), nullptr,
0644                               lhsFormatter, rhsFormatter, actual, expected, file, line);
0645     }
0646 
0647     inline bool compare_ptr_helper(std::nullptr_t, const volatile QObject *t2, const char *actual,
0648                                    const char *expected, const char *file, int line)
0649     {
0650         auto lhsFormatter = Internal::genericToString<std::nullptr_t>;
0651         auto rhsFormatter = Internal::pointerToString<QObject>;
0652         return compare_helper(nullptr == t2, "Compared QObject pointers are not the same",
0653                               nullptr, const_cast<const QObject *>(t2),
0654                               lhsFormatter, rhsFormatter, actual, expected, file, line);
0655     }
0656 
0657     inline bool compare_ptr_helper(const volatile void *t1, std::nullptr_t, const char *actual,
0658                                    const char *expected, const char *file, int line)
0659     {
0660         auto lhsFormatter = Internal::pointerToString<void>;
0661         auto rhsFormatter = Internal::genericToString<std::nullptr_t>;
0662         return compare_helper(t1 == nullptr, "Compared pointers are not the same",
0663                               const_cast<const void *>(t1), nullptr,
0664                               lhsFormatter, rhsFormatter, actual, expected, file, line);
0665     }
0666 
0667     inline bool compare_ptr_helper(std::nullptr_t, const volatile void *t2, const char *actual,
0668                                    const char *expected, const char *file, int line)
0669     {
0670         auto lhsFormatter = Internal::genericToString<std::nullptr_t>;
0671         auto rhsFormatter = Internal::pointerToString<void>;
0672         return compare_helper(nullptr == t2, "Compared pointers are not the same",
0673                               nullptr, const_cast<const void *>(t2),
0674                               lhsFormatter, rhsFormatter, actual, expected, file, line);
0675     }
0676 
0677     template <typename T1, typename T2 = T1>
0678     inline bool qCompare(const T1 &t1, const T2 &t2, const char *actual, const char *expected,
0679                          const char *file, int line)
0680     {
0681         using Internal::genericToString;
0682         if constexpr (QtPrivate::is_standard_or_extended_integer_type_v<T1>
0683                       && QtPrivate::is_standard_or_extended_integer_type_v<T2>) {
0684             return compare_helper(q20::cmp_equal(t1, t2), "Compared values are not the same",
0685                                   std::addressof(t1), std::addressof(t2),
0686                                   genericToString<T1>, genericToString<T2>,
0687                                   actual, expected, file, line);
0688         } else {
0689             return compare_helper(t1 == t2, "Compared values are not the same",
0690                                   std::addressof(t1), std::addressof(t2),
0691                                   genericToString<T1>, genericToString<T2>,
0692                                   actual, expected, file, line);
0693         }
0694     }
0695 
0696     inline bool qCompare(double const &t1, float const &t2, const char *actual,
0697                                  const char *expected, const char *file, int line)
0698     {
0699         return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
0700     }
0701 
0702     inline bool qCompare(float const &t1, double const &t2, const char *actual,
0703                                  const char *expected, const char *file, int line)
0704     {
0705         return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
0706     }
0707 
0708     template <typename T>
0709     inline bool qCompare(const T *t1, const T *t2, const char *actual, const char *expected,
0710                         const char *file, int line)
0711     {
0712         return compare_ptr_helper(t1, t2, actual, expected, file, line);
0713     }
0714     template <typename T>
0715     inline bool qCompare(T *t1, T *t2, const char *actual, const char *expected,
0716                         const char *file, int line)
0717     {
0718         return compare_ptr_helper(t1, t2, actual, expected, file, line);
0719     }
0720 
0721     template <typename T>
0722     inline bool qCompare(T *t1, std::nullptr_t, const char *actual, const char *expected,
0723                         const char *file, int line)
0724     {
0725         return compare_ptr_helper(t1, nullptr, actual, expected, file, line);
0726     }
0727     template <typename T>
0728     inline bool qCompare(std::nullptr_t, T *t2, const char *actual, const char *expected,
0729                         const char *file, int line)
0730     {
0731         return compare_ptr_helper(nullptr, t2, actual, expected, file, line);
0732     }
0733 
0734     template <typename T1, typename T2>
0735     inline bool qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected,
0736                         const char *file, int line)
0737     {
0738         return compare_ptr_helper(t1, static_cast<const T1 *>(t2), actual, expected, file, line);
0739     }
0740     template <typename T1, typename T2>
0741     inline bool qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected,
0742                         const char *file, int line)
0743     {
0744         return compare_ptr_helper(const_cast<const T1 *>(t1),
0745                 static_cast<const T1 *>(const_cast<const T2 *>(t2)), actual, expected, file, line);
0746     }
0747     inline bool qCompare(const char *t1, const char *t2, const char *actual,
0748                                        const char *expected, const char *file, int line)
0749     {
0750         return compare_string_helper(t1, t2, actual, expected, file, line);
0751     }
0752     inline bool qCompare(char *t1, char *t2, const char *actual, const char *expected,
0753                         const char *file, int line)
0754     {
0755         return compare_string_helper(t1, t2, actual, expected, file, line);
0756     }
0757 
0758     /* The next two overloads are for MSVC that shows problems with implicit
0759        conversions
0760      */
0761     inline bool qCompare(char *t1, const char *t2, const char *actual,
0762                          const char *expected, const char *file, int line)
0763     {
0764         return compare_string_helper(t1, t2, actual, expected, file, line);
0765     }
0766     inline bool qCompare(const char *t1, char *t2, const char *actual,
0767                          const char *expected, const char *file, int line)
0768     {
0769         return compare_string_helper(t1, t2, actual, expected, file, line);
0770     }
0771 
0772     template <class T>
0773     inline bool qTest(const T& actual, const char *elementName, const char *actualStr,
0774                      const char *expected, const char *file, int line)
0775     {
0776         return qCompare(actual, *static_cast<const T *>(QTest::qElementData(elementName,
0777                        qMetaTypeId<T>())), actualStr, expected, file, line);
0778     }
0779 
0780 #if QT_DEPRECATED_SINCE(6, 8)
0781     QT_DEPRECATED_VERSION_X_6_8("use the overload without qxp::function_ref")
0782     Q_TESTLIB_EXPORT bool reportResult(bool success, qxp::function_ref<const char*()> lhs,
0783                                        qxp::function_ref<const char*()> rhs,
0784                                        const char *lhsExpr, const char *rhsExpr,
0785                                        ComparisonOperation op, const char *file, int line);
0786 #endif // QT_DEPRECATED_SINCE(6, 8)
0787 
0788     Q_TESTLIB_EXPORT bool reportResult(bool success, const void *lhs, const void *rhs,
0789                                        const char *(*lhsFormatter)(const void*),
0790                                        const char *(*rhsFormatter)(const void*),
0791                                        const char *lhsExpr, const char *rhsExpr,
0792                                        ComparisonOperation op, const char *file, int line);
0793 
0794     template <ComparisonOperation op, typename T1, typename T2 = T1>
0795     inline bool qCompareOp(T1 &&lhs, T2 &&rhs, const char *lhsExpr, const char *rhsExpr,
0796                            const char *file, int line)
0797     {
0798         using D1 = std::decay_t<T1>;
0799         using D2 = std::decay_t<T2>;
0800         using Internal::genericToString;
0801         using Comparator = Internal::Compare<op>;
0802 
0803         // force decaying of T1 and T2
0804         auto doReport = [&](bool result, const D1 &lhs_, const D2 &rhs_) {
0805             return reportResult(result, std::addressof(lhs_), std::addressof(rhs_),
0806                                 genericToString<D1>, genericToString<D2>,
0807                                 lhsExpr, rhsExpr, op, file, line);
0808         };
0809 
0810         /* assumes that op does not actually move from lhs and rhs */
0811         bool result = Comparator::compare(std::forward<T1>(lhs), std::forward<T2>(rhs));
0812         return doReport(result, std::forward<T1>(lhs), std::forward<T2>(rhs));
0813     }
0814 
0815 #if defined(__cpp_lib_three_way_comparison)
0816     template <typename OrderingType, typename LHS, typename RHS = LHS>
0817     inline bool qCompare3Way(LHS &&lhs, RHS &&rhs, OrderingType order,
0818                              const char *lhsExpression,
0819                              const char *rhsExpression,
0820                              const char *resultExpression,
0821                              const char *file, int line)
0822     {
0823 #if defined(__cpp_concepts)
0824         static_assert(requires { lhs <=> rhs; },
0825                       "The three-way comparison operator (<=>) is not implemented");
0826 #endif // __cpp_concepts
0827         static_assert(QtOrderingPrivate::is_ordering_type_v<OrderingType>,
0828                       "Please provide, as the order parameter, a value "
0829                       "of one of the Qt::{partial,weak,strong}_ordering or "
0830                       "std::{partial,weak,strong}_ordering types.");
0831 
0832         const auto comparisonResult = std::forward<LHS>(lhs) <=> std::forward<RHS>(rhs);
0833         static_assert(std::is_same_v<decltype(QtOrderingPrivate::to_Qt(comparisonResult)),
0834                                      decltype(QtOrderingPrivate::to_Qt(order))>,
0835                       "The expected and actual ordering types should be the same "
0836                       "strength for proper comparison.");
0837 
0838         const OrderingType actualOrder = comparisonResult;
0839         using DLHS = q20::remove_cvref_t<LHS>;
0840         using DRHS = q20::remove_cvref_t<RHS>;
0841         using Internal::genericToString;
0842 
0843         return compare_3way_helper(actualOrder == order,
0844                                    "The result of operator<=>() is not what was expected",
0845                                    std::addressof(lhs), std::addressof(rhs),
0846                                    genericToString<DLHS>, genericToString<DRHS>,
0847                                    lhsExpression, rhsExpression,
0848                                    genericToString<decltype(comparisonResult)>,
0849                                    genericToString<OrderingType>,
0850                                    std::addressof(comparisonResult),
0851                                    std::addressof(order),
0852                                    resultExpression, file, line);
0853     }
0854 #else
0855     template <typename OrderingType, typename LHS, typename RHS = LHS>
0856     void qCompare3Way(LHS &&lhs, RHS &&rhs, OrderingType order,
0857                       const char *lhsExpression,
0858                       const char *rhsExpression,
0859                       const char *resultExpression,
0860                       const char *file, int line) = delete;
0861 #endif // __cpp_lib_three_way_comparison
0862 
0863 }
0864 
0865 #define QWARN(msg) QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
0866 
0867 QT_END_NAMESPACE
0868 
0869 #endif