Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:12:23

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 
0009 #include <QtCore/qstring.h>
0010 #include <QtCore/qnamespace.h>
0011 #include <QtCore/qmetatype.h>
0012 #include <QtCore/qmetaobject.h>
0013 #include <QtCore/qsharedpointer.h>
0014 #include <QtCore/qtemporarydir.h>
0015 #include <QtCore/qthread.h>
0016 #include <QtCore/qxpfunctional.h>
0017 
0018 #include <string.h>
0019 
0020 #ifndef QT_NO_EXCEPTIONS
0021 #  include <exception>
0022 #endif // QT_NO_EXCEPTIONS
0023 
0024 QT_BEGIN_NAMESPACE
0025 
0026 class qfloat16;
0027 class QRegularExpression;
0028 
0029 #define QVERIFY(statement) \
0030 do {\
0031     if (!QTest::qVerify(static_cast<bool>(statement), #statement, "", __FILE__, __LINE__))\
0032         return;\
0033 } while (false)
0034 
0035 #define QFAIL(message) \
0036 do {\
0037     QTest::qFail(static_cast<const char *>(message), __FILE__, __LINE__);\
0038     return;\
0039 } while (false)
0040 
0041 #define QVERIFY2(statement, description) \
0042 do {\
0043     if (statement) {\
0044         if (!QTest::qVerify(true, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
0045             return;\
0046     } else {\
0047         if (!QTest::qVerify(false, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
0048             return;\
0049     }\
0050 } while (false)
0051 
0052 #define QCOMPARE(actual, expected) \
0053 do {\
0054     if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
0055         return;\
0056 } while (false)
0057 
0058 // A wrapper lambda is introduced to extend the lifetime of lhs and rhs in
0059 // case they are temporary objects.
0060 // We also use IILE to prevent potential name clashes and shadowing of variables
0061 // from user code. A drawback of the approach is that it looks ugly :(
0062 #define QCOMPARE_OP_IMPL(lhs, rhs, op, opId) \
0063 do { \
0064     if (![](auto &&qt_lhs_arg, auto &&qt_rhs_arg) { \
0065         /* assumes that op does not actually move from qt_{lhs, rhs}_arg */ \
0066         return QTest::reportResult(std::forward<decltype(qt_lhs_arg)>(qt_lhs_arg) \
0067                                    op \
0068                                    std::forward<decltype(qt_rhs_arg)>(qt_rhs_arg), \
0069                                    [&qt_lhs_arg] { return QTest::toString(qt_lhs_arg); }, \
0070                                    [&qt_rhs_arg] { return QTest::toString(qt_rhs_arg); }, \
0071                                    #lhs, #rhs, QTest::ComparisonOperation::opId, \
0072                                    __FILE__, __LINE__); \
0073     }(lhs, rhs)) { \
0074         return; \
0075     } \
0076 } while (false)
0077 
0078 #define QCOMPARE_EQ(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, ==, Equal)
0079 #define QCOMPARE_NE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, !=, NotEqual)
0080 #define QCOMPARE_LT(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, <, LessThan)
0081 #define QCOMPARE_LE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, <=, LessThanOrEqual)
0082 #define QCOMPARE_GT(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, >, GreaterThan)
0083 #define QCOMPARE_GE(computed, baseline) QCOMPARE_OP_IMPL(computed, baseline, >=, GreaterThanOrEqual)
0084 
0085 #ifndef QT_NO_EXCEPTIONS
0086 
0087 #  define QVERIFY_THROWS_NO_EXCEPTION(...) \
0088     do { \
0089         QT_TRY { \
0090             __VA_ARGS__; \
0091             /* success */ \
0092         } QT_CATCH (...) { \
0093             QTest::qCaught(nullptr, __FILE__, __LINE__); \
0094             return; \
0095         } \
0096     } while (false) \
0097     /* end */
0098 
0099 #if QT_DEPRECATED_SINCE(6, 3)
0100 namespace QTest {
0101 QT_DEPRECATED_VERSION_X_6_3("Don't use QVERIFY_EXCEPTION_THROWN(expr, type) anymore, "
0102                             "use QVERIFY_THROWS_EXCEPTION(type, expr...) instead")
0103 inline void useVerifyThrowsException() {}
0104 } // namespace QTest
0105 #  define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
0106     QVERIFY_THROWS_EXCEPTION(exceptiontype, QTest::useVerifyThrowsException(); expression)
0107 #endif
0108 
0109 #  define QVERIFY_THROWS_EXCEPTION(exceptiontype, ...) \
0110     do {\
0111         QT_TRY {\
0112             __VA_ARGS__; \
0113             QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
0114                          " but no exception caught", __FILE__, __LINE__); \
0115             return; \
0116         } QT_CATCH (const exceptiontype &) { \
0117             /* success */ \
0118         } QT_CATCH (...) {\
0119             QTest::qCaught(#exceptiontype, __FILE__, __LINE__); \
0120             return; \
0121         }\
0122     } while (false)
0123 
0124 #else // QT_NO_EXCEPTIONS
0125 
0126 /*
0127  * These macros check whether the expression passed throws exceptions, but we can't
0128  * catch them to check because Qt has been compiled without exception support. We can't
0129  * skip the expression because it may have side effects and must be executed.
0130  * So, users must use Qt with exception support enabled if they use exceptions
0131  * in their code.
0132  */
0133 #  define QVERIFY_THROWS_EXCEPTION(...) \
0134     static_assert(false, "Support for exceptions is disabled")
0135 #  define QVERIFY_THROWS_NO_EXCEPTION(...) \
0136     static_assert(false, "Support for exceptions is disabled")
0137 
0138 #endif // !QT_NO_EXCEPTIONS
0139 
0140 /* Ideally we would adapt qWaitFor(), or a variant on it, to implement roughly
0141  * what the following provides as QTRY_LOOP_IMPL(); however, for now, the
0142  * reporting of how much to increase the timeout to (if within a factor of two)
0143  * on failure and the check for (QTest::runningTest() &&
0144  * QTest::currentTestResolved()) go beyond qWaitFor(). (We no longer care about
0145  * the bug in MSVC < 2017 that precluded using qWaitFor() in the implementation
0146  * here, see QTBUG-59096.)
0147  */
0148 
0149 // NB: not do {...} while (0) wrapped, as qt_test_i is accessed after it
0150 #define QTRY_LOOP_IMPL(expr, timeoutValue, step) \
0151     if (!(expr)) { \
0152         QTest::qWait(0); \
0153     } \
0154     int qt_test_i = 0; \
0155     for (; qt_test_i < timeoutValue && !(QTest::runningTest() && QTest::currentTestResolved()) \
0156              && !(expr); qt_test_i += step) { \
0157         QTest::qWait(step); \
0158     }
0159 // Ends in a for-block, so doesn't want a following semicolon.
0160 
0161 #define QTRY_TIMEOUT_DEBUG_IMPL(expr, timeoutValue, step) \
0162     if (!(QTest::runningTest() && QTest::currentTestResolved()) && !(expr)) { \
0163         QTRY_LOOP_IMPL(expr, 2 * (timeoutValue), step) \
0164         if ((expr)) { \
0165             QFAIL(qPrintable(QTest::Internal::formatTryTimeoutDebugMessage(\
0166                                  u8"" #expr, timeoutValue, timeoutValue + qt_test_i))); \
0167         } \
0168     }
0169 
0170 #define QTRY_IMPL(expr, timeout)\
0171     const int qt_test_step = timeout < 350 ? timeout / 7 + 1 : 50; \
0172     const int qt_test_timeoutValue = timeout; \
0173     { QTRY_LOOP_IMPL(expr, qt_test_timeoutValue, qt_test_step) } \
0174     QTRY_TIMEOUT_DEBUG_IMPL(expr, qt_test_timeoutValue, qt_test_step)
0175 // Ends with an if-block, so doesn't want a following semicolon.
0176 
0177 // Will try to wait for the expression to become true while allowing event processing
0178 #define QTRY_VERIFY_WITH_TIMEOUT(expr, timeout) \
0179 do { \
0180     QTRY_IMPL(expr, timeout) \
0181     QVERIFY(expr); \
0182 } while (false)
0183 
0184 #define QTRY_VERIFY(expr) QTRY_VERIFY_WITH_TIMEOUT(expr, 5000)
0185 
0186 // Will try to wait for the expression to become true while allowing event processing
0187 #define QTRY_VERIFY2_WITH_TIMEOUT(expr, messageExpression, timeout) \
0188 do { \
0189     QTRY_IMPL(expr, timeout) \
0190     QVERIFY2(expr, messageExpression); \
0191 } while (false)
0192 
0193 #define QTRY_VERIFY2(expr, messageExpression) QTRY_VERIFY2_WITH_TIMEOUT(expr, messageExpression, 5000)
0194 
0195 // Will try to wait for the comparison to become successful while allowing event processing
0196 #define QTRY_COMPARE_WITH_TIMEOUT(expr, expected, timeout) \
0197 do { \
0198     QTRY_IMPL((expr) == (expected), timeout) \
0199     QCOMPARE(expr, expected); \
0200 } while (false)
0201 
0202 #define QTRY_COMPARE(expr, expected) QTRY_COMPARE_WITH_TIMEOUT(expr, expected, 5000)
0203 
0204 #define QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, op, opId, timeout) \
0205 do { \
0206     QTRY_IMPL(((computed) op (baseline)), timeout) \
0207     QCOMPARE_OP_IMPL(computed, baseline, op, opId); \
0208 } while (false)
0209 
0210 #define QTRY_COMPARE_EQ_WITH_TIMEOUT(computed, baseline, timeout) \
0211     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, ==, Equal, timeout)
0212 
0213 #define QTRY_COMPARE_EQ(computed, baseline) QTRY_COMPARE_EQ_WITH_TIMEOUT(computed, baseline, 5000)
0214 
0215 #define QTRY_COMPARE_NE_WITH_TIMEOUT(computed, baseline, timeout) \
0216     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, !=, NotEqual, timeout)
0217 
0218 #define QTRY_COMPARE_NE(computed, baseline) QTRY_COMPARE_NE_WITH_TIMEOUT(computed, baseline, 5000)
0219 
0220 #define QTRY_COMPARE_LT_WITH_TIMEOUT(computed, baseline, timeout) \
0221     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, <, LessThan, timeout)
0222 
0223 #define QTRY_COMPARE_LT(computed, baseline) QTRY_COMPARE_LT_WITH_TIMEOUT(computed, baseline, 5000)
0224 
0225 #define QTRY_COMPARE_LE_WITH_TIMEOUT(computed, baseline, timeout) \
0226     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, <=, LessThanOrEqual, timeout)
0227 
0228 #define QTRY_COMPARE_LE(computed, baseline) QTRY_COMPARE_LE_WITH_TIMEOUT(computed, baseline, 5000)
0229 
0230 #define QTRY_COMPARE_GT_WITH_TIMEOUT(computed, baseline, timeout) \
0231     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, >, GreaterThan, timeout)
0232 
0233 #define QTRY_COMPARE_GT(computed, baseline) QTRY_COMPARE_GT_WITH_TIMEOUT(computed, baseline, 5000)
0234 
0235 #define QTRY_COMPARE_GE_WITH_TIMEOUT(computed, baseline, timeout) \
0236     QTRY_COMPARE_OP_WITH_TIMEOUT_IMPL(computed, baseline, >=, GreaterThanOrEqual, timeout)
0237 
0238 #define QTRY_COMPARE_GE(computed, baseline) QTRY_COMPARE_GE_WITH_TIMEOUT(computed, baseline, 5000)
0239 
0240 #define QSKIP_INTERNAL(statement) \
0241 do {\
0242     QTest::qSkip(static_cast<const char *>(statement), __FILE__, __LINE__);\
0243     return;\
0244 } while (false)
0245 
0246 #define QSKIP(statement, ...) QSKIP_INTERNAL(statement)
0247 
0248 #define QEXPECT_FAIL(dataIndex, comment, mode)\
0249 do {\
0250     if (!QTest::qExpectFail(dataIndex, static_cast<const char *>(comment), QTest::mode, __FILE__, __LINE__))\
0251         return;\
0252 } while (false)
0253 
0254 #define QFETCH(Type, name)\
0255     Type name = *static_cast<Type *>(QTest::qData(#name, ::qMetaTypeId<typename std::remove_cv<Type >::type>()))
0256 
0257 #define QFETCH_GLOBAL(Type, name)\
0258     Type name = *static_cast<Type *>(QTest::qGlobalData(#name, ::qMetaTypeId<typename std::remove_cv<Type >::type>()))
0259 
0260 #define QTEST(actual, testElement)\
0261 do {\
0262     if (!QTest::qTest(actual, testElement, #actual, #testElement, __FILE__, __LINE__))\
0263         return;\
0264 } while (false)
0265 
0266 #ifdef QT_TESTCASE_BUILDDIR
0267 
0268 #ifndef QT_TESTCASE_SOURCEDIR
0269 #define QT_TESTCASE_SOURCEDIR nullptr
0270 #endif
0271 
0272 # define QFINDTESTDATA(basepath)\
0273     QTest::qFindTestData(basepath, __FILE__, __LINE__, QT_TESTCASE_BUILDDIR, QT_TESTCASE_SOURCEDIR)
0274 #else
0275 # define QFINDTESTDATA(basepath)\
0276     QTest::qFindTestData(basepath, __FILE__, __LINE__)
0277 #endif
0278 
0279 # define QEXTRACTTESTDATA(resourcePath) \
0280     QTest::qExtractTestData(resourcePath)
0281 
0282 class QObject;
0283 class QTestData;
0284 
0285 #define QTEST_COMPARE_DECL(KLASS)\
0286     template<> Q_TESTLIB_EXPORT char *toString<KLASS >(const KLASS &);
0287 
0288 namespace QTest
0289 {
0290     namespace Internal {
0291 
0292     Q_TESTLIB_EXPORT QString formatTryTimeoutDebugMessage(q_no_char8_t::QUtf8StringView expr, int timeout, int actual);
0293 
0294     template<typename T> // Output registered enums
0295     inline typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, char*>::type toString(T e)
0296     {
0297         QMetaEnum me = QMetaEnum::fromType<T>();
0298         return qstrdup(me.valueToKey(int(e))); // int cast is necessary to support enum classes
0299     }
0300 
0301     template <typename T>
0302     inline typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value && std::is_enum_v<T>, char*>::type toString(const T &e)
0303     {
0304         return qstrdup(QByteArray::number(static_cast<std::underlying_type_t<T>>(e)).constData());
0305     }
0306 
0307     template <typename T> // Fallback; for built-in types debug streaming must be possible
0308     inline typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value && !std::is_enum_v<T>, char *>::type toString(const T &t)
0309     {
0310         char *result = nullptr;
0311 #ifndef QT_NO_DEBUG_STREAM
0312         if constexpr (QTypeTraits::has_ostream_operator_v<QDebug, T>) {
0313             result = qstrdup(QDebug::toString(t).toUtf8().constData());
0314         } else {
0315             static_assert(!QMetaTypeId2<T>::IsBuiltIn,
0316                         "Built-in type must implement debug streaming operator "
0317                         "or provide QTest::toString specialization");
0318         }
0319 #endif
0320         return result;
0321     }
0322 
0323     template<typename F> // Output QFlags of registered enumerations
0324     inline typename std::enable_if<QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f)
0325     {
0326         const QMetaEnum me = QMetaEnum::fromType<F>();
0327         return qstrdup(me.valueToKeys(int(f.toInt())).constData());
0328     }
0329 
0330     template <typename F> // Fallback: Output hex value
0331     inline typename std::enable_if<!QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f)
0332     {
0333         const size_t space = 3 + 2 * sizeof(unsigned); // 2 for 0x, two hex digits per byte, 1 for '\0'
0334         char *msg = new char[space];
0335         qsnprintf(msg, space, "0x%x", unsigned(f.toInt()));
0336         return msg;
0337     }
0338 
0339     } // namespace Internal
0340 
0341     template<typename T>
0342     inline char *toString(const T &t)
0343     {
0344         return Internal::toString(t);
0345     }
0346 
0347     template <typename T1, typename T2>
0348     inline char *toString(const std::pair<T1, T2> &pair);
0349 
0350     template <class... Types>
0351     inline char *toString(const std::tuple<Types...> &tuple);
0352 
0353     template <typename Rep, typename Period>
0354     inline char *toString(std::chrono::duration<Rep, Period> duration);
0355 
0356     Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, qsizetype length);
0357     Q_TESTLIB_EXPORT char *toPrettyCString(const char *unicode, qsizetype length);
0358     Q_TESTLIB_EXPORT char *toPrettyUnicode(QStringView string);
0359     Q_TESTLIB_EXPORT char *toString(const char *);
0360     Q_TESTLIB_EXPORT char *toString(const volatile void *);
0361     Q_TESTLIB_EXPORT char *toString(const void *); // ### FIXME: Qt 7: Remove
0362     Q_TESTLIB_EXPORT char *toString(const volatile QObject *);
0363 
0364     Q_TESTLIB_EXPORT void qInit(QObject *testObject, int argc = 0, char **argv = nullptr);
0365     Q_TESTLIB_EXPORT int qRun();
0366     Q_TESTLIB_EXPORT void qCleanup();
0367 
0368     Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = nullptr);
0369     Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments);
0370 
0371 #if QT_CONFIG(batch_test_support) || defined(Q_QDOC)
0372     using TestEntryFunction = int (*)(int, char **);
0373     Q_TESTLIB_EXPORT void qRegisterTestCase(const QString &name, TestEntryFunction entryFunction);
0374 #endif  // QT_CONFIG(batch_test_support)
0375 
0376     Q_TESTLIB_EXPORT void setMainSourcePath(const char *file, const char *builddir = nullptr);
0377 
0378     Q_TESTLIB_EXPORT bool qVerify(bool statement, const char *statementStr, const char *description,
0379                                  const char *file, int line);
0380     Q_DECL_COLD_FUNCTION
0381     Q_TESTLIB_EXPORT void qFail(const char *message, const char *file, int line);
0382     Q_TESTLIB_EXPORT void qSkip(const char *message, const char *file, int line);
0383     Q_TESTLIB_EXPORT bool qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode,
0384                            const char *file, int line);
0385     Q_DECL_COLD_FUNCTION
0386     Q_TESTLIB_EXPORT void qCaught(const char *expected, const char *what, const char *file, int line);
0387     Q_DECL_COLD_FUNCTION
0388     Q_TESTLIB_EXPORT void qCaught(const char *expected, const char *file, int line);
0389 #if QT_DEPRECATED_SINCE(6, 3)
0390     QT_DEPRECATED_VERSION_X_6_3("Use qWarning() instead")
0391     Q_TESTLIB_EXPORT void qWarn(const char *message, const char *file = nullptr, int line = 0);
0392 #endif
0393     Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message);
0394 #if QT_CONFIG(regularexpression)
0395     Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const QRegularExpression &messagePattern);
0396 #endif
0397     Q_TESTLIB_EXPORT void failOnWarning(const char *message);
0398 #if QT_CONFIG(regularexpression)
0399     Q_TESTLIB_EXPORT void failOnWarning(const QRegularExpression &messagePattern);
0400 #endif
0401 
0402 #if QT_CONFIG(temporaryfile)
0403     Q_TESTLIB_EXPORT QSharedPointer<QTemporaryDir> qExtractTestData(const QString &dirName);
0404 #endif
0405     Q_TESTLIB_EXPORT QString qFindTestData(const char* basepath, const char* file = nullptr, int line = 0, const char* builddir = nullptr, const char* sourcedir = nullptr);
0406     Q_TESTLIB_EXPORT QString qFindTestData(const QString& basepath, const char* file = nullptr, int line = 0, const char* builddir = nullptr, const char *sourcedir = nullptr);
0407 
0408     Q_TESTLIB_EXPORT void *qData(const char *tagName, int typeId);
0409     Q_TESTLIB_EXPORT void *qGlobalData(const char *tagName, int typeId);
0410     Q_TESTLIB_EXPORT void *qElementData(const char *elementName, int metaTypeId);
0411     Q_TESTLIB_EXPORT QObject *testObject();
0412 
0413     Q_TESTLIB_EXPORT const char *currentAppName();
0414 
0415     Q_TESTLIB_EXPORT const char *currentTestFunction();
0416     Q_TESTLIB_EXPORT const char *currentDataTag();
0417     Q_TESTLIB_EXPORT bool currentTestFailed();
0418     Q_TESTLIB_EXPORT bool currentTestResolved();
0419     Q_TESTLIB_EXPORT bool runningTest(); // Internal, for use by macros and QTestEventLoop.
0420 
0421     Q_TESTLIB_EXPORT Qt::Key asciiToKey(char ascii);
0422     Q_TESTLIB_EXPORT char keyToAscii(Qt::Key key);
0423 
0424     // ### TODO: remove QTestResult::compare() overload that takes char * values
0425     // when this overload is removed.
0426 #if QT_DEPRECATED_SINCE(6, 4)
0427     QT_DEPRECATED_VERSION_X_6_4("use an overload that takes function_ref as parameters, "
0428                                 "or an overload that takes only failure message, if you "
0429                                 "do not need to stringify the values")
0430     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0431                                          char *actualVal, char *expectedVal,
0432                                          const char *actual, const char *expected,
0433                                          const char *file, int line);
0434 #endif // QT_DEPRECATED_SINCE(6, 4)
0435     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0436                                          qxp::function_ref<const char*()> actualVal,
0437                                          qxp::function_ref<const char*()> expectedVal,
0438                                          const char *actual, const char *expected,
0439                                          const char *file, int line);
0440     Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg,
0441                                          const char *actual, const char *expected,
0442                                          const char *file, int line);
0443 
0444     Q_TESTLIB_EXPORT void addColumnInternal(int id, const char *name);
0445 
0446     template <typename T>
0447     inline void addColumn(const char *name, T * = nullptr)
0448     {
0449         using QIsSameTConstChar = std::is_same<T, const char*>;
0450         static_assert(!QIsSameTConstChar::value, "const char* is not allowed as a test data format.");
0451         addColumnInternal(qMetaTypeId<T>(), name);
0452     }
0453     Q_TESTLIB_EXPORT QTestData &newRow(const char *dataTag);
0454     Q_TESTLIB_EXPORT QTestData &addRow(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
0455 
0456     Q_TESTLIB_EXPORT bool qCompare(qfloat16 const &t1, qfloat16 const &t2,
0457                     const char *actual, const char *expected, const char *file, int line);
0458 
0459     Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2,
0460                     const char *actual, const char *expected, const char *file, int line);
0461 
0462     Q_TESTLIB_EXPORT bool qCompare(double const &t1, double const &t2,
0463                     const char *actual, const char *expected, const char *file, int line);
0464 
0465     Q_TESTLIB_EXPORT bool qCompare(int t1, int t2, const char *actual, const char *expected,
0466                                    const char *file, int line);
0467 
0468 #if QT_POINTER_SIZE == 8
0469     Q_TESTLIB_EXPORT bool qCompare(qsizetype t1, qsizetype t2, const char *actual, const char *expected,
0470                                    const char *file, int line);
0471 #endif
0472 
0473     Q_TESTLIB_EXPORT bool qCompare(unsigned t1, unsigned t2, const char *actual, const char *expected,
0474                                    const char *file, int line);
0475 
0476     Q_TESTLIB_EXPORT bool qCompare(QStringView t1, QStringView t2,
0477                                    const char *actual, const char *expected,
0478                                    const char *file, int line);
0479     Q_TESTLIB_EXPORT bool qCompare(QStringView t1, const QLatin1StringView &t2,
0480                                    const char *actual, const char *expected,
0481                                    const char *file, int line);
0482     Q_TESTLIB_EXPORT bool qCompare(const QLatin1StringView &t1, QStringView t2,
0483                                    const char *actual, const char *expected,
0484                                    const char *file, int line);
0485     inline bool qCompare(const QString &t1, const QString &t2,
0486                          const char *actual, const char *expected,
0487                          const char *file, int line)
0488     {
0489         return qCompare(QStringView(t1), QStringView(t2), actual, expected, file, line);
0490     }
0491     inline bool qCompare(const QString &t1, const QLatin1StringView &t2,
0492                          const char *actual, const char *expected,
0493                          const char *file, int line)
0494     {
0495         return qCompare(QStringView(t1), t2, actual, expected, file, line);
0496     }
0497     inline bool qCompare(const QLatin1StringView &t1, const QString &t2,
0498                          const char *actual, const char *expected,
0499                          const char *file, int line)
0500     {
0501         return qCompare(t1, QStringView(t2), actual, expected, file, line);
0502     }
0503 
0504     inline bool compare_ptr_helper(const volatile void *t1, const volatile void *t2, const char *actual,
0505                                    const char *expected, const char *file, int line)
0506     {
0507         return compare_helper(t1 == t2, "Compared pointers are not the same",
0508                               [t1] { return toString(t1); }, [t2] { return toString(t2); },
0509                               actual, expected, file, line);
0510     }
0511 
0512     inline bool compare_ptr_helper(const volatile QObject *t1, const volatile QObject *t2, const char *actual,
0513                                    const char *expected, const char *file, int line)
0514     {
0515         return compare_helper(t1 == t2, "Compared QObject pointers are not the same",
0516                               [t1] { return toString(t1); }, [t2] { return toString(t2); },
0517                               actual, expected, file, line);
0518     }
0519 
0520     inline bool compare_ptr_helper(const volatile QObject *t1, std::nullptr_t, const char *actual,
0521                                    const char *expected, const char *file, int line)
0522     {
0523         return compare_helper(t1 == nullptr, "Compared QObject pointers are not the same",
0524                               [t1] { return toString(t1); }, [] { return toString(nullptr); },
0525                               actual, expected, file, line);
0526     }
0527 
0528     inline bool compare_ptr_helper(std::nullptr_t, const volatile QObject *t2, const char *actual,
0529                                    const char *expected, const char *file, int line)
0530     {
0531         return compare_helper(nullptr == t2, "Compared QObject pointers are not the same",
0532                               [] { return toString(nullptr); }, [t2] { return toString(t2); },
0533                               actual, expected, file, line);
0534     }
0535 
0536     inline bool compare_ptr_helper(const volatile void *t1, std::nullptr_t, const char *actual,
0537                                    const char *expected, const char *file, int line)
0538     {
0539         return compare_helper(t1 == nullptr, "Compared pointers are not the same",
0540                               [t1] { return toString(t1); }, [] { return toString(nullptr); },
0541                               actual, expected, file, line);
0542     }
0543 
0544     inline bool compare_ptr_helper(std::nullptr_t, const volatile void *t2, const char *actual,
0545                                    const char *expected, const char *file, int line)
0546     {
0547         return compare_helper(nullptr == t2, "Compared pointers are not the same",
0548                               [] { return toString(nullptr); }, [t2] { return toString(t2); },
0549                               actual, expected, file, line);
0550     }
0551 
0552     Q_TESTLIB_EXPORT bool compare_string_helper(const char *t1, const char *t2, const char *actual,
0553                                       const char *expected, const char *file, int line);
0554 
0555     Q_TESTLIB_EXPORT char *formatString(const char *prefix, const char *suffix, size_t numArguments, ...);
0556 
0557 #ifndef Q_QDOC
0558     QTEST_COMPARE_DECL(short)
0559     QTEST_COMPARE_DECL(ushort)
0560     QTEST_COMPARE_DECL(int)
0561     QTEST_COMPARE_DECL(uint)
0562     QTEST_COMPARE_DECL(long)
0563     QTEST_COMPARE_DECL(ulong)
0564     QTEST_COMPARE_DECL(qint64)
0565     QTEST_COMPARE_DECL(quint64)
0566 
0567     QTEST_COMPARE_DECL(float)
0568     QTEST_COMPARE_DECL(double)
0569     QTEST_COMPARE_DECL(qfloat16)
0570     QTEST_COMPARE_DECL(char)
0571     QTEST_COMPARE_DECL(signed char)
0572     QTEST_COMPARE_DECL(unsigned char)
0573     QTEST_COMPARE_DECL(bool)
0574 #endif
0575 
0576     template <typename T1, typename T2 = T1>
0577     inline bool qCompare(const T1 &t1, const T2 &t2, const char *actual, const char *expected,
0578                          const char *file, int line)
0579     {
0580         return compare_helper(t1 == t2, "Compared values are not the same",
0581                               [&t1] { return toString(t1); }, [&t2] { return toString(t2); },
0582                               actual, expected, file, line);
0583     }
0584 
0585     inline bool qCompare(double const &t1, float const &t2, const char *actual,
0586                                  const char *expected, const char *file, int line)
0587     {
0588         return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
0589     }
0590 
0591     inline bool qCompare(float const &t1, double const &t2, const char *actual,
0592                                  const char *expected, const char *file, int line)
0593     {
0594         return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
0595     }
0596 
0597     template <typename T>
0598     inline bool qCompare(const T *t1, const T *t2, const char *actual, const char *expected,
0599                         const char *file, int line)
0600     {
0601         return compare_ptr_helper(t1, t2, actual, expected, file, line);
0602     }
0603     template <typename T>
0604     inline bool qCompare(T *t1, T *t2, const char *actual, const char *expected,
0605                         const char *file, int line)
0606     {
0607         return compare_ptr_helper(t1, t2, actual, expected, file, line);
0608     }
0609 
0610     template <typename T>
0611     inline bool qCompare(T *t1, std::nullptr_t, const char *actual, const char *expected,
0612                         const char *file, int line)
0613     {
0614         return compare_ptr_helper(t1, nullptr, actual, expected, file, line);
0615     }
0616     template <typename T>
0617     inline bool qCompare(std::nullptr_t, T *t2, const char *actual, const char *expected,
0618                         const char *file, int line)
0619     {
0620         return compare_ptr_helper(nullptr, t2, actual, expected, file, line);
0621     }
0622 
0623     template <typename T1, typename T2>
0624     inline bool qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected,
0625                         const char *file, int line)
0626     {
0627         return compare_ptr_helper(t1, static_cast<const T1 *>(t2), actual, expected, file, line);
0628     }
0629     template <typename T1, typename T2>
0630     inline bool qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected,
0631                         const char *file, int line)
0632     {
0633         return compare_ptr_helper(const_cast<const T1 *>(t1),
0634                 static_cast<const T1 *>(const_cast<const T2 *>(t2)), actual, expected, file, line);
0635     }
0636     inline bool qCompare(const char *t1, const char *t2, const char *actual,
0637                                        const char *expected, const char *file, int line)
0638     {
0639         return compare_string_helper(t1, t2, actual, expected, file, line);
0640     }
0641     inline bool qCompare(char *t1, char *t2, const char *actual, const char *expected,
0642                         const char *file, int line)
0643     {
0644         return compare_string_helper(t1, t2, actual, expected, file, line);
0645     }
0646 
0647     /* The next two overloads are for MSVC that shows problems with implicit
0648        conversions
0649      */
0650     inline bool qCompare(char *t1, const char *t2, const char *actual,
0651                          const char *expected, const char *file, int line)
0652     {
0653         return compare_string_helper(t1, t2, actual, expected, file, line);
0654     }
0655     inline bool qCompare(const char *t1, char *t2, const char *actual,
0656                          const char *expected, const char *file, int line)
0657     {
0658         return compare_string_helper(t1, t2, actual, expected, file, line);
0659     }
0660 
0661     template <class T>
0662     inline bool qTest(const T& actual, const char *elementName, const char *actualStr,
0663                      const char *expected, const char *file, int line)
0664     {
0665         return qCompare(actual, *static_cast<const T *>(QTest::qElementData(elementName,
0666                        qMetaTypeId<T>())), actualStr, expected, file, line);
0667     }
0668 
0669     Q_TESTLIB_EXPORT bool reportResult(bool success, qxp::function_ref<const char*()> lhs,
0670                                        qxp::function_ref<const char*()> rhs,
0671                                        const char *lhsExpr, const char *rhsExpr,
0672                                        ComparisonOperation op, const char *file, int line);
0673 }
0674 
0675 #undef QTEST_COMPARE_DECL
0676 
0677 #define QWARN(msg) QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
0678 
0679 QT_END_NAMESPACE
0680 
0681 #endif