File indexing completed on 2025-09-16 09:06:17
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 #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
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
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 \
0113 } QT_CATCH (...) { \
0114 QTest::qCaught(nullptr, __FILE__, __LINE__); \
0115 QTEST_FAIL_ACTION; \
0116 } \
0117 } while (false) \
0118
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 }
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 \
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
0149
0150
0151
0152
0153
0154
0155
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
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
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
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 \
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
0205
0206
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
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
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
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
0399 Q_TESTLIB_EXPORT extern bool noCrashHandler;
0400
0401 }
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
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();
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
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
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
0735
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
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
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
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
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
0838
0839 }
0840
0841 #define QWARN(msg) QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
0842
0843 QT_END_NAMESPACE
0844
0845 #endif