diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-01-20 16:03:30 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-16 06:54:18 +0100 |
commit | 579526cfec082679241548a0fca1ff9ba2c350a7 (patch) | |
tree | 46062137fa4749fdc19793d13a4def2e4dab62d7 /src/testlib | |
parent | 19c70982517e76d89bb3da931e1390a6386603da (diff) |
Make the printing of complex Unicode in a QString prettier
This also has the advantage of not requiring the use of the locale
codec. Quite an advantage if you're debugging the locale codec. But it's
mostly so that we don't get question marks that hide the difference we
were trying to locate.
[ChangeLog][QtTest] QtTest now prints an escaped version of QStrings
that failed to compare with QCOMPARE. That is, instead of converting
non-printable characters to question marks, QtTest will print the
Unicode representation of the character in question.
Change-Id: I44c1ef3246b188c913dacd3ca4df02581356ea41
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/testlib')
-rw-r--r-- | src/testlib/qtest.h | 16 | ||||
-rw-r--r-- | src/testlib/qtestcase.cpp | 66 | ||||
-rw-r--r-- | src/testlib/qtestcase.h | 1 |
3 files changed, 72 insertions, 11 deletions
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index ac1d6cc9ef..7c9a7b2b3f 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -66,14 +66,14 @@ QT_BEGIN_NAMESPACE namespace QTest { -template<> inline char *toString(const QLatin1String &str) +template<> inline char *toString(const QString &str) { - return qstrdup(qPrintable(QString(str))); + return QTest::toPrettyUnicode(reinterpret_cast<const ushort *>(str.constData()), str.length()); } -template<> inline char *toString(const QString &str) +template<> inline char *toString(const QLatin1String &str) { - return qstrdup(qPrintable(str)); + return toString(QString(str)); } template<> inline char *toString(const QByteArray &ba) @@ -195,15 +195,15 @@ inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const int expectedSize = t2.count(); if (actualSize != expectedSize) { qsnprintf(msg, sizeof(msg), "Compared lists have different sizes.\n" - " Actual (%s) size: '%d'\n" - " Expected (%s) size: '%d'", actual, actualSize, expected, expectedSize); + " Actual (%s) size: %d\n" + " Expected (%s) size: %d", actual, actualSize, expected, expectedSize); isOk = false; } for (int i = 0; isOk && i < actualSize; ++i) { if (!(t1.at(i) == t2.at(i))) { qsnprintf(msg, sizeof(msg), "Compared lists differ at index %d.\n" - " Actual (%s): '%s'\n" - " Expected (%s): '%s'", i, actual, toString(t1.at(i)), + " Actual (%s): %s\n" + " Expected (%s): %s", i, actual, toString(t1.at(i)), expected, toString(t2.at(i))); isOk = false; } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 0d7a017f89..6c1df8815c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1894,6 +1894,12 @@ void *fetchData(QTestData *data, const char *tagName, int typeId) return data->data(idx); } +static char toHex(ushort value) +{ + static const char hexdigits[] = "0123456789ABCDEF"; + return hexdigits[value & 0xF]; +} + /*! \fn char* QTest::toHexRepresentation(const char *ba, int length) @@ -1937,16 +1943,15 @@ char *toHexRepresentation(const char *ba, int length) result[size - 1] = '\0'; } - const char toHex[] = "0123456789ABCDEF"; int i = 0; int o = 0; while (true) { const char at = ba[i]; - result[o] = toHex[(at >> 4) & 0x0F]; + result[o] = toHex(at >> 4); ++o; - result[o] = toHex[at & 0x0F]; + result[o] = toHex(at); ++i; ++o; @@ -1961,6 +1966,61 @@ char *toHexRepresentation(const char *ba, int length) return result; } +/*! + \internal + Returns the same QString but with only the ASCII characters still shown; + everything else is replaced with \c {\uXXXX}. +*/ +char *toPrettyUnicode(const ushort *p, int length) +{ + // keep it simple for the vast majority of cases + QScopedArrayPointer<char> buffer(new char[length * 6 + 3]); + const ushort *end = p + length; + char *dst = buffer.data(); + + *dst++ = '"'; + for ( ; p != end; ++p) { + if (*p < 0x7f && *p >= 0x20 && *p != '\\') { + *dst++ = *p; + continue; + } + + // write as an escape sequence + *dst++ = '\\'; + switch (*p) { + case 0x22: + case 0x5c: + *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: + *dst++ = 'u'; + *dst++ = toHex(*p >> 12); + *dst++ = toHex(*p >> 8); + *dst++ = toHex(*p >> 4); + *dst++ = toHex(*p); + } + } + + *dst++ = '"'; + *dst++ = '\0'; + return buffer.take(); +} + static void qInvokeTestMethods(QObject *testObject) { const QMetaObject *metaObject = testObject->metaObject(); diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 05da33c400..b715d83383 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -233,6 +233,7 @@ namespace QTest Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, 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 *); |