From d84ee92ecf18f305e02cf58fcc835d27aa2f6579 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sat, 9 Jul 2022 17:01:38 +0200 Subject: [PATCH] Use debug stream in QTest::toString's default fallback if possible For built-in types, this is a compile-time assert - we should not have any types in Qt for which we have neither debug streaming nor a QTest::toString specialization implemented. A build of most of Qt submodules passes with this change, after minor modifications to some tests. We cannot declare QSizeHint::Policy as a metatype after the QMetaType has already been instantiated for it, and the QDebug stream operator for QElaspedTimer needs to be correctly declared within the namespace. Add a self-test function for a custom type, and update reference files of the self-test. Task-number: QTBUG-104867 Change-Id: I2936db5933f4589fce45f47cf2f3224ed614d8c9 Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale (cherry picked from commit 92e696b4bad52c40c6cdc1c5bf7c0c0ea8a2b283) Reviewed-by: Qt Cherry-pick Bot --- src/testlib/qtestcase.h | 13 +- .../qelapsedtimer/tst_qelapsedtimer.cpp | 2 + .../testlib/selftests/cmptest/tst_cmptest.cpp | 31 ++++- .../selftests/expected_cmptest.junitxml | 8 +- .../selftests/expected_cmptest.lightxml | 8 ++ .../testlib/selftests/expected_cmptest.tap | 116 ++++++++++-------- .../selftests/expected_cmptest.teamcity | 3 + .../testlib/selftests/expected_cmptest.txt | 6 +- .../testlib/selftests/expected_cmptest.xml | 8 ++ .../selftests/expected_testlib.junitxml | 2 +- .../selftests/expected_testlib.lightxml | 2 +- .../testlib/selftests/expected_testlib.tap | 4 +- .../selftests/expected_testlib.teamcity | 2 +- .../testlib/selftests/expected_testlib.txt | 2 +- .../testlib/selftests/expected_testlib.xml | 2 +- .../tst_qgraphicsgridlayout.cpp | 1 - .../kernel/qsizepolicy/tst_qsizepolicy.cpp | 3 +- 17 files changed, 146 insertions(+), 67 deletions(-) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 0412f872f78..d8ad48d2c0a 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -307,9 +307,18 @@ namespace QTest return qstrdup(QByteArray::number(static_cast>(e)).constData()); } - template // Fallback - inline typename std::enable_if::Value && !std::is_enum_v, char*>::type toString(const T &) + template // Fallback; for built-in types debug streaming must be possible + inline typename std::enable_if::Value && !std::is_enum_v, char *>::type toString(const T &t) { +#ifndef QT_NO_DEBUG_STREAM + if constexpr (QTypeTraits::has_ostream_operator_v) { + return qstrdup(QDebug::toString(t).toUtf8().constData()); + } else { + static_assert(!QMetaTypeId2::IsBuiltIn, + "Built-in type must implement debug streaming operator " + "or provide QTest::toString specialization"); + } +#endif return nullptr; } diff --git a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp index 652a62f6405..f2f42bef4b8 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp +++ b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp @@ -9,11 +9,13 @@ static const int minResolution = 100; // the minimum resolution for the tests +QT_BEGIN_NAMESPACE QDebug operator<<(QDebug s, const QElapsedTimer &t) { s.nospace() << "(" << t.msecsSinceReference() << ")"; return s.space(); } +QT_END_NAMESPACE class tst_QElapsedTimer : public QObject { diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 5842d7b3b15..94c04157f20 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -115,6 +115,7 @@ private slots: void compare_tostring(); void compare_tostring_data(); void compare_unknown(); + void compare_textFromDebug(); void compareQObjects(); void compareQStringLists(); void compareQStringLists_data(); @@ -324,10 +325,36 @@ void tst_Cmptest::compare_tostring() QCOMPARE(actual, expected); } +struct UnknownType +{ + int value; + bool operator==(const UnknownType &rhs) const { return value == rhs.value; } +}; + void tst_Cmptest::compare_unknown() { - std::string a("a"); - std::string b("b"); + UnknownType a{1}; + UnknownType b{2}; + + QCOMPARE(a, b); +} + +struct CustomType +{ + int value; + bool operator==(const CustomType &rhs) const { return value == rhs.value; } +}; + +QDebug operator<<(QDebug dbg, const CustomType &val) +{ + dbg << "QDebug stream: " << val.value; + return dbg; +} + +void tst_Cmptest::compare_textFromDebug() +{ + CustomType a{0}; + CustomType b{1}; QCOMPARE(a, b); } diff --git a/tests/auto/testlib/selftests/expected_cmptest.junitxml b/tests/auto/testlib/selftests/expected_cmptest.junitxml index 2c92cc66fd6..f71b8f0a192 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.junitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.junitxml @@ -1,5 +1,5 @@ - + @@ -84,6 +84,12 @@ Expected : b]]> + + + + + + + + + + + + + + + + + ]]> + Expected (nullptr) : (nullptr)]]> diff --git a/tests/auto/testlib/selftests/expected_testlib.lightxml b/tests/auto/testlib/selftests/expected_testlib.lightxml index 7d0c1f66c67..cd0f96d6d4e 100644 --- a/tests/auto/testlib/selftests/expected_testlib.lightxml +++ b/tests/auto/testlib/selftests/expected_testlib.lightxml @@ -11,7 +11,7 @@ ]]> + Expected (nullptr) : (nullptr)]]> diff --git a/tests/auto/testlib/selftests/expected_testlib.tap b/tests/auto/testlib/selftests/expected_testlib.tap index ed421f12417..4a6056bc77d 100644 --- a/tests/auto/testlib/selftests/expected_testlib.tap +++ b/tests/auto/testlib/selftests/expected_testlib.tap @@ -5,9 +5,9 @@ not ok 2 - basics() --- type: QCOMPARE message: Compared QObject pointers are not the same - wanted: (nullptr) + wanted: (nullptr) (nullptr) found: tst_TestLib/"TestObject" (QTest::testObject()) - expected: (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 diff --git a/tests/auto/testlib/selftests/expected_testlib.teamcity b/tests/auto/testlib/selftests/expected_testlib.teamcity index 44558008268..279ef03f3f4 100644 --- a/tests/auto/testlib/selftests/expected_testlib.teamcity +++ b/tests/auto/testlib/selftests/expected_testlib.teamcity @@ -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) : ' 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'] diff --git a/tests/auto/testlib/selftests/expected_testlib.txt b/tests/auto/testlib/selftests/expected_testlib.txt index 98ca6ecf115..a0b8a275d09 100644 --- a/tests/auto/testlib/selftests/expected_testlib.txt +++ b/tests/auto/testlib/selftests/expected_testlib.txt @@ -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) : + Expected (nullptr) : (nullptr) Loc: [qtbase/tests/auto/testlib/selftests/testlib/tst_testlib.cpp(0)] PASS : tst_TestLib::delays() PASS : tst_TestLib::reals(zero) diff --git a/tests/auto/testlib/selftests/expected_testlib.xml b/tests/auto/testlib/selftests/expected_testlib.xml index a31259a9e22..241fd3f8d12 100644 --- a/tests/auto/testlib/selftests/expected_testlib.xml +++ b/tests/auto/testlib/selftests/expected_testlib.xml @@ -13,7 +13,7 @@ ]]> + Expected (nullptr) : (nullptr)]]> diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 04d1d0da594..f4b3a5ef99d 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -3156,7 +3156,6 @@ void tst_QGraphicsGridLayout::heightForWidthWithSpanning() QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 100)); } -Q_DECLARE_METATYPE(QSizePolicy::Policy) void tst_QGraphicsGridLayout::spanningItem2x2_data() { QTest::addColumn("sizePolicy"); diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp index f8c6779a83b..5b64f122e20 100644 --- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp +++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp @@ -1,7 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include #include Q_DECLARE_METATYPE(Qt::Orientations) @@ -9,6 +8,8 @@ Q_DECLARE_METATYPE(QSizePolicy) Q_DECLARE_METATYPE(QSizePolicy::Policy) Q_DECLARE_METATYPE(QSizePolicy::ControlType) +#include + class tst_QSizePolicy : public QObject { Q_OBJECT