diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-04-24 09:54:02 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-04-26 09:11:27 +0000 |
commit | 979f9f4d3442ef9373e823cd681c5c23f84cc55b (patch) | |
tree | f69f51de19bf75a3f29ec1e0abbcd42c27ff3187 /tests/auto/corelib/tools/qstringapisymmetry | |
parent | 5677b70eee2e923eea8e5150500ac745d8d54974 (diff) |
QLatin1String: fix qt_compare_strings(QLatin1String, QLatin1String) for null strings
qstrcmp sorts null strings before empty ones, while the Qt string
classes consider them equal.
The qt_compare_strings() overload for QLatin1String was using
qstrcmp(), but is supposed to implement the semantics that Qt string
classes use, so we need to add an extra check.
Was uncovered by tests for QLatin1String::startsWith(), but added a
new test for qCompareStrings() now, which is a bit more complicated
than desired, due to the lack of QUtf8String.
Change-Id: I0493c4491df928a68861a1bc7f0962f1c870a416
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools/qstringapisymmetry')
-rw-r--r-- | tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp index f2ca48d739..4c2219cf7a 100644 --- a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -319,6 +319,9 @@ void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) QTest::newRow("null <> empty") << QStringRef() << QLatin1String() << QStringRef(&empty) << QLatin1String("") << 0 << 0; + QTest::newRow("empty <> null") << QStringRef(&empty) << QLatin1String("") + << QStringRef() << QLatin1String() + << 0 << 0; } #define ROW(lhs, rhs) \ @@ -363,6 +366,38 @@ struct has_nothrow_compare { }; template <typename LHS, typename RHS> +struct has_qCompareStrings { + enum { value = !std::is_same<LHS, QChar>::value && !std::is_same<RHS, QChar>::value && + !is_utf8_encoded<LHS>::value && !is_utf8_encoded<RHS>::value }; +}; + +template <typename LHS, typename RHS> +using if_has_qCompareStrings = typename std::enable_if<has_qCompareStrings<LHS, RHS>::value, bool>::type; + +template <typename LHS, typename RHS> +using if_lacks_qCompareStrings = typename std::enable_if<!has_qCompareStrings<LHS, RHS>::value, bool>::type; + +static inline Q_DECL_CONSTEXPR int sign(int x) Q_DECL_NOTHROW +{ + return x < 0 ? -1 : + x > 0 ? +1 : + /*else*/ 0 ; +} + +template <typename LHS, typename RHS, if_has_qCompareStrings<LHS, RHS> = true> +int qCompareStringsWrapper(const LHS &lhs, const RHS &rhs, Qt::CaseSensitivity cs, int) + Q_DECL_NOEXCEPT_EXPR(noexcept(qCompareStrings(lhs, rhs, cs))) +{ + return qCompareStrings(lhs, rhs, cs); +} + +template <typename LHS, typename RHS, if_lacks_qCompareStrings<LHS, RHS> = true> +int qCompareStringsWrapper(const LHS &, const RHS &, Qt::CaseSensitivity, int result) +{ + return result; +} + +template <typename LHS, typename RHS> void tst_QStringApiSymmetry::compare_impl() const { QFETCH(QStringRef, lhsUnicode); @@ -370,6 +405,7 @@ void tst_QStringApiSymmetry::compare_impl() const QFETCH(QStringRef, rhsUnicode); QFETCH(QLatin1String, rhsLatin1); QFETCH(int, caseSensitiveCompareResult); + QFETCH(const int, caseInsensitiveCompareResult); const auto lhsU8 = lhsUnicode.toUtf8(); const auto rhsU8 = rhsUnicode.toUtf8(); @@ -386,6 +422,10 @@ void tst_QStringApiSymmetry::compare_impl() const # define QVERIFY_NOEXCEPT(expr) #endif + QCOMPARE(sign(qCompareStringsWrapper(lhs, rhs, Qt::CaseSensitive, caseSensitiveCompareResult)), + sign(caseSensitiveCompareResult)); + QCOMPARE(sign(qCompareStringsWrapper(lhs, rhs, Qt::CaseInsensitive, caseInsensitiveCompareResult)), + sign(caseInsensitiveCompareResult)); #define CHECK(op) \ QVERIFY_NOEXCEPT(lhs op rhs); \ do { if (caseSensitiveCompareResult op 0) { \ |