Improve std::tuple handling in tests
Currently when doing comparison with std::tuple the fallback toString method is called which returns a Q_NULLPTR thus not allowing proper diagnostic of the values that triggered an error. This patch adds support for std::tuple to improve the tests output readability. [ChangeLog][QtTest][QCOMPARE] Now outputs contents of std::tuple on failure. Change-Id: I046a55e2ce44c3f7728d51e4745120d38aa5e007 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
9998654eac
commit
04b180f7f2
@ -59,6 +59,8 @@
|
||||
#include <QtCore/qsize.h>
|
||||
#include <QtCore/qrect.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
@ -215,6 +217,25 @@ inline char *toString(const std::pair<T1, T2> &pair)
|
||||
return toString(QString::asprintf("std::pair(%s,%s)", first.data(), second.data()));
|
||||
}
|
||||
|
||||
template <typename Tuple, int... I>
|
||||
inline char *toString(const Tuple & tuple, QtPrivate::IndexesList<I...>) {
|
||||
using UP = std::unique_ptr<char[]>;
|
||||
// Generate a table of N + 1 elements where N is the number of
|
||||
// elements in the tuple.
|
||||
// The last element is needed to support the empty tuple use case.
|
||||
const UP data[] = {
|
||||
UP(toString(std::get<I>(tuple)))..., UP{}
|
||||
};
|
||||
return formatString("std::tuple(", ")", sizeof...(I), data[I].get()...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline char *toString(const std::tuple<Types...> &tuple)
|
||||
{
|
||||
static const std::size_t params_count = sizeof...(Types);
|
||||
return toString(tuple, typename QtPrivate::Indexes<params_count>::Value());
|
||||
}
|
||||
|
||||
inline char *toString(std::nullptr_t)
|
||||
{
|
||||
return toString(QLatin1String("nullptr"));
|
||||
|
@ -1146,6 +1146,31 @@ void *fetchData(QTestData *data, const char *tagName, int typeId)
|
||||
return data->data(idx);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
char *formatString(const char *prefix, const char *suffix, size_t numArguments, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, numArguments);
|
||||
|
||||
QByteArray arguments;
|
||||
arguments += prefix;
|
||||
|
||||
if (numArguments > 0) {
|
||||
arguments += va_arg(ap, const char *);
|
||||
|
||||
for (size_t i = 1; i < numArguments; ++i) {
|
||||
arguments += ", ";
|
||||
arguments += va_arg(ap, const char *);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
arguments += suffix;
|
||||
return qstrdup(arguments.constData());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn char* QTest::toHexRepresentation(const char *ba, int length)
|
||||
|
||||
|
@ -283,6 +283,9 @@ namespace QTest
|
||||
template <typename T1, typename T2>
|
||||
inline char *toString(const std::pair<T1, T2> &pair);
|
||||
|
||||
template <class... Types>
|
||||
inline char *toString(const std::tuple<Types...> &tuple);
|
||||
|
||||
Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, int length);
|
||||
Q_TESTLIB_EXPORT char *toPrettyCString(const char *unicode, int length);
|
||||
Q_TESTLIB_EXPORT char *toPrettyUnicode(QStringView string);
|
||||
@ -388,6 +391,8 @@ namespace QTest
|
||||
Q_TESTLIB_EXPORT bool compare_string_helper(const char *t1, const char *t2, const char *actual,
|
||||
const char *expected, const char *file, int line);
|
||||
|
||||
Q_TESTLIB_EXPORT char *formatString(const char *prefix, const char *suffix, size_t numArguments, ...);
|
||||
|
||||
#ifndef Q_QDOC
|
||||
QTEST_COMPARE_DECL(short)
|
||||
QTEST_COMPARE_DECL(ushort)
|
||||
|
@ -0,0 +1,34 @@
|
||||
<Environment>
|
||||
<QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
|
||||
<QtBuild/>
|
||||
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
|
||||
</Environment>
|
||||
<TestFunction name="initTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testEmptyTuple">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testSimpleTuple">
|
||||
<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
|
||||
<Description><![CDATA[Compared values are not the same
|
||||
Actual (std::tuple<int>{1}): std::tuple(1)
|
||||
Expected (std::tuple<int>{2}): std::tuple(2)]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testTuple">
|
||||
<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
|
||||
<Description><![CDATA[Compared values are not the same
|
||||
Actual (tuple1): std::tuple(42, 'Y', "tuple1")
|
||||
Expected (tuple2): std::tuple(42, 'Y', "tuple2")]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="cleanupTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<Duration msecs="0"/>
|
33
tests/auto/testlib/selftests/expected_tuplediagnostics.tap
Normal file
33
tests/auto/testlib/selftests/expected_tuplediagnostics.tap
Normal file
@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# tst_TupleDiagnostics
|
||||
ok 1 - initTestCase()
|
||||
ok 2 - testEmptyTuple()
|
||||
not ok 3 - testSimpleTuple()
|
||||
---
|
||||
type: QCOMPARE
|
||||
message: Compared values are not the same
|
||||
wanted: std::tuple(2) (std::tuple<int>{2})
|
||||
found: std::tuple(1) (std::tuple<int>{1})
|
||||
expected: std::tuple(2) (std::tuple<int>{2})
|
||||
actual: std::tuple(1) (std::tuple<int>{1})
|
||||
at: tst_TupleDiagnostics::testSimpleTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:53)
|
||||
file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
|
||||
line: 53
|
||||
...
|
||||
not ok 4 - testTuple()
|
||||
---
|
||||
type: QCOMPARE
|
||||
message: Compared values are not the same
|
||||
wanted: std::tuple(42, 'Y', "tuple2") (tuple2)
|
||||
found: std::tuple(42, 'Y', "tuple1") (tuple1)
|
||||
expected: std::tuple(42, 'Y', "tuple2") (tuple2)
|
||||
actual: std::tuple(42, 'Y', "tuple1") (tuple1)
|
||||
at: tst_TupleDiagnostics::testTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:60)
|
||||
file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
|
||||
line: 60
|
||||
...
|
||||
ok 5 - cleanupTestCase()
|
||||
1..5
|
||||
# tests 5
|
||||
# pass 3
|
||||
# fail 2
|
@ -0,0 +1,14 @@
|
||||
##teamcity[testSuiteStarted name='tst_TupleDiagnostics' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testStarted name='initTestCase()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFinished name='initTestCase()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testStarted name='testEmptyTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFinished name='testEmptyTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testStarted name='testSimpleTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFailed name='testSimpleTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (std::tuple<int>{1}): std::tuple(1)|n Expected (std::tuple<int>{2}): std::tuple(2)' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFinished name='testSimpleTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testStarted name='testTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFailed name='testTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (tuple1): std::tuple(42, |'Y|', "tuple1")|n Expected (tuple2): std::tuple(42, |'Y|', "tuple2")' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFinished name='testTuple()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_TupleDiagnostics']
|
||||
##teamcity[testSuiteFinished name='tst_TupleDiagnostics' flowId='tst_TupleDiagnostics']
|
15
tests/auto/testlib/selftests/expected_tuplediagnostics.txt
Normal file
15
tests/auto/testlib/selftests/expected_tuplediagnostics.txt
Normal file
@ -0,0 +1,15 @@
|
||||
********* Start testing of tst_TupleDiagnostics *********
|
||||
Config: Using QtTest library
|
||||
PASS : tst_TupleDiagnostics::initTestCase()
|
||||
PASS : tst_TupleDiagnostics::testEmptyTuple()
|
||||
FAIL! : tst_TupleDiagnostics::testSimpleTuple() Compared values are not the same
|
||||
Actual (std::tuple<int>{1}): std::tuple(1)
|
||||
Expected (std::tuple<int>{2}): std::tuple(2)
|
||||
Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)]
|
||||
FAIL! : tst_TupleDiagnostics::testTuple() Compared values are not the same
|
||||
Actual (tuple1): std::tuple(42, 'Y', "tuple1")
|
||||
Expected (tuple2): std::tuple(42, 'Y', "tuple2")
|
||||
Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)]
|
||||
PASS : tst_TupleDiagnostics::cleanupTestCase()
|
||||
Totals: 3 passed, 2 failed, 0 skipped, 0 blacklisted, 0ms
|
||||
********* Finished testing of tst_TupleDiagnostics *********
|
37
tests/auto/testlib/selftests/expected_tuplediagnostics.xml
Normal file
37
tests/auto/testlib/selftests/expected_tuplediagnostics.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestCase name="tst_TupleDiagnostics">
|
||||
<Environment>
|
||||
<QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
|
||||
<QtBuild/>
|
||||
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
|
||||
</Environment>
|
||||
<TestFunction name="initTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testEmptyTuple">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testSimpleTuple">
|
||||
<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
|
||||
<Description><![CDATA[Compared values are not the same
|
||||
Actual (std::tuple<int>{1}): std::tuple(1)
|
||||
Expected (std::tuple<int>{2}): std::tuple(2)]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="testTuple">
|
||||
<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
|
||||
<Description><![CDATA[Compared values are not the same
|
||||
Actual (tuple1): std::tuple(42, 'Y', "tuple1")
|
||||
Expected (tuple2): std::tuple(42, 'Y', "tuple2")]]></Description>
|
||||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="cleanupTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<Duration msecs="0"/>
|
||||
</TestCase>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite errors="0" failures="2" tests="5" name="tst_TupleDiagnostics">
|
||||
<properties>
|
||||
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
|
||||
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
|
||||
<property value="" name="QtBuild"/>
|
||||
</properties>
|
||||
<testcase result="pass" name="initTestCase"/>
|
||||
<testcase result="pass" name="testEmptyTuple"/>
|
||||
<testcase result="fail" name="testSimpleTuple">
|
||||
<failure message="Compared values are not the same
|
||||
Actual (std::tuple<int>{1}): std::tuple(1)
|
||||
Expected (std::tuple<int>{2}): std::tuple(2)" result="fail"/>
|
||||
</testcase>
|
||||
<testcase result="fail" name="testTuple">
|
||||
<failure message="Compared values are not the same
|
||||
Actual (tuple1): std::tuple(42, 'Y', "tuple1")
|
||||
Expected (tuple2): std::tuple(42, 'Y', "tuple2")" result="fail"/>
|
||||
</testcase>
|
||||
<testcase result="pass" name="cleanupTestCase"/>
|
||||
<system-err/>
|
||||
</testsuite>
|
@ -45,6 +45,7 @@ SUBPROGRAMS = \
|
||||
sleep \
|
||||
strcmp \
|
||||
subtest \
|
||||
tuplediagnostics \
|
||||
verbose1 \
|
||||
verbose2 \
|
||||
verifyexceptionthrown \
|
||||
|
@ -494,6 +494,7 @@ void tst_Selftests::runSubTest_data()
|
||||
<< "sleep"
|
||||
<< "strcmp"
|
||||
<< "subtest"
|
||||
<< "tuplediagnostics"
|
||||
<< "verbose1"
|
||||
<< "verbose2"
|
||||
#ifndef QT_NO_EXCEPTIONS
|
||||
|
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Samuel Gaist <samuel.gaist@edeltech.ch>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// Make sure we get a real Q_ASSERT even in release builds
|
||||
#ifdef QT_NO_DEBUG
|
||||
# undef QT_NO_DEBUG
|
||||
#endif
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class tst_TupleDiagnostics: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void testEmptyTuple() const;
|
||||
void testSimpleTuple() const;
|
||||
void testTuple() const;
|
||||
};
|
||||
|
||||
void tst_TupleDiagnostics::testEmptyTuple() const
|
||||
{
|
||||
QCOMPARE(std::tuple<>{}, std::tuple<>{});
|
||||
}
|
||||
|
||||
void tst_TupleDiagnostics::testSimpleTuple() const
|
||||
{
|
||||
QCOMPARE(std::tuple<int>{1}, std::tuple<int>{2});
|
||||
}
|
||||
|
||||
void tst_TupleDiagnostics::testTuple() const
|
||||
{
|
||||
std::tuple<int, char, QString> tuple1{42, 'Y', QStringLiteral("tuple1")};
|
||||
std::tuple<int, char, QString> tuple2{42, 'Y', QStringLiteral("tuple2")};
|
||||
QCOMPARE(tuple1, tuple2);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_TupleDiagnostics)
|
||||
|
||||
#include "tst_tuplediagnostics.moc"
|
@ -0,0 +1,6 @@
|
||||
SOURCES += tst_tuplediagnostics.cpp
|
||||
QT = core testlib
|
||||
|
||||
CONFIG -= app_bundle debug_and_release_target
|
||||
|
||||
TARGET = tuplediagnostics
|
Loading…
x
Reference in New Issue
Block a user