From f5b609cac864e010085d5965b84832b2d85643e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Jan 2014 16:03:30 -0800 Subject: [PATCH] Make the printing of complex byte arrays prettier Similar to what we've done to QString, only we print each byte that is not ASCII as \OOO (octal representation). [ChangeLog][QtTest] QtTest now prints an escaped version of QByteArrays that failed to compare with QCOMPARE, instead of the hex dump. Change-Id: I6a8c43f138c66c998280998a242b43cd579666a0 Reviewed-by: Richard J. Moore --- src/testlib/qtest.h | 2 +- src/testlib/qtestcase.cpp | 66 +++++++++++++++++++ src/testlib/qtestcase.h | 1 + .../selftests/expected_strcmp.lightxml | 20 +++--- .../testlib/selftests/expected_strcmp.txt | 30 ++++----- .../testlib/selftests/expected_strcmp.xml | 20 +++--- .../selftests/expected_strcmp.xunitxml | 20 +++--- .../auto/testlib/selftests/tst_selftests.cpp | 2 +- 8 files changed, 114 insertions(+), 47 deletions(-) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 38c1807e082..81cc07c410c 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -70,7 +70,7 @@ template<> inline char *toString(const QLatin1String &str) template<> inline char *toString(const QByteArray &ba) { - return QTest::toHexRepresentation(ba.constData(), ba.length()); + return QTest::toPrettyCString(ba.constData(), ba.length()); } #ifndef QT_NO_DATESTRING diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 59f20aae934..16dade91543 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2179,6 +2179,72 @@ char *toHexRepresentation(const char *ba, int length) return result; } +/*! + \internal + Returns the same QByteArray but with only the ASCII characters still shown; + everything else is replaced with \c {\OOO}. +*/ +char *toPrettyCString(const char *p, int length) +{ + bool trimmed = false; + QScopedArrayPointer buffer(new char[256]); + const char *end = p + length; + char *dst = buffer.data(); + + *dst++ = '"'; + for ( ; p != end; ++p) { + if (dst - buffer.data() > 246) { + // plus the the quote, the three dots and NUL, it's 251, 252 or 255 + trimmed = true; + break; + } + + if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') { + *dst++ = *p; + continue; + } + + // write as an escape sequence + // this means we may advance dst to buffer.data() + 247 or 250 + *dst++ = '\\'; + switch (*p) { + case 0x5c: + case 0x22: + *dst++ = uchar(*p); + break; + case 0x8: + *dst++ = 'b'; + break; + case 0xc: + *dst++ = 'f'; + break; + case 0xa: + *dst++ = 'n'; + break; + case 0xd: + *dst++ = 'r'; + break; + case 0x9: + *dst++ = 't'; + break; + default: + // write as octal + *dst++ = '0' + ((uchar(*p) >> 6) & 7); + *dst++ = '0' + ((uchar(*p) >> 3) & 7); + *dst++ = '0' + ((uchar(*p)) & 7); + } + } + + *dst++ = '"'; + if (trimmed) { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst++ = '\0'; + return buffer.take(); +} + /*! \internal Returns the same QString but with only the ASCII characters still shown; diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 532031e0c26..9bfef80bacc 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -225,6 +225,7 @@ namespace QTest 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(const ushort *unicode, int length); Q_TESTLIB_EXPORT char *toString(const char *); Q_TESTLIB_EXPORT char *toString(const void *); diff --git a/tests/auto/testlib/selftests/expected_strcmp.lightxml b/tests/auto/testlib/selftests/expected_strcmp.lightxml index 298e910be81..93a860431e0 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.lightxml +++ b/tests/auto/testlib/selftests/expected_strcmp.lightxml @@ -23,40 +23,40 @@ + Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... + Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...]]> + Actual (QByteArray("abc")): "abc" + Expected (QByteArray("cba")): "cba"]]> + Actual (QByteArray("foo")): "foo" + Expected (QByteArray()) : ""]]> + Actual (QByteArray("")) : "" + Expected (QByteArray("foo")): "foo"]]> + Actual (QByteArray("6")): "6" + Expected (QByteArray("7")): "7"]]> diff --git a/tests/auto/testlib/selftests/expected_strcmp.txt b/tests/auto/testlib/selftests/expected_strcmp.txt index 3d58698781e..270ce098920 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.txt +++ b/tests/auto/testlib/selftests/expected_strcmp.txt @@ -9,25 +9,25 @@ XFAIL : tst_StrCmp::compareByteArray() Next test should fail XFAIL : tst_StrCmp::compareByteArray() Next test should fail Loc: [tst_strcmp.cpp(102)] FAIL! : tst_StrCmp::compareByteArray() Compared values are not the same - Actual (a): 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 ... - Expected (b): 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ... - Loc: [tst_strcmp.cpp(109)] + Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... + Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"... + Loc: [/home/thiago/src/qt/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp(109)] FAIL! : tst_StrCmp::failByteArray() Compared values are not the same - Actual (QByteArray("abc")): 61 62 63 - Expected (QByteArray("cba")): 63 62 61 - Loc: [tst_strcmp.cpp(115)] + Actual (QByteArray("abc")): "abc" + Expected (QByteArray("cba")): "cba" + Loc: [/home/thiago/src/qt/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp(115)] FAIL! : tst_StrCmp::failByteArrayNull() Compared values are not the same - Actual (QByteArray("foo")): 66 6F 6F - Expected (QByteArray()) : - Loc: [tst_strcmp.cpp(121)] + Actual (QByteArray("foo")): "foo" + Expected (QByteArray()) : "" + Loc: [/home/thiago/src/qt/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp(121)] FAIL! : tst_StrCmp::failByteArrayEmpty() Compared values are not the same - Actual (QByteArray("")) : - Expected (QByteArray("foo")): 66 6F 6F - Loc: [tst_strcmp.cpp(126)] + Actual (QByteArray("")) : "" + Expected (QByteArray("foo")): "foo" + Loc: [/home/thiago/src/qt/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp(126)] FAIL! : tst_StrCmp::failByteArraySingleChars() Compared values are not the same - Actual (QByteArray("6")): 36 - Expected (QByteArray("7")): 37 - Loc: [tst_strcmp.cpp(133)] + Actual (QByteArray("6")): "6" + Expected (QByteArray("7")): "7" + Loc: [/home/thiago/src/qt/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp(133)] PASS : tst_StrCmp::cleanupTestCase() Totals: 3 passed, 5 failed, 0 skipped, 0 blacklisted ********* Finished testing of tst_StrCmp ********* diff --git a/tests/auto/testlib/selftests/expected_strcmp.xml b/tests/auto/testlib/selftests/expected_strcmp.xml index 29208f9a87b..9e14dddd7c0 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.xml +++ b/tests/auto/testlib/selftests/expected_strcmp.xml @@ -25,40 +25,40 @@ + Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... + Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...]]> + Actual (QByteArray("abc")): "abc" + Expected (QByteArray("cba")): "cba"]]> + Actual (QByteArray("foo")): "foo" + Expected (QByteArray()) : ""]]> + Actual (QByteArray("")) : "" + Expected (QByteArray("foo")): "foo"]]> + Actual (QByteArray("6")): "6" + Expected (QByteArray("7")): "7"]]> diff --git a/tests/auto/testlib/selftests/expected_strcmp.xunitxml b/tests/auto/testlib/selftests/expected_strcmp.xunitxml index 14bef9ec478..66dce857c98 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.xunitxml +++ b/tests/auto/testlib/selftests/expected_strcmp.xunitxml @@ -12,28 +12,28 @@ + Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... + Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..." result="fail"/> + Actual (QByteArray("abc")): "abc" + Expected (QByteArray("cba")): "cba"" result="fail"/> + Actual (QByteArray("foo")): "foo" + Expected (QByteArray()) : """ result="fail"/> + Actual (QByteArray("")) : "" + Expected (QByteArray("foo")): "foo"" result="fail"/> + Actual (QByteArray("6")): "6" + Expected (QByteArray("7")): "7"" result="fail"/> diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index acd3faaa452..488b65c6576 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -746,7 +746,7 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge .arg(i).arg(loggers.at(n), output))); } else { QVERIFY2(output == expected, - qPrintable(QString::fromLatin1("Mismatch at line %1 (%2, %3): '%4' != '%5'") + qPrintable(QString::fromLatin1("Mismatch at line %1 (%2, %3):\n'%4'\n !=\n'%5'") .arg(i + 1).arg(loggers.at(n), expectedFileName, output, expected))); }