Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:06:17

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