diff options
Diffstat (limited to 'src/testlib')
| -rw-r--r-- | src/testlib/qtest.h | 2 | ||||
| -rw-r--r-- | src/testlib/qtest_gui.h | 20 | ||||
| -rw-r--r-- | src/testlib/qtestcase.cpp | 62 | ||||
| -rw-r--r-- | src/testlib/qtestcase.h | 39 | ||||
| -rw-r--r-- | src/testlib/qtestresult.cpp | 49 | ||||
| -rw-r--r-- | src/testlib/qtestresult_p.h | 9 |
6 files changed, 153 insertions, 28 deletions
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index cb73a9538a..e185e81eb8 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -421,7 +421,7 @@ bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd, delete [] val2; } } - return compare_helper(isOk, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(isOk, msg, actual, expected, file, line); } namespace Internal { diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index 68c13ee57b..26cf17c6ef 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -122,17 +122,17 @@ inline bool qCompare(QImage const &t1, QImage const &t2, qsnprintf(msg, 1024, "Compared QImages differ.\n" " Actual (%s).isNull(): %d\n" " Expected (%s).isNull(): %d", actual, t1Null, expected, t2Null); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } if (t1Null && t2Null) - return compare_helper(true, nullptr, nullptr, nullptr, actual, expected, file, line); + return compare_helper(true, nullptr, actual, expected, file, line); if (!qFuzzyCompare(t1.devicePixelRatio(), t2.devicePixelRatio())) { qsnprintf(msg, 1024, "Compared QImages differ in device pixel ratio.\n" " Actual (%s): %g\n" " Expected (%s): %g", actual, t1.devicePixelRatio(), expected, t2.devicePixelRatio()); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QImages differ in size.\n" @@ -140,17 +140,17 @@ inline bool qCompare(QImage const &t1, QImage const &t2, " Expected (%s): %dx%d", actual, t1.width(), t1.height(), expected, t2.width(), t2.height()); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } if (t1.format() != t2.format()) { qsnprintf(msg, 1024, "Compared QImages differ in format.\n" " Actual (%s): %d\n" " Expected (%s): %d", actual, t1.format(), expected, t2.format()); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } return compare_helper(t1 == t2, "Compared values are not the same", - nullptr, nullptr, actual, expected, file, line); + actual, expected, file, line); } inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, @@ -164,17 +164,17 @@ inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, c qsnprintf(msg, 1024, "Compared QPixmaps differ.\n" " Actual (%s).isNull(): %d\n" " Expected (%s).isNull(): %d", actual, t1Null, expected, t2Null); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } if (t1Null && t2Null) - return compare_helper(true, nullptr, nullptr, nullptr, actual, expected, file, line); + return compare_helper(true, nullptr, actual, expected, file, line); if (!qFuzzyCompare(t1.devicePixelRatio(), t2.devicePixelRatio())) { qsnprintf(msg, 1024, "Compared QPixmaps differ in device pixel ratio.\n" " Actual (%s): %g\n" " Expected (%s): %g", actual, t1.devicePixelRatio(), expected, t2.devicePixelRatio()); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QPixmaps differ in size.\n" @@ -182,7 +182,7 @@ inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, c " Expected (%s): %dx%d", actual, t1.width(), t1.height(), expected, t2.width(), t2.height()); - return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + return compare_helper(false, msg, actual, expected, file, line); } return qCompare(t1.toImage(), t2.toImage(), actual, expected, file, line); } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 919447cce3..7eeacccf39 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2904,7 +2904,9 @@ void QTest::setMainSourcePath(const char *file, const char *builddir) QTest::mainSourcePath = fi.absolutePath(); } +#if QT_DEPRECATED_SINCE(6, 4) /*! \internal + \deprecated [6.4] This function is called by various specializations of QTest::qCompare to decide whether to report a failure and to produce verbose test output. @@ -2912,15 +2914,61 @@ void QTest::setMainSourcePath(const char *file, const char *builddir) will be output if the compare fails. If the compare succeeds, failureMsg will not be output. - If the caller has already passed a failure message showing the compared - values, or if those values cannot be stringified, val1 and val2 can be null. + Using this function is not optimal, because it requires the string + representations of \a actualVal and \a expectedVal to be pre-calculated, + even though they will be used only if the comparison fails. Prefer using the + \l compare_helper() overload that takes qxp::function_ref() for such cases. + + If the caller creates a custom failure message showing the compared values, + or if those values cannot be stringified, use the overload of the function + that takes no \a actualVal and \a expecetedVal parameters. */ bool QTest::compare_helper(bool success, const char *failureMsg, - char *val1, char *val2, + char *actualVal, char *expectedVal, const char *actual, const char *expected, const char *file, int line) { - return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line); + return QTestResult::compare(success, failureMsg, actualVal, expectedVal, + actual, expected, file, line); +} +#endif // QT_DEPRECATED_SINCE(6, 4) + +/*! \internal + This function is called by various specializations of QTest::qCompare + to decide whether to report a failure and to produce verbose test output. + + The \a failureMsg parameter can be \c {nullptr}, in which case a default + message will be output if the compare fails. If the comparison succeeds, + \a failureMsg will not be output. + + This overload of the function uses qxp::function_ref to defer conversion of + \a actualVal and \a expectedVal to strings until that is really needed + (when the comparison fails). This speeds up test case execution on success. +*/ +bool QTest::compare_helper(bool success, const char *failureMsg, + qxp::function_ref<const char *()> actualVal, + qxp::function_ref<const char *()> expectedVal, + const char *actual, const char *expected, + const char *file, int line) +{ + return QTestResult::reportResult(success, actualVal, expectedVal, actual, expected, + QTest::ComparisonOperation::CustomCompare, + file, line, failureMsg); +} + +/*! \internal + This function is called by various specializations of QTest::qCompare + to decide whether to report a failure and to produce verbose test output. + + This overload should be used when there is no string representation of + actual and expected values, so only the \a failureMsg is shown when the + comparison fails. Because of that, \a failureMsg can't be \c {nullptr}. + If the comparison succeeds, \a failureMsg will not be output. +*/ +bool QTest::compare_helper(bool success, const char *failureMsg, const char *actual, + const char *expected, const char *file, int line) +{ + return QTestResult::compare(success, failureMsg, actual, expected, file, line); } template <typename T> @@ -2950,7 +2998,8 @@ bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual, { return compare_helper(floatingCompare(t1, t2), "Compared qfloat16s are not the same (fuzzy compare)", - toString(t1), toString(t2), actual, expected, file, line); + [&t1] { return toString(t1); }, [&t2] { return toString(t2); }, + actual, expected, file, line); } /*! \fn bool QTest::qCompare(const float &t1, const float &t2, const char *actual, const char *expected, const char *file, int line) @@ -3272,7 +3321,8 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac const char *expected, const char *file, int line) { return compare_helper(qstrcmp(t1, t2) == 0, "Compared strings are not the same", - toString(t1), toString(t2), actual, expected, file, line); + [t1] { return toString(t1); }, [t2] { return toString(t2); }, + actual, expected, file, line); } /*! diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index d4caf20e69..ab64d712f9 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -405,10 +405,26 @@ namespace QTest Q_TESTLIB_EXPORT Qt::Key asciiToKey(char ascii); Q_TESTLIB_EXPORT char keyToAscii(Qt::Key key); + // ### TODO: remove QTestResult::compare() overload that takes char * values + // when this overload is removed. +#if QT_DEPRECATED_SINCE(6, 4) + QT_DEPRECATED_VERSION_X_6_4("use an overload that takes function_ref as parameters, " + "or an overload that takes only failure message, if you " + "do not need to stringify the values") Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg, - char *val1, char *val2, + char *actualVal, char *expectedVal, const char *actual, const char *expected, const char *file, int line); +#endif // QT_DEPRECATED_SINCE(6, 4) + Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg, + qxp::function_ref<const char*()> actualVal, + qxp::function_ref<const char*()> expectedVal, + const char *actual, const char *expected, + const char *file, int line); + Q_TESTLIB_EXPORT bool compare_helper(bool success, const char *failureMsg, + const char *actual, const char *expected, + const char *file, int line); + Q_TESTLIB_EXPORT void addColumnInternal(int id, const char *name); template <typename T> @@ -484,42 +500,48 @@ namespace QTest const char *expected, const char *file, int line) { return compare_helper(t1 == t2, "Compared pointers are not the same", - toString(t1), toString(t2), actual, expected, file, line); + [t1] { return toString(t1); }, [t2] { return toString(t2); }, + actual, expected, file, line); } inline bool compare_ptr_helper(const volatile QObject *t1, const volatile QObject *t2, const char *actual, const char *expected, const char *file, int line) { return compare_helper(t1 == t2, "Compared QObject pointers are not the same", - toString(t1), toString(t2), actual, expected, file, line); + [t1] { return toString(t1); }, [t2] { return toString(t2); }, + actual, expected, file, line); } inline bool compare_ptr_helper(const volatile QObject *t1, std::nullptr_t, const char *actual, const char *expected, const char *file, int line) { return compare_helper(t1 == nullptr, "Compared QObject pointers are not the same", - toString(t1), toString(nullptr), actual, expected, file, line); + [t1] { return toString(t1); }, [] { return toString(nullptr); }, + actual, expected, file, line); } inline bool compare_ptr_helper(std::nullptr_t, const volatile QObject *t2, const char *actual, const char *expected, const char *file, int line) { return compare_helper(nullptr == t2, "Compared QObject pointers are not the same", - toString(nullptr), toString(t2), actual, expected, file, line); + [] { return toString(nullptr); }, [t2] { return toString(t2); }, + actual, expected, file, line); } inline bool compare_ptr_helper(const volatile void *t1, std::nullptr_t, const char *actual, const char *expected, const char *file, int line) { return compare_helper(t1 == nullptr, "Compared pointers are not the same", - toString(t1), toString(nullptr), actual, expected, file, line); + [t1] { return toString(t1); }, [] { return toString(nullptr); }, + actual, expected, file, line); } inline bool compare_ptr_helper(std::nullptr_t, const volatile void *t2, const char *actual, const char *expected, const char *file, int line) { return compare_helper(nullptr == t2, "Compared pointers are not the same", - toString(nullptr), toString(t2), actual, expected, file, line); + [] { return toString(nullptr); }, [t2] { return toString(t2); }, + actual, expected, file, line); } Q_TESTLIB_EXPORT bool compare_string_helper(const char *t1, const char *t2, const char *actual, @@ -551,7 +573,8 @@ namespace QTest const char *file, int line) { return compare_helper(t1 == t2, "Compared values are not the same", - toString(t1), toString(t2), actual, expected, file, line); + [&t1] { return toString(t1); }, [&t2] { return toString(t2); }, + actual, expected, file, line); } inline bool qCompare(double const &t1, float const &t2, const char *actual, diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 22d8f11424..5c947301cc 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -402,6 +402,38 @@ static bool compareHelper(bool success, const char *failureMsg, return checkStatement(success, msg, file, line); } +// A simplified version of compareHelper that does not use string +// representations of the values, and prints only failureMsg when the +// comparison fails. +static bool compareHelper(bool success, const char *failureMsg, + const char *actual, const char *expected, + const char *file, int line) +{ + const size_t maxMsgLen = 1024; + char msg[maxMsgLen]; + msg[0] = '\0'; + + QTEST_ASSERT(expected); + QTEST_ASSERT(actual); + // failureMsg can be null, if we do not use it + QTEST_ASSERT(success || failureMsg); + + if (QTestLog::verboseLevel() >= 2) { + qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s)", actual, expected); + QTestLog::info(msg, file, line); + } + + if (success) { + if (QTest::expectFailMode) { + qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s) returned TRUE unexpectedly.", + actual, expected); + } + return checkStatement(success, msg, file, line); + } + + return checkStatement(success, failureMsg, file, line); +} + bool QTestResult::compare(bool success, const char *failureMsg, char *val1, char *val2, const char *actual, const char *expected, @@ -486,6 +518,15 @@ bool QTestResult::compare(bool success, const char *failureMsg, return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); } +// Simplified version of compare() that does not take the values, because they +// can't be converted to strings (or the user didn't want to do that). +bool QTestResult::compare(bool success, const char *failureMsg, + const char *actual, const char *expeceted, + const char *file, int line) +{ + return compareHelper(success, failureMsg, actual, expeceted, file, line); +} + void QTestResult::addFailure(const char *message, const char *file, int line) { clearExpectFail(); @@ -584,7 +625,8 @@ static const char *failureMessageForOp(QTest::ComparisonOperation op) bool QTestResult::reportResult(bool success, qxp::function_ref<const char *()> lhs, qxp::function_ref<const char *()> rhs, const char *lhsExpr, const char *rhsExpr, - QTest::ComparisonOperation op, const char *file, int line) + QTest::ComparisonOperation op, const char *file, int line, + const char *failureMessage) { const size_t maxMsgLen = 1024; char msg[maxMsgLen] = {'\0'}; @@ -608,7 +650,10 @@ bool QTestResult::reportResult(bool success, qxp::function_ref<const char *()> l const std::unique_ptr<const char[]> lhsPtr{ lhs() }; const std::unique_ptr<const char[]> rhsPtr{ rhs() }; - formatFailMessage(msg, maxMsgLen, failureMessageForOp(op), lhsPtr.get(), rhsPtr.get(), + if (!failureMessage) + failureMessage = failureMessageForOp(op); + + formatFailMessage(msg, maxMsgLen, failureMessage, lhsPtr.get(), rhsPtr.get(), lhsExpr, rhsExpr, op); return checkStatement(success, msg, file, line); diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index fa4e117fb3..48c2c34611 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -42,6 +42,9 @@ public: static void setBlacklistCurrentTest(bool b); static void addFailure(const char *message, const char *file = nullptr, int line = 0); + // ### TODO: Remove this overload when deprecated QTest::compare_overload + // is removed. Can't declare it deprecated, because it will unconditionally + // provide warnings. static bool compare(bool success, const char *failureMsg, char *val1, char *val2, const char *actual, const char *expected, @@ -80,6 +83,9 @@ public: QStringView val1, const QLatin1StringView &val2, const char *actual, const char *expected, const char *file, int line); + static bool compare(bool success, const char *failureMsg, + const char *actual, const char *expeceted, + const char *file, int line); static void setCurrentGlobalTestData(QTestData *data); static void setCurrentTestData(QTestData *data); static void setCurrentTestFunction(const char *func); @@ -99,7 +105,8 @@ public: static bool reportResult(bool success, qxp::function_ref<const char *()> lhs, qxp::function_ref<const char *()> rhs, const char *lhsExpr, const char *rhsExpr, - QTest::ComparisonOperation op, const char *file, int line); + QTest::ComparisonOperation op, const char *file, int line, + const char *failureMessage = nullptr); private: Q_DISABLE_COPY(QTestResult) |
