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 <rich@kde.org>
This commit is contained in:
Thiago Macieira 2014-01-20 16:03:30 -08:00
parent 8d9d2a7b85
commit f5b609cac8
8 changed files with 114 additions and 47 deletions

View File

@ -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

View File

@ -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<char> 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;

View File

@ -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 *);

View File

@ -23,40 +23,40 @@
</Incident>
<Incident type="fail" file="tst_strcmp.cpp" line="109">
<Description><![CDATA[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 ...]]></Description>
Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"...
Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArray">
<Incident type="fail" file="tst_strcmp.cpp" line="115">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("abc")): 61 62 63
Expected (QByteArray("cba")): 63 62 61]]></Description>
Actual (QByteArray("abc")): "abc"
Expected (QByteArray("cba")): "cba"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayNull">
<Incident type="fail" file="tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
Expected (QByteArray()) : ]]></Description>
Actual (QByteArray("foo")): "foo"
Expected (QByteArray()) : ""]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
<Incident type="fail" file="tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
Actual (QByteArray("")) : ""
Expected (QByteArray("foo")): "foo"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArraySingleChars">
<Incident type="fail" file="tst_strcmp.cpp" line="133">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("6")): 36
Expected (QByteArray("7")): 37]]></Description>
Actual (QByteArray("6")): "6"
Expected (QByteArray("7")): "7"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>

View File

@ -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 *********

View File

@ -25,40 +25,40 @@
</Incident>
<Incident type="fail" file="tst_strcmp.cpp" line="109">
<Description><![CDATA[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 ...]]></Description>
Actual (a): "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"...
Expected (b): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArray">
<Incident type="fail" file="tst_strcmp.cpp" line="115">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("abc")): 61 62 63
Expected (QByteArray("cba")): 63 62 61]]></Description>
Actual (QByteArray("abc")): "abc"
Expected (QByteArray("cba")): "cba"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayNull">
<Incident type="fail" file="tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
Expected (QByteArray()) : ]]></Description>
Actual (QByteArray("foo")): "foo"
Expected (QByteArray()) : ""]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
<Incident type="fail" file="tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
Actual (QByteArray("")) : ""
Expected (QByteArray("foo")): "foo"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArraySingleChars">
<Incident type="fail" file="tst_strcmp.cpp" line="133">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("6")): 36
Expected (QByteArray("7")): 37]]></Description>
Actual (QByteArray("6")): "6"
Expected (QByteArray("7")): "7"]]></Description>
</Incident>
<Duration msecs="0"/>
</TestFunction>

View File

@ -12,28 +12,28 @@
<!-- message="Next test should fail" type="info" -->
<!-- message="Next test should fail" type="info" -->
<failure message="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 ..." result="fail"/>
Actual (a): &quot;BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB&quot;...
Expected (b): &quot;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&quot;..." result="fail"/>
</testcase>
<testcase result="fail" name="failByteArray">
<failure message="Compared values are not the same
Actual (QByteArray(&quot;abc&quot;)): 61 62 63
Expected (QByteArray(&quot;cba&quot;)): 63 62 61" result="fail"/>
Actual (QByteArray(&quot;abc&quot;)): &quot;abc&quot;
Expected (QByteArray(&quot;cba&quot;)): &quot;cba&quot;" result="fail"/>
</testcase>
<testcase result="fail" name="failByteArrayNull">
<failure message="Compared values are not the same
Actual (QByteArray(&quot;foo&quot;)): 66 6F 6F
Expected (QByteArray()) : " result="fail"/>
Actual (QByteArray(&quot;foo&quot;)): &quot;foo&quot;
Expected (QByteArray()) : &quot;&quot;" result="fail"/>
</testcase>
<testcase result="fail" name="failByteArrayEmpty">
<failure message="Compared values are not the same
Actual (QByteArray(&quot;&quot;)) :
Expected (QByteArray(&quot;foo&quot;)): 66 6F 6F" result="fail"/>
Actual (QByteArray(&quot;&quot;)) : &quot;&quot;
Expected (QByteArray(&quot;foo&quot;)): &quot;foo&quot;" result="fail"/>
</testcase>
<testcase result="fail" name="failByteArraySingleChars">
<failure message="Compared values are not the same
Actual (QByteArray(&quot;6&quot;)): 36
Expected (QByteArray(&quot;7&quot;)): 37" result="fail"/>
Actual (QByteArray(&quot;6&quot;)): &quot;6&quot;
Expected (QByteArray(&quot;7&quot;)): &quot;7&quot;" result="fail"/>
</testcase>
<testcase result="pass" name="cleanupTestCase"/>
<system-err>

View File

@ -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)));
}