QTest: rip out qxp::function_ref from reportResult()
This is causing huge code bloat because everything is a local lambda. Instead, pass direct type-erased function and data pointers to the replacement function. Testing with tst_qcborvalue, this reduces the compilation time and the output binary size significantly: Before After Compiler Time Size Time Size GCC 13.2 136.99 s 202.3 MB 13.88 s 14.3 MB GCC 14.0 131.49 s 202.7 MB 14.69 s 14.4 MB Clang 17 77.2 s 146.7 MB 13.62 s 12.2 MB Clang 18 141.9 s 187.1 MB 13.62 s 12.4 MB This causes a difference in how toString() overloads are found. Previously it would match far more overloads because the toString() calls were expanded by the macro. Now, we depend on Argument-Dependent Lookup and associated namespaces, so toString() overloads should not be in the QTest namespace any more. With this patch applied, the testlib testcase of tst_selftest started failing, because nullptr is now handled differently. However, I consider it as a bugfix, because previously it was falling back to a default implementation, and now it is using the QTest::toString(std::nullptr_t) overload, which is a desired behavior. Update the reference files for tst_selftest with the new expected output. Task-number: QTBUG-124272 Change-Id: Ie28eadac333c4bcd8c08fffd17c5484186accdf6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
4ae6f40b3a
commit
c14f399d2a
@ -4,7 +4,7 @@
|
||||
#ifndef QTEST_NETWORK_H
|
||||
#define QTEST_NETWORK_H
|
||||
|
||||
#include <QtTest/qtest.h>
|
||||
#include <QtTest/qtesttostring.h>
|
||||
|
||||
// enable NETWORK features
|
||||
#ifndef QT_NETWORK_LIB
|
||||
@ -43,6 +43,7 @@ inline char *toString<QHostAddress>(const QHostAddress &addr)
|
||||
|
||||
return toString(addr.toString());
|
||||
}
|
||||
} // namespace QTest
|
||||
|
||||
inline char *toString(QNetworkReply::NetworkError code)
|
||||
{
|
||||
@ -57,7 +58,7 @@ inline char *toString(QNetworkReply::NetworkError code)
|
||||
|
||||
inline char *toString(const QNetworkCookie &cookie)
|
||||
{
|
||||
return toString(cookie.toRawForm());
|
||||
return QTest::toString(cookie.toRawForm());
|
||||
}
|
||||
|
||||
inline char *toString(const QList<QNetworkCookie> &list)
|
||||
@ -69,11 +70,9 @@ inline char *toString(const QList<QNetworkCookie> &list)
|
||||
result.chop(2); // remove trailing ", "
|
||||
}
|
||||
result.append(')');
|
||||
return toString(result);
|
||||
return QTest::toString(result);
|
||||
}
|
||||
|
||||
} // namespace QTest
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -62,15 +62,16 @@ inline QByteArray toString(QSizePolicy sp)
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QTest
|
||||
|
||||
inline char *toString(QSizePolicy::Policy p)
|
||||
{
|
||||
return qstrdup(Internal::toString(p));
|
||||
return qstrdup(QTest::Internal::toString(p));
|
||||
}
|
||||
|
||||
inline char *toString(QSizePolicy::ControlTypes ct)
|
||||
{
|
||||
return qstrdup(Internal::toString(ct).constData());
|
||||
return qstrdup(QTest::Internal::toString(ct).constData());
|
||||
}
|
||||
|
||||
inline char *toString(QSizePolicy::ControlType ct)
|
||||
@ -80,11 +81,9 @@ inline char *toString(QSizePolicy::ControlType ct)
|
||||
|
||||
inline char *toString(QSizePolicy sp)
|
||||
{
|
||||
return qstrdup(Internal::toString(sp).constData());
|
||||
return qstrdup(QTest::Internal::toString(sp).constData());
|
||||
}
|
||||
|
||||
} // namespace QTest
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -1745,14 +1745,33 @@ void TestMethods::invokeTests(QObject *testObject) const
|
||||
QSignalDumper::endDump();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 8)
|
||||
static const char *functionRefFormatter(const void *f)
|
||||
{
|
||||
auto formatter = static_cast<const qxp::function_ref<const char *()> *>(f);
|
||||
return (*formatter)();
|
||||
};
|
||||
|
||||
bool reportResult(bool success, qxp::function_ref<const char *()> lhs,
|
||||
qxp::function_ref<const char *()> rhs,
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
ComparisonOperation op, const char *file, int line)
|
||||
{
|
||||
return QTestResult::reportResult(success, lhs, rhs, lhsExpr, rhsExpr, op, file, line);
|
||||
return QTestResult::reportResult(success, &lhs, &rhs,
|
||||
functionRefFormatter, functionRefFormatter,
|
||||
lhsExpr, rhsExpr, op, file, line);
|
||||
}
|
||||
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||
|
||||
bool reportResult(bool success, const void *lhs, const void *rhs,
|
||||
const char *(*lhsFormatter)(const void*),
|
||||
const char *(*rhsFormatter)(const void*),
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
ComparisonOperation op, const char *file, int line)
|
||||
{
|
||||
return QTestResult::reportResult(success, lhs, rhs, lhsFormatter, rhsFormatter,
|
||||
lhsExpr, rhsExpr, op, file, line);
|
||||
}
|
||||
} // namespace QTest
|
||||
|
||||
static void initEnvironment()
|
||||
@ -2748,7 +2767,12 @@ bool QTest::compare_helper(bool success, const char *failureMsg,
|
||||
const char *actual, const char *expected,
|
||||
const char *file, int line)
|
||||
{
|
||||
return QTestResult::reportResult(success, actualVal, expectedVal, actual, expected,
|
||||
auto functionRefFormatter = [](const void *f) {
|
||||
auto formatter = static_cast<const qxp::function_ref<const char *()> *>(f);
|
||||
return (*formatter)();
|
||||
};
|
||||
return QTestResult::reportResult(success, &actualVal, &expectedVal, functionRefFormatter,
|
||||
functionRefFormatter, actual, expected,
|
||||
QTest::ComparisonOperation::CustomCompare,
|
||||
file, line, failureMsg);
|
||||
}
|
||||
|
@ -95,8 +95,7 @@ do { \
|
||||
return QTest::reportResult(std::forward<decltype(qt_lhs_arg)>(qt_lhs_arg) \
|
||||
op \
|
||||
std::forward<decltype(qt_rhs_arg)>(qt_rhs_arg), \
|
||||
[&qt_lhs_arg] { return QTest::toString(qt_lhs_arg); }, \
|
||||
[&qt_rhs_arg] { return QTest::toString(qt_rhs_arg); }, \
|
||||
qt_lhs_arg, qt_rhs_arg, \
|
||||
#lhs, #rhs, QTest::ComparisonOperation::opId, \
|
||||
__FILE__, __LINE__); \
|
||||
}(lhs, rhs)) { \
|
||||
@ -330,6 +329,18 @@ namespace QTest
|
||||
|
||||
Q_TESTLIB_EXPORT QString formatTryTimeoutDebugMessage(q_no_char8_t::QUtf8StringView expr, int timeout, int actual);
|
||||
|
||||
template <typename T1> const char *genericToString(const void *arg)
|
||||
{
|
||||
using QTest::toString;
|
||||
return toString(*static_cast<const T1 *>(arg));
|
||||
}
|
||||
|
||||
template <> inline const char *genericToString<char *>(const void *arg)
|
||||
{
|
||||
using QTest::toString;
|
||||
return toString(static_cast<const char *>(arg));
|
||||
}
|
||||
|
||||
// Exported so Qt Quick Test can also use it for generating backtraces upon crashes.
|
||||
Q_TESTLIB_EXPORT extern bool noCrashHandler;
|
||||
|
||||
@ -644,10 +655,32 @@ namespace QTest
|
||||
qMetaTypeId<T>())), actualStr, expected, file, line);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 8)
|
||||
QT_DEPRECATED_VERSION_X_6_8("use the overload without qxp::function_ref")
|
||||
Q_TESTLIB_EXPORT bool reportResult(bool success, qxp::function_ref<const char*()> lhs,
|
||||
qxp::function_ref<const char*()> rhs,
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
ComparisonOperation op, const char *file, int line);
|
||||
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||
|
||||
Q_TESTLIB_EXPORT bool reportResult(bool success, const void *lhs, const void *rhs,
|
||||
const char *(*lhsFormatter)(const void*),
|
||||
const char *(*rhsFormatter)(const void*),
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
ComparisonOperation op, const char *file, int line);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool reportResult(bool result, const T1 &lhs, const T2 &rhs,
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
ComparisonOperation op, const char *file, int line)
|
||||
{
|
||||
using D1 = std::decay_t<T1>;
|
||||
using D2 = std::decay_t<T2>;
|
||||
using Internal::genericToString;
|
||||
return reportResult(result, std::addressof(lhs), std::addressof(rhs),
|
||||
genericToString<D1>, genericToString<D2>,
|
||||
lhsExpr, rhsExpr, op, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1608,7 +1608,8 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(QSizePolicy::ControlType ct)
|
||||
\fn char *toString(QSizePolicy::ControlType ct)
|
||||
\relates QTest
|
||||
\overload
|
||||
\since 5.5
|
||||
|
||||
@ -1616,7 +1617,8 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(QSizePolicy::ControlTypes cts)
|
||||
\fn char *toString(QSizePolicy::ControlTypes cts)
|
||||
\relates QTest
|
||||
\overload
|
||||
\since 5.5
|
||||
|
||||
@ -1624,7 +1626,8 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(QSizePolicy::Policy p)
|
||||
\fn char *toString(QSizePolicy::Policy p)
|
||||
\relates QTest
|
||||
\overload
|
||||
\since 5.5
|
||||
|
||||
@ -1632,7 +1635,8 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(QSizePolicy sp)
|
||||
\fn char *toString(QSizePolicy sp)
|
||||
\relates QTest
|
||||
\overload
|
||||
\since 5.5
|
||||
|
||||
|
@ -628,8 +628,9 @@ static const char *failureMessageForOp(QTest::ComparisonOperation op)
|
||||
Q_UNREACHABLE_RETURN("");
|
||||
}
|
||||
|
||||
bool QTestResult::reportResult(bool success, qxp::function_ref<const char *()> lhs,
|
||||
qxp::function_ref<const char *()> rhs,
|
||||
bool QTestResult::reportResult(bool success, const void *lhs, const void *rhs,
|
||||
const char *(*lhsFormatter)(const void*),
|
||||
const char *(*rhsFormatter)(const void*),
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
QTest::ComparisonOperation op, const char *file, int line,
|
||||
const char *failureMessage)
|
||||
@ -653,8 +654,8 @@ bool QTestResult::reportResult(bool success, qxp::function_ref<const char *()> l
|
||||
return checkStatement(success, msg, file, line);
|
||||
}
|
||||
|
||||
const std::unique_ptr<const char[]> lhsPtr{ lhs() };
|
||||
const std::unique_ptr<const char[]> rhsPtr{ rhs() };
|
||||
const std::unique_ptr<const char[]> lhsPtr{ lhsFormatter(lhs) };
|
||||
const std::unique_ptr<const char[]> rhsPtr{ rhsFormatter(rhs) };
|
||||
|
||||
if (!failureMessage)
|
||||
failureMessage = failureMessageForOp(op);
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include <QtTest/qttestglobal.h>
|
||||
#include <QtCore/qstringfwd.h>
|
||||
#include <QtCore/qxpfunctional.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -102,8 +101,9 @@ public:
|
||||
static void setCurrentAppName(const char *appName);
|
||||
static const char *currentAppName();
|
||||
|
||||
static bool reportResult(bool success, qxp::function_ref<const char *()> lhs,
|
||||
qxp::function_ref<const char *()> rhs,
|
||||
static bool reportResult(bool success, const void *lhs, const void *rhs,
|
||||
const char *(*lhsFormatter)(const void*),
|
||||
const char *(*rhsFormatter)(const void*),
|
||||
const char *lhsExpr, const char *rhsExpr,
|
||||
QTest::ComparisonOperation op, const char *file, int line,
|
||||
const char *failureMessage = nullptr);
|
||||
|
@ -9,7 +9,7 @@
|
||||
<testcase name="basics" classname="tst_TestLib" time="@TEST_DURATION@">
|
||||
<failure type="fail" message="Compared QObject pointers are not the same">
|
||||
<![CDATA[ Actual (QTest::testObject()): tst_TestLib/"TestObject"
|
||||
Expected (nullptr) : (nullptr)]]>
|
||||
Expected (nullptr) : "nullptr"]]>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase name="delays" classname="tst_TestLib" time="@TEST_DURATION@"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp" line="0">
|
||||
<Description><![CDATA[Compared QObject pointers are not the same
|
||||
Actual (QTest::testObject()): tst_TestLib/"TestObject"
|
||||
Expected (nullptr) : (nullptr)]]></Description>
|
||||
Expected (nullptr) : "nullptr"]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
|
@ -5,9 +5,9 @@ not ok 2 - basics()
|
||||
---
|
||||
type: QCOMPARE
|
||||
message: Compared QObject pointers are not the same
|
||||
wanted: (nullptr) (nullptr)
|
||||
wanted: "nullptr" (nullptr)
|
||||
found: tst_TestLib/"TestObject" (QTest::testObject())
|
||||
expected: (nullptr) (nullptr)
|
||||
expected: "nullptr" (nullptr)
|
||||
actual: tst_TestLib/"TestObject" (QTest::testObject())
|
||||
at: tst_TestLib::basics() (qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp:0)
|
||||
file: qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp
|
||||
|
@ -2,7 +2,7 @@
|
||||
##teamcity[testStarted name='initTestCase()' flowId='tst_TestLib']
|
||||
##teamcity[testFinished name='initTestCase()' flowId='tst_TestLib']
|
||||
##teamcity[testStarted name='basics()' flowId='tst_TestLib']
|
||||
##teamcity[testFailed name='basics()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp(0)|]' details='Compared QObject pointers are not the same|n Actual (QTest::testObject()): tst_TestLib/"TestObject"|n Expected (nullptr) : (nullptr)' flowId='tst_TestLib']
|
||||
##teamcity[testFailed name='basics()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp(0)|]' details='Compared QObject pointers are not the same|n Actual (QTest::testObject()): tst_TestLib/"TestObject"|n Expected (nullptr) : "nullptr"' flowId='tst_TestLib']
|
||||
##teamcity[testFinished name='basics()' flowId='tst_TestLib']
|
||||
##teamcity[testStarted name='delays()' flowId='tst_TestLib']
|
||||
##teamcity[testFinished name='delays()' flowId='tst_TestLib']
|
||||
|
@ -3,7 +3,7 @@ Config: Using QtTest library
|
||||
PASS : tst_TestLib::initTestCase()
|
||||
FAIL! : tst_TestLib::basics() Compared QObject pointers are not the same
|
||||
Actual (QTest::testObject()): tst_TestLib/"TestObject"
|
||||
Expected (nullptr) : (nullptr)
|
||||
Expected (nullptr) : "nullptr"
|
||||
Loc: [qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp(0)]
|
||||
PASS : tst_TestLib::delays()
|
||||
PASS : tst_TestLib::reals(zero)
|
||||
|
@ -13,7 +13,7 @@
|
||||
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp" line="0">
|
||||
<Description><![CDATA[Compared QObject pointers are not the same
|
||||
Actual (QTest::testObject()): tst_TestLib/"TestObject"
|
||||
Expected (nullptr) : (nullptr)]]></Description>
|
||||
Expected (nullptr) : "nullptr"]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
|
@ -93,11 +93,13 @@ static ClassWithPointerGetter getClassForValue(int val)
|
||||
// various toString() overloads
|
||||
namespace QTest {
|
||||
|
||||
char *toString(const int *val)
|
||||
template <> char *toString(const int *const &val)
|
||||
{
|
||||
return val ? toString(*val) : toString(nullptr);
|
||||
}
|
||||
|
||||
} // namespace QTest
|
||||
|
||||
char *toString(const MyClass &val)
|
||||
{
|
||||
char *msg = new char[128];
|
||||
@ -117,8 +119,6 @@ char *toString(const MyClass *val)
|
||||
return toString(nullptr);
|
||||
}
|
||||
|
||||
} // namespace QTest
|
||||
|
||||
enum MyUnregisteredEnum { MyUnregisteredEnumValue1, MyUnregisteredEnumValue2 };
|
||||
|
||||
class tst_ExtendedCompare : public QObject
|
||||
@ -293,8 +293,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
namespace QTest {
|
||||
|
||||
char *toString(const ClassWithDeferredSetter &val)
|
||||
{
|
||||
char *msg = new char[128];
|
||||
@ -302,8 +300,6 @@ char *toString(const ClassWithDeferredSetter &val)
|
||||
return msg;
|
||||
}
|
||||
|
||||
} // namespace QTest
|
||||
|
||||
void tst_ExtendedCompare::checkComparisonWithTimeout()
|
||||
{
|
||||
QFETCH_GLOBAL(QTest::ComparisonOperation, operation);
|
||||
|
Loading…
x
Reference in New Issue
Block a user