From 6b9a1824a4c1e4c773c31db8df6c9bf8c768079f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 27 Jul 2019 13:57:37 +0300 Subject: Extend tst_qstringapisymmetry for member compare() There were a few surprises: - QByteArray::compare() are missing noexcept (will add) - ibid., called with non-ascii content and CaseInsensitive fails (this was discussed on the ML, with tentative agreement that it's a feature, not a bug; waiting for QUtf8String(View) for a fix, then). - As was the case when we did this exercise with the relational operators, QString(Ref)/QChar is not noexcept (will fix) These have been QEXPECT_FAIL'ed. Not much of the cartesian product is implemented at all, yet. These have been #ifdef'ed with NOT_YET_IMPLEMENTED to see what's still missing. Change-Id: I7d9b21e292b98f980aacdc6248e88188f7472ba2 Reviewed-by: Thiago Macieira --- .../qstringapisymmetry/tst_qstringapisymmetry.cpp | 160 ++++++++++++++++++++- 1 file changed, 158 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 24382a2b61..bcf4e73108 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz ** Copyright (C) 2019 Mail.ru Group. ** Contact: https://www.qt.io/licensing/ ** @@ -80,6 +80,13 @@ MAKE_ALL(const char*, QChar) #undef MAKE_RELOP // END FIXME +static Q_DECL_CONSTEXPR int sign(int i) noexcept +{ + return i < 0 ? -1 : + i > 0 ? +1 : + /*else*/ 0 ; +} + // Return a plain ASCII row name consisting of maximum 16 chars and the // size for data static QByteArray rowName(const QByteArray &data) @@ -162,6 +169,12 @@ private Q_SLOTS: void compare_QStringView_QStringView() { compare_impl(); } void compare_QStringView_QLatin1String_data() { compare_data(); } void compare_QStringView_QLatin1String() { compare_impl(); } +#ifdef NOT_YET_IMPLMENTED + void compare_QStringView_QByteArray_data() { compare_data(); } + void compare_QStringView_QByteArray() { compare_impl(); } + void compare_QStringView_const_char_star_data() { compare_data(); } + void compare_QStringView_const_char_star() { compare_impl(); } +#endif void compare_QLatin1String_QChar_data() { compare_data(false); } void compare_QLatin1String_QChar() { compare_impl(); } @@ -204,6 +217,111 @@ private Q_SLOTS: //void compare_const_char_star_const_char_star_data() { compare_data(); } //void compare_const_char_star_const_char_star() { compare_impl(); } +private: + void member_compare_data(bool hasConceptOfNullAndEmpty=true) { compare_data(hasConceptOfNullAndEmpty); } + template + void member_compare_impl() const; + +private Q_SLOTS: + // test all combinations of {QChar, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*} +#ifdef NOT_YET_IMPLEMENTED // probably never will be - what's the point of QChar::compare(QStringView)? + void member_compare_QChar_QChar_data() { member_compare_data(false); } + void member_compare_QChar_QChar() { member_compare_impl(); } + void member_compare_QChar_QStringRef_data() { member_compare_data(false); } + void member_compare_QChar_QStringRef() { member_compare_impl(); } + void member_compare_QChar_QString_data() { member_compare_data(false); } + void member_compare_QChar_QString() { member_compare_impl(); } + void member_compare_QChar_QStringView_data() { member_compare_data(false); } + void member_compare_QChar_QStringView() { member_compare_impl(); } + void member_compare_QChar_QLatin1String_data() { member_compare_data(false); } + void member_compare_QChar_QLatin1String() { member_compare_impl(); } + void member_compare_QChar_QByteArray_data() { member_compare_data(false); } + void member_compare_QChar_QByteArray() { member_compare_impl(); } + void member_compare_QChar_const_char_star_data() { member_compare_data(false); } + void member_compare_QChar_const_char_star() { member_compare_impl(); } +#endif + + void member_compare_QStringRef_QChar_data() { member_compare_data(false); } + void member_compare_QStringRef_QChar() { member_compare_impl(); } + void member_compare_QStringRef_QStringRef_data() { member_compare_data(); } + void member_compare_QStringRef_QStringRef() { member_compare_impl(); } + void member_compare_QStringRef_QString_data() { member_compare_data(); } + void member_compare_QStringRef_QString() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_QStringView_data() { member_compare_data(); } + void member_compare_QStringRef_QStringView() { member_compare_impl(); } +#endif + void member_compare_QStringRef_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringRef_QLatin1String() { member_compare_impl(); } + void member_compare_QStringRef_QByteArray_data() { member_compare_data(); } + void member_compare_QStringRef_QByteArray() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_const_char_star_data() { member_compare_data(); } + void member_compare_QStringRef_const_char_star() { member_compare_impl(); } +#endif + + void member_compare_QString_QChar_data() { member_compare_data(false); } + void member_compare_QString_QChar() { member_compare_impl(); } + void member_compare_QString_QStringRef_data() { member_compare_data(); } + void member_compare_QString_QStringRef() { member_compare_impl(); } + void member_compare_QString_QString_data() { member_compare_data(); } + void member_compare_QString_QString() { member_compare_impl(); } + void member_compare_QString_QStringView_data() { member_compare_data(); } + void member_compare_QString_QStringView() { member_compare_impl(); } + void member_compare_QString_QLatin1String_data() { member_compare_data(); } + void member_compare_QString_QLatin1String() { member_compare_impl(); } + void member_compare_QString_QByteArray_data() { member_compare_data(); } + void member_compare_QString_QByteArray() { member_compare_impl(); } + void member_compare_QString_const_char_star_data() { member_compare_data(); } + void member_compare_QString_const_char_star() { member_compare_impl(); } + +#ifdef NOT_YET_IMPLEMENTED // QChar doesn't implicitly convert to QStringView + void member_compare_QStringView_QChar_data() { member_compare_data(false); } + void member_compare_QStringView_QChar() { member_compare_impl(); } +#endif + void member_compare_QStringView_QStringRef_data() { member_compare_data(); } + void member_compare_QStringView_QStringRef() { member_compare_impl(); } + void member_compare_QStringView_QString_data() { member_compare_data(); } + void member_compare_QStringView_QString() { member_compare_impl(); } + void member_compare_QStringView_QStringView_data() { member_compare_data(); } + void member_compare_QStringView_QStringView() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringView_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringView_QLatin1String() { member_compare_impl(); } + void member_compare_QStringView_QByteArray_data() { member_compare_data(); } + void member_compare_QStringView_QByteArray() { member_compare_impl(); } + void member_compare_QStringView_const_char_star_data() { member_compare_data(); } + void member_compare_QStringView_const_char_star() { member_compare_impl(); } + + void member_compare_QLatin1String_QChar_data() { member_compare_data(false); } + void member_compare_QLatin1String_QChar() { member_compare_impl(); } + void member_compare_QLatin1String_QStringRef_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringRef() { member_compare_impl(); } + void member_compare_QLatin1String_QString_data() { member_compare_data(); } + void member_compare_QLatin1String_QString() { member_compare_impl(); } + void member_compare_QLatin1String_QStringView_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringView() { member_compare_impl(); } + void member_compare_QLatin1String_QLatin1String_data() { member_compare_data(); } + void member_compare_QLatin1String_QLatin1String() { member_compare_impl(); } + void member_compare_QLatin1String_QByteArray_data() { member_compare_data(); } + void member_compare_QLatin1String_QByteArray() { member_compare_impl(); } + void member_compare_QLatin1String_const_char_star_data() { member_compare_data(); } + void member_compare_QLatin1String_const_char_star() { member_compare_impl(); } + + void member_compare_QByteArray_QChar_data() { member_compare_data(false); } + void member_compare_QByteArray_QChar() { member_compare_impl(); } + void member_compare_QByteArray_QStringRef_data() { member_compare_data(); } + void member_compare_QByteArray_QStringRef() { member_compare_impl(); } + void member_compare_QByteArray_QString_data() { member_compare_data(); } + void member_compare_QByteArray_QString() { member_compare_impl(); } + void member_compare_QByteArray_QLatin1String_data() { member_compare_data(); } + void member_compare_QByteArray_QLatin1String() { member_compare_impl(); } +#endif + void member_compare_QByteArray_QByteArray_data() { member_compare_data(); } + void member_compare_QByteArray_QByteArray() { member_compare_impl(); } + void member_compare_QByteArray_const_char_star_data() { member_compare_data(); } + void member_compare_QByteArray_const_char_star() { member_compare_impl(); } + private: void startsWith_data(bool rhsIsQChar = false); template void startsWith_impl() const; @@ -601,7 +719,7 @@ void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \ << QStringRef(&pinned[0]) << QLatin1String(lhs) \ << QStringRef(&pinned[1]) << QLatin1String(rhs) \ - << qstrcmp(lhs, rhs) << qstricmp(lhs, rhs); \ + << sign(qstrcmp(lhs, rhs)) << sign(qstricmp(lhs, rhs)); \ } while (false) ROW("", "0"); ROW("0", ""); @@ -691,6 +809,44 @@ void tst_QStringApiSymmetry::compare_impl() const #undef CHECK } +template +void tst_QStringApiSymmetry::member_compare_impl() const +{ + QFETCH(QStringRef, lhsUnicode); + QFETCH(QLatin1String, lhsLatin1); + QFETCH(QStringRef, rhsUnicode); + QFETCH(QLatin1String, rhsLatin1); + QFETCH(const int, caseSensitiveCompareResult); + QFETCH(const int, caseInsensitiveCompareResult); + + const auto lhsU8 = lhsUnicode.toUtf8(); + const auto rhsU8 = rhsUnicode.toUtf8(); + + const auto lhs = make(lhsUnicode, lhsLatin1, lhsU8); + const auto rhs = make(rhsUnicode, rhsLatin1, rhsU8); + +#define QVERIFY_NOEXCEPT(expr) do { \ + if (has_nothrow_compare::value) {} else \ + QEXPECT_FAIL("", "Qt is missing a nothrow utf8-utf16 comparator", Continue); \ + QVERIFY(noexcept(expr)); } while (0) + + if (std::is_same::value || // needs to simply be marked as noexcept + ((std::is_same::value || std::is_same::value) + && std::is_same::value)) // implict QChar -> QString conversion kills noexcept + QEXPECT_FAIL("", "known issues, will be fixed before 5.14 release", Continue); + QVERIFY_NOEXCEPT(lhs.compare(rhs, Qt::CaseSensitive)); + + QCOMPARE(sign(lhs.compare(rhs)), caseSensitiveCompareResult); + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseSensitive)), caseSensitiveCompareResult); + if (is_utf8_encoded::value && is_utf8_encoded::value && + caseSensitiveCompareResult != caseInsensitiveCompareResult && + (!QtPrivate::isAscii(lhsUnicode) || !QtPrivate::isAscii(rhsUnicode))) + { + QEXPECT_FAIL("", "Qt is missing a case-insensitive UTF-8/UTF-8 comparator", Continue); + } + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseInsensitive)), caseInsensitiveCompareResult); +} + static QString empty = QLatin1String(""); static QString null; // the tests below rely on the fact that these objects' names match their contents: -- cgit v1.2.3