diff --git a/tests/auto/corelib/tools/qstringapisymmetry/.gitignore b/tests/auto/corelib/tools/qstringapisymmetry/.gitignore new file mode 100644 index 00000000000..d28de05438e --- /dev/null +++ b/tests/auto/corelib/tools/qstringapisymmetry/.gitignore @@ -0,0 +1 @@ +tst_qstringapisymmetry diff --git a/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro b/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro new file mode 100644 index 00000000000..76e89c9acd9 --- /dev/null +++ b/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro @@ -0,0 +1,5 @@ +CONFIG += testcase +TARGET = tst_qstringapisymmetry +QT = core testlib +SOURCES = tst_qstringapisymmetry.cpp +contains(QT_CONFIG,c++14): CONFIG += c++14 diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp new file mode 100644 index 00000000000..5bf7984a657 --- /dev/null +++ b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII +#undef QT_ASCII_CAST_WARNINGS + +#include +#include +#include +#include + +#include + +Q_DECLARE_METATYPE(QLatin1String) +Q_DECLARE_METATYPE(QStringRef) + +template +QString toQString(const T &t) { return QString(t); } +QString toQString(const QStringRef &ref) { return ref.toString(); } + +// FIXME: these are missing at the time of writing, add them, then remove the dummies here: +#define MAKE_RELOP(op, A1, A2) \ + static bool operator op (const A1 &lhs, const A2 &rhs) \ + { return toQString(lhs) op toQString(rhs); } \ + /*end*/ +#define MAKE_LESS_ETC(A1, A2) \ + MAKE_RELOP(<, A1, A2) \ + MAKE_RELOP(>, A1, A2) \ + MAKE_RELOP(<=, A1, A2) \ + MAKE_RELOP(>=, A1, A2) \ + /*end*/ +MAKE_RELOP(==, QChar, QLatin1String) +MAKE_RELOP(!=, QChar, QLatin1String) +MAKE_LESS_ETC(QChar, QLatin1String) + +MAKE_LESS_ETC(QChar, QStringRef) +MAKE_LESS_ETC(QStringRef, QChar) + +MAKE_LESS_ETC(QString, QStringRef) +MAKE_LESS_ETC(QStringRef, QString) + +MAKE_LESS_ETC(QStringRef, QLatin1String) +MAKE_LESS_ETC(QLatin1String, QStringRef) + +#undef MAKE_LESS_ETC +#undef MAKE_RELOP +// END FIXME + +class tst_QStringApiSymmetry : public QObject +{ + Q_OBJECT + + void compare_data(bool hasConceptOfNullAndEmpty=true); + template + void compare_impl() const; + +private Q_SLOTS: + // test all combinations of {QChar, QStringRef, QString, QLatin1String} + void compare_QChar_QChar_data() { compare_data(false); } + void compare_QChar_QChar() { compare_impl(); } + void compare_QChar_QStringRef_data() { compare_data(false); } + void compare_QChar_QStringRef() { compare_impl(); } + void compare_QChar_QString_data() { compare_data(false); } + void compare_QChar_QString() { compare_impl(); } + void compare_QChar_QLatin1String_data() { compare_data(false); } + void compare_QChar_QLatin1String() { compare_impl(); } + + void compare_QStringRef_QChar_data() { compare_data(false); } + void compare_QStringRef_QChar() { compare_impl(); } + void compare_QStringRef_QStringRef_data() { compare_data(); } + void compare_QStringRef_QStringRef() { compare_impl(); } + void compare_QStringRef_QString_data() { compare_data(); } + void compare_QStringRef_QString() { compare_impl(); } + void compare_QStringRef_QLatin1String_data() { compare_data(); } + void compare_QStringRef_QLatin1String() { compare_impl(); } + + void compare_QString_QChar_data() { compare_data(false); } + void compare_QString_QChar() { compare_impl(); } + void compare_QString_QStringRef_data() { compare_data(); } + void compare_QString_QStringRef() { compare_impl(); } + void compare_QString_QString_data() { compare_data(); } + void compare_QString_QString() { compare_impl(); } + void compare_QString_QLatin1String_data() { compare_data(); } + void compare_QString_QLatin1String() { compare_impl(); } + + void compare_QLatin1String_QChar_data() { compare_data(false); } + void compare_QLatin1String_QChar() { compare_impl(); } + void compare_QLatin1String_QStringRef_data() { compare_data(); } + void compare_QLatin1String_QStringRef() { compare_impl(); } + void compare_QLatin1String_QString_data() { compare_data(); } + void compare_QLatin1String_QString() { compare_impl(); } + void compare_QLatin1String_QLatin1String_data() { compare_data(); } + void compare_QLatin1String_QLatin1String() { compare_impl(); } + +}; + +void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) +{ + QTest::addColumn("lhsUnicode"); + QTest::addColumn("lhsLatin1"); + QTest::addColumn("rhsUnicode"); + QTest::addColumn("rhsLatin1"); + QTest::addColumn("caseSensitiveCompareResult"); + QTest::addColumn("caseInsensitiveCompareResult"); + + if (hasConceptOfNullAndEmpty) { + QTest::newRow("null <> null") << QStringRef() << QLatin1String() + << QStringRef() << QLatin1String() + << 0 << 0; + static const QString empty(""); + QTest::newRow("null <> empty") << QStringRef() << QLatin1String() + << QStringRef(&empty) << QLatin1String("") + << 0 << 0; + } + +#define ROW(lhs, rhs) \ + do { \ + static const QString pinned[] = { \ + QString(QLatin1String(lhs)), \ + QString(QLatin1String(rhs)), \ + }; \ + QTest::newRow("'" lhs "' <> '" rhs "'") \ + << QStringRef(&pinned[0]) << QLatin1String(lhs) \ + << QStringRef(&pinned[1]) << QLatin1String(rhs) \ + << qstrcmp(lhs, rhs) << qstricmp(lhs, rhs); \ + } while (false) + ROW("", "0"); + ROW("0", ""); + ROW("0", "1"); + ROW("0", "0"); +#undef ROW +} + +template String make(const QStringRef &sf, QLatin1String l1); +template <> QChar make(const QStringRef &sf, QLatin1String) +{ return sf.isEmpty() ? QChar(QLatin1Char('\0')) : sf.at(0); } +template <> QStringRef make(const QStringRef &sf, QLatin1String) { return sf; } +template <> QString make(const QStringRef &sf, QLatin1String) { return sf.toString(); } +template <> QLatin1String make(const QStringRef &, QLatin1String l1) { return l1; } + +template +void tst_QStringApiSymmetry::compare_impl() const +{ + QFETCH(QStringRef, lhsUnicode); + QFETCH(QLatin1String, lhsLatin1); + QFETCH(QStringRef, rhsUnicode); + QFETCH(QLatin1String, rhsLatin1); + QFETCH(int, caseSensitiveCompareResult); + + const LHS lhs = make(lhsUnicode, lhsLatin1); + const RHS rhs = make(rhsUnicode, rhsLatin1); + +#define CHECK(op) \ + do { if (caseSensitiveCompareResult op 0) { \ + QVERIFY(lhs op rhs); \ + } else { \ + QVERIFY(!(lhs op rhs)); \ + } } while (false) + + CHECK(==); + CHECK(!=); + CHECK(<); + CHECK(>); + CHECK(<=); + CHECK(>=); +#undef CHECK +} + +QTEST_APPLESS_MAIN(tst_QStringApiSymmetry) + +#include "tst_qstringapisymmetry.moc" diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index f9e1c454e71..5fe8c13e259 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -51,6 +51,7 @@ SUBDIRS=\ qstl \ qstring \ qstring_no_cast_from_bytearray \ + qstringapisymmetry \ qstringbuilder \ qstringiterator \ qstringlist \