File indexing completed on 2026-08-03 09:26:49
0001
0002
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
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
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 \
0114 } QT_CATCH (...) { \
0115 QTest::qCaught(nullptr, __FILE__, __LINE__); \
0116 QTEST_FAIL_ACTION; \
0117 } \
0118 } while (false) \
0119
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 }
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 \
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
0150
0151
0152
0153
0154
0155
0156
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
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
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
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 \
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
0209
0210
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
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
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
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
0422 Q_TESTLIB_EXPORT extern bool noCrashHandler;
0423
0424 }
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
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();
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
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
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
0759
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
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
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
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
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
0862
0863 }
0864
0865 #define QWARN(msg) QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
0866
0867 QT_END_NAMESPACE
0868
0869 #endif