From e5ebb9022ab9e00ab01d0bce527755da77083217 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Tue, 12 Mar 2024 20:33:15 +0100 Subject: [PATCH] QCborMap: use new comparison helper macros Replace public operators operator==(), operator!=(), operator<() of QCborMap to friend methods comparesEqual() / compareThreeWay(). Use QT_CORE_REMOVED_SINCE to get rid of current comparison methods and replace them with a friend. Delete #if 0 && __has_include() blocks, since they are not required anymore. Add friend methods comparesEqual(QCborMap, QCborValue) and compareThreeWay(QCborMap, QCborValue) to the QCborMap class, to support comparison between QCborMap and QCborValue elements, see test-case mapSelfAssign() -> QT_TEST_EQUALITY_OPS(it.key(), QCborMap({{0, v}}), true); Task-number: QTBUG-120300 Change-Id: I9e33df255d16484efd3124cf0632db859408fb5d Reviewed-by: Thiago Macieira Reviewed-by: Ivan Solovev --- src/corelib/compat/removed_api.cpp | 2 + src/corelib/serialization/qcbormap.cpp | 81 ++++- src/corelib/serialization/qcbormap.h | 38 ++- .../qcborvalue/tst_qcborvalue.cpp | 319 ++++++++++-------- 4 files changed, 271 insertions(+), 169 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 372b647bf0d..f10eba5f7a3 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -934,6 +934,8 @@ QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode mode) #include "qcborarray.h" // inlined API +#include "qcbormap.h" // inlined API + #include "qcborvalue.h" // inlined API #include "qdatastream.h" // inlined API diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp index 57186a3d1f1..9367a2ab9b2 100644 --- a/src/corelib/serialization/qcbormap.cpp +++ b/src/corelib/serialization/qcbormap.cpp @@ -18,6 +18,10 @@ using namespace QtCbor; \brief The QCborMap class is used to hold an associative container representable in CBOR. + \compares strong + \compareswith strong QCborValue + \endcompareswith + This class can be used to hold an associative container in CBOR, a map between a key and a value type. CBOR is the Concise Binary Object Representation, a very compact form of binary data encoding that is a @@ -1105,10 +1109,10 @@ QCborValue QCborMap::extract(iterator it) */ /*! - \fn bool QCborMap::operator==(const QCborMap &other) const + \fn bool QCborMap::operator==(const QCborMap &lhs, const QCborMap &rhs) - Compares this map and \a other, comparing each element in sequence, and - returns true if the two maps contains the same elements in the same order, + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if the two maps contain the same elements in the same order, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the @@ -1124,10 +1128,10 @@ QCborValue QCborMap::extract(iterator it) */ /*! - \fn bool QCborMap::operator!=(const QCborMap &other) const + \fn bool QCborMap::operator!=(const QCborMap &lhs, const QCborMap &rhs) - Compares this map and \a other, comparing each element in sequence, and - returns true if the two maps contains any different elements or elements in + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if the two maps contain any different elements or elements in different orders, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the @@ -1143,10 +1147,10 @@ QCborValue QCborMap::extract(iterator it) */ /*! - \fn bool QCborMap::operator<(const QCborMap &other) const + \fn bool QCborMap::operator<(const QCborMap &lhs, const QCborMap &rhs) - Compares this map and \a other, comparing each element in sequence, and - returns true if this map should be sorted before \a other, false + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if \a lhs map should be sorted before \a rhs, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the @@ -1161,6 +1165,65 @@ QCborValue QCborMap::extract(iterator it) operator==(), operator!=() */ +/*! + \fn bool QCborMap::operator<=(const QCborMap &lhs, const QCborMap &rhs) + + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if \a lhs map should be sorted before \a rhs or + if the two maps contain the same elements in the same order, false + otherwise. + + Note that CBOR maps are unordered, which means that two maps containing the + very same pairs but in different order will still compare differently. To + avoid this, it is recommended to insert elements into the map in a + predictable order, such as by ascending key value. In fact, maps with keys + in sorted order are required for Canonical CBOR representation. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator==(), QCborMap::operator==(), + operator==(), operator!=() +*/ + +/*! + \fn bool QCborMap::operator>=(const QCborMap &lhs, const QCborMap &rhs) + + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if \a lhs map should be sorted after \a rhs or + if the two maps contain the same elements in the same order, false + otherwise. + + Note that CBOR maps are unordered, which means that two maps containing the + very same pairs but in different order will still compare differently. To + avoid this, it is recommended to insert elements into the map in a + predictable order, such as by ascending key value. In fact, maps with keys + in sorted order are required for Canonical CBOR representation. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator==(), QCborMap::operator==(), + operator==(), operator!=() +*/ + +/*! + \fn bool QCborMap::operator>(const QCborMap &lhs, const QCborMap &rhs) + + Compares \a lhs and \a rhs maps, comparing each element in sequence, and + returns true if \a lhs map should be sorted after \a rhs, false + otherwise. + + Note that CBOR maps are unordered, which means that two maps containing the + very same pairs but in different order will still compare differently. To + avoid this, it is recommended to insert elements into the map in a + predictable order, such as by ascending key value. In fact, maps with keys + in sorted order are required for Canonical CBOR representation. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator==(), QCborMap::operator==(), + operator==(), operator!=() +*/ + void QCborMap::detach(qsizetype reserved) { d = QCborContainerPrivate::detach(d.data(), reserved ? reserved : size() * 2); diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index f5a118d673b..55935e113ec 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -221,19 +221,11 @@ public: { const_iterator it = find(key); return it != end(); } int compare(const QCborMap &other) const noexcept Q_DECL_PURE_FUNCTION; -#if 0 && __has_include() - std::strong_ordering operator<=>(const QCborMap &other) const - { - int c = compare(other); - if (c > 0) return std::strong_ordering::greater; - if (c == 0) return std::strong_ordering::equivalent; - return std::strong_ordering::less; - } -#else +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const QCborMap &other) const noexcept { return compare(other) == 0; } bool operator!=(const QCborMap &other) const noexcept - { return !(*this == other); } + { return !operator==(other); } bool operator<(const QCborMap &other) const { return compare(other) < 0; } #endif @@ -308,6 +300,32 @@ private: friend class QJsonPrivate::Variant; void detach(qsizetype reserve = 0); + friend bool comparesEqual(const QCborMap &lhs, const QCborMap &rhs) noexcept + { + return lhs.compare(rhs) == 0; + } + friend Qt::strong_ordering compareThreeWay(const QCborMap &lhs, + const QCborMap &rhs) noexcept + { + int c = lhs.compare(rhs); + return Qt::compareThreeWay(c, 0); + } + Q_DECLARE_STRONGLY_ORDERED(QCborMap) + + friend bool comparesEqual(const QCborMap &lhs, + const QCborValue &rhs) noexcept + { + return lhs.compare(rhs.toMap()) == 0; + } + + friend Qt::strong_ordering compareThreeWay(const QCborMap &lhs, + const QCborValue &rhs) noexcept + { + int c = lhs.compare(rhs.toMap()); + return Qt::compareThreeWay(c, 0); + } + Q_DECLARE_STRONGLY_ORDERED(QCborMap, QCborValue) + explicit QCborMap(QCborContainerPrivate &dd) noexcept; QExplicitlySharedDataPointer d; }; diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 4a8c32e148d..e3544a4056e 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -81,6 +81,8 @@ private slots: void sorting(); void comparison_data(); void comparison(); + void comparisonMap_data(); + void comparisonMap(); void toCbor_data(); void toCbor(); @@ -454,11 +456,13 @@ void tst_QCborValue::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); } void tst_QCborValue::extendedTypes() @@ -594,9 +598,8 @@ void tst_QCborValue::mapDefaultInitialization() QVERIFY(m.value("Hello").isUndefined()); #endif - QVERIFY(m == m); - QVERIFY(m == QCborMap{}); - QVERIFY(QCborMap{} == m); + QT_TEST_EQUALITY_OPS(m, m, true); + QT_TEST_EQUALITY_OPS(m, QCborMap{}, true); const QCborValue v(m); QVERIFY(v.isMap()); @@ -609,7 +612,7 @@ void tst_QCborValue::mapDefaultInitialization() QCborMap m2 = v.toMap(); QVERIFY(m2.isEmpty()); QCOMPARE(m2.size(), 0); - QCOMPARE(m2, m); + QT_TEST_EQUALITY_OPS(m2, m, true); } void tst_QCborValue::arrayEmptyInitializerList() @@ -626,9 +629,8 @@ void tst_QCborValue::mapEmptyInitializerList() QCborMap m{}; QVERIFY(m.isEmpty()); QCOMPARE(m.size(), 0); - QVERIFY(m == m); - QVERIFY(m == QCborMap{}); - QVERIFY(QCborMap{} == m); + QT_TEST_EQUALITY_OPS(m, m, true); + QT_TEST_EQUALITY_OPS(QCborMap{}, m, true); } void tst_QCborValue::arrayEmptyDetach() @@ -658,9 +660,8 @@ void tst_QCborValue::mapEmptyDetach() QVERIFY(m.isEmpty()); QCOMPARE(m.size(), 0); - QVERIFY(m == m); - QVERIFY(m == QCborMap{}); - QVERIFY(QCborMap{} == m); + QT_TEST_EQUALITY_OPS(m, m, true); + QT_TEST_EQUALITY_OPS(QCborMap{}, m, true); QCborValue v(m); QVERIFY(v.isMap()); @@ -669,7 +670,7 @@ void tst_QCborValue::mapEmptyDetach() QCborMap m2 = v.toMap(); QVERIFY(m2.isEmpty()); - QCOMPARE(m2, m); + QT_TEST_EQUALITY_OPS(m2, m, true); } void tst_QCborValue::arrayNonEmptyDetach() @@ -807,10 +808,9 @@ void tst_QCborValue::mapSimpleInitializerList() { QCborMap m{{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}}; QCOMPARE(m.size(), 6); - QVERIFY(m == m); - QVERIFY(m != QCborMap{}); - QVERIFY(QCborMap{} != m); - QVERIFY(m == QCborMap({{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}})); + QT_TEST_EQUALITY_OPS(m, m, true); + QT_TEST_EQUALITY_OPS(m, QCborMap{}, false); + QT_TEST_EQUALITY_OPS(m, QCborMap({{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}}), true); QCborValue vmap = m; { @@ -1093,27 +1093,27 @@ void tst_QCborValue::mapMutation() const QString strValue = QStringLiteral("value"); v = strValue; QVERIFY(v.isString()); - QCOMPARE(v, QCborValue(strValue)); - QCOMPARE(m, QCborMap({{42, strValue}})); + QT_TEST_EQUALITY_OPS(v, QCborValue(strValue), true); + QT_TEST_EQUALITY_OPS(m, QCborMap({{42, strValue}}), true); // HasByteData -> HasByteData const QLatin1String otherStrValue("othervalue"); v = otherStrValue; QVERIFY(v.isString()); - QCOMPARE(v, QCborValue(otherStrValue)); - QCOMPARE(m, QCborMap({{42, otherStrValue}})); + QT_TEST_EQUALITY_OPS(v, QCborValue(otherStrValue), true); + QT_TEST_EQUALITY_OPS(m, QCborMap({{42, otherStrValue}}), true); // HasByteData -> simple v = 42; QVERIFY(v.isInteger()); - QCOMPARE(v, QCborValue(42)); - QCOMPARE(m, QCborMap({{42, 42}})); + QT_TEST_EQUALITY_OPS(v, QCborValue(42), true); + QT_TEST_EQUALITY_OPS(m, QCborMap({{42, 42}}), true); // simple -> container v = QCborArray{1, 2, 3}; QVERIFY(v.isArray()); QT_TEST_EQUALITY_OPS(v, QCborArray({1, 2, 3}), true); - QCOMPARE(m, QCborMap({{42, QCborArray{1, 2, 3}}})); + QT_TEST_EQUALITY_OPS(m, QCborMap({{42, QCborArray{1, 2, 3}}}), true); // container -> simple v = true; @@ -1149,12 +1149,11 @@ void tst_QCborValue::mapMutation() QT_TEST_EQUALITY_OPS(it.value(), QCborValue(2.5), true); QT_TEST_EQUALITY_OPS((++it).value(), QCborValue(nullptr), true); QT_TEST_EQUALITY_OPS(it.key(), QCborValue(nullptr), true); - QVERIFY(m2 == m); - QVERIFY(m == m2); + QT_TEST_EQUALITY_OPS(m2, m, true); it.value() = -1; - QCOMPARE(it.key(), QCborValue(nullptr)); - QCOMPARE(it.value(), QCborValue(-1)); + QT_TEST_EQUALITY_OPS(it.key(), QCborValue(nullptr), true); + QT_TEST_EQUALITY_OPS(it.value(), QCborValue(-1), true); QCOMPARE((m.end() - 1)->toInteger(), -1); QVERIFY((m2.end() - 1)->isNull()); QCOMPARE(++it, end); @@ -1263,8 +1262,8 @@ void tst_QCborValue::arrayPrepend() QCborArray a; a.prepend(0); a.prepend(nullptr); - QCOMPARE(a.at(1), QCborValue(0)); - QCOMPARE(a.at(0), QCborValue(nullptr)); + QT_TEST_EQUALITY_OPS(a.at(1), QCborValue(0), true); + QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(nullptr), true); QCOMPARE(a.size(), 2); } @@ -1274,17 +1273,17 @@ void tst_QCborValue::arrayValueRef() QCborArray a = { v }; // methods that return QCborValueRef - QCOMPARE(a.first(), v); - QCOMPARE(a.last(), v); - QCOMPARE(a[0], v); + QT_TEST_EQUALITY_OPS(a.first(), v, true); + QT_TEST_EQUALITY_OPS(a.last(), v, true); + QT_TEST_EQUALITY_OPS(a[0], v, true); QVERIFY(v == a.first()); QVERIFY(v == a.last()); QVERIFY(v == a[0]); auto iteratorCheck = [&v](auto it) { - QCOMPARE(*it, v); + QT_TEST_EQUALITY_OPS(*it, v, true); QCOMPARE(it->type(), v.type()); // just to test operator-> - QCOMPARE(it[0], v); + QT_TEST_EQUALITY_OPS(it[0], v, true); }; iteratorCheck(a.begin()); @@ -1302,17 +1301,17 @@ void tst_QCborValue::arrayValueRefLargeKey() a[LargeKey + 1] = 123; QCborValue v(a); - QCOMPARE(std::as_const(v)[LargeKey], QCborValue()); + QT_TEST_EQUALITY_OPS(std::as_const(v)[LargeKey], QCborValue(), true); QCOMPARE(std::as_const(v)[LargeKey + 1], 123); - QCOMPARE(v[LargeKey], QCborValue()); + QT_TEST_EQUALITY_OPS(v[LargeKey], QCborValue(), true); QCOMPARE(v[LargeKey + 1], 123); QCOMPARE(v.type(), QCborValue::Array); QCborArray outer = { QCborValue(a) }; QCborValueRef ref = outer[0]; - QCOMPARE(std::as_const(ref)[LargeKey], QCborValue()); + QT_TEST_EQUALITY_OPS(std::as_const(ref)[LargeKey], QCborValue(), true); QCOMPARE(std::as_const(ref)[LargeKey + 1], 123); - QCOMPARE(ref[LargeKey], QCborValue()); + QT_TEST_EQUALITY_OPS(ref[LargeKey], QCborValue(), true); QCOMPARE(ref[LargeKey + 1], 123); QCOMPARE(ref.type(), QCborValue::Array); } @@ -1329,9 +1328,9 @@ void tst_QCborValue::mapValueRef() QCOMPARE(m.size(), 3); // methods that return QCborValueRef - QCOMPARE(m[intKey], v); - QCOMPARE(m[stringKey], v); - QCOMPARE(m[v], v); + QT_TEST_EQUALITY_OPS(m[intKey], v, true); + QT_TEST_EQUALITY_OPS(m[stringKey], v, true); + QT_TEST_EQUALITY_OPS(m[v], v, true); QVERIFY(v == m[intKey]); QVERIFY(v == m[stringKey]); QVERIFY(v == m[v]); @@ -1364,28 +1363,28 @@ void tst_QCborValue::arrayInsertRemove() a.append(42); a.append(v); a.insert(1, QCborValue(nullptr)); - QCOMPARE(a.at(0), QCborValue(42)); - QCOMPARE(a.at(1), QCborValue(nullptr)); - QCOMPARE(a.at(2), v); + QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(42), true); + QT_TEST_EQUALITY_OPS(a.at(1), QCborValue(nullptr), true); + QT_TEST_EQUALITY_OPS(a.at(2), v, true); // remove 42 a.removeAt(0); QCOMPARE(a.size(), 2); - QCOMPARE(a.at(0), QCborValue(nullptr)); - QCOMPARE(a.at(1), v); + QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(nullptr), true); + QT_TEST_EQUALITY_OPS(a.at(1), v, true); auto it = a.begin(); it = a.erase(it); // removes nullptr QCOMPARE(a.size(), 1); - QCOMPARE(a.at(0), v); + QT_TEST_EQUALITY_OPS(a.at(0), v, true); it = a.erase(it); QVERIFY(a.isEmpty()); - QCOMPARE(it, a.end()); + QT_TEST_EQUALITY_OPS(it, a.end(), true); // reinsert the element so we can take it a.append(v); - QCOMPARE(a.takeAt(0), v); + QT_TEST_EQUALITY_OPS(a.takeAt(0), v, true); QVERIFY(a.isEmpty()); } @@ -1411,11 +1410,11 @@ void tst_QCborValue::arrayStringElements() // v2 must continue to be valid after the entry getting removed a.removeAt(1); QCOMPARE(v2.toByteArray(), QByteArray("Hello")); - QCOMPARE(v2, QCborValue(QByteArray("Hello"))); + QT_TEST_EQUALITY_OPS(v2, QCborValue(QByteArray("Hello")), true); v2 = a.at(1); QCOMPARE(v2.toString(), "World"); - QCOMPARE(v2, QCborValue("World")); + QT_TEST_EQUALITY_OPS(v2, QCborValue("World"), true); QCOMPARE(a.takeAt(1).toString(), "World"); QCOMPARE(a.takeAt(0).toString(), "Hello"); @@ -1427,12 +1426,12 @@ void tst_QCborValue::mapStringValues() QCborMap m{{0, "Hello"}}; m.insert({1, QByteArray("Hello")}); m.insert({2, QLatin1String("World")}); - QVERIFY(m == m); + QT_TEST_EQUALITY_OPS(m, m, true); QCborValueRef r1 = m[0]; QCOMPARE(r1.toString(), "Hello"); QCOMPARE(r1.operator QCborValue(), QCborValue("Hello")); - QVERIFY(r1 == QCborValue("Hello")); + QT_TEST_EQUALITY_OPS(r1, QCborValue("Hello"), true); QCborValue v2 = m.value(1); QCOMPARE(v2.toByteArray(), QByteArray("Hello")); @@ -1441,7 +1440,7 @@ void tst_QCborValue::mapStringValues() // v2 must continue to be valid after the entry getting removed m.erase(m.constFind(1)); QCOMPARE(v2.toByteArray(), QByteArray("Hello")); - QCOMPARE(v2, QCborValue(QByteArray("Hello"))); + QT_TEST_EQUALITY_OPS(v2, QCborValue(QByteArray("Hello")), true); v2 = (m.begin() + 1).value(); QCOMPARE(v2.toString(), "World"); @@ -1459,14 +1458,12 @@ void tst_QCborValue::mapStringKeys() QCOMPARE(m.value(QLatin1String("World")), QCborValue(2)); QCborMap m2 = m; - QVERIFY(m2 == m); - QVERIFY(m == m2); + QT_TEST_EQUALITY_OPS(m2, m, true); m.insert({QByteArray("foo"), "bar"}); QCOMPARE(m.size(), 3); QCOMPARE(m2.size(), 2); - QVERIFY(m2 != m); - QVERIFY(m != m2); + QT_TEST_EQUALITY_OPS(m2, m, false); QVERIFY(m2.value(QCborValue(QByteArray("foo"))).isUndefined()); QVERIFY(m.value(QCborValue(QLatin1String("foo"))).isUndefined()); @@ -1484,8 +1481,7 @@ void tst_QCborValue::mapInsertRemove() m.insert(2, v); QVERIFY(m.contains(2)); - QVERIFY(m[2] == v); - QVERIFY(v == m[2]); + QT_TEST_EQUALITY_OPS(m[2], v, true); auto it = m.find(2); it = m.erase(it); @@ -1498,10 +1494,8 @@ void tst_QCborValue::mapInsertRemove() r = v; it = m.find(42); - QVERIFY(it.value() == v); - QVERIFY(v == it.value()); - QVERIFY(it.value() == r); - QVERIFY(r == it.value()); + QT_TEST_EQUALITY_OPS(it.value(), v, true); + QT_TEST_EQUALITY_OPS(it.value(), r, true); QCOMPARE(m.extract(it), v); QVERIFY(!m.contains(42)); @@ -1522,12 +1516,12 @@ void tst_QCborValue::arrayInsertTagged() QCborArray a{tagged}; a.insert(1, tagged); QCOMPARE(a.size(), 2); - QCOMPARE(a.at(0), tagged); - QCOMPARE(a.at(1), tagged); - QCOMPARE(a.at(0).taggedValue(), v); - QCOMPARE(a.at(1).taggedValue(), v); - QCOMPARE(a.takeAt(0).taggedValue(), v); - QCOMPARE(a.takeAt(0).taggedValue(), v); + QT_TEST_EQUALITY_OPS(a.at(0), tagged, true); + QT_TEST_EQUALITY_OPS(a.at(1), tagged, true); + QT_TEST_EQUALITY_OPS(a.at(0).taggedValue(), v, true); + QT_TEST_EQUALITY_OPS(a.at(1).taggedValue(), v, true); + QT_TEST_EQUALITY_OPS(a.takeAt(0).taggedValue(), v, true); + QT_TEST_EQUALITY_OPS(a.takeAt(0).taggedValue(), v, true); QVERIFY(a.isEmpty()); } @@ -1541,13 +1535,13 @@ void tst_QCborValue::mapInsertTagged() QCborMap m{{11, tagged}}; m.insert({-21, tagged}); QCOMPARE(m.size(), 2); - QCOMPARE(m.constBegin().value(), tagged); - QCOMPARE(m.value(-21), tagged); - QCOMPARE(m.value(11).taggedValue(), v); - QCOMPARE((m.end() - 1).value().taggedValue(), v); - QCOMPARE(m.extract(m.end() - 1).taggedValue(), v); + QT_TEST_EQUALITY_OPS(m.constBegin().value(), tagged, true); + QT_TEST_EQUALITY_OPS(m.value(-21), tagged, true); + QT_TEST_EQUALITY_OPS(m.value(11).taggedValue(), v, true); + QT_TEST_EQUALITY_OPS((m.end() - 1).value().taggedValue(), v, true); + QT_TEST_EQUALITY_OPS(m.extract(m.end() - 1).taggedValue(), v, true); QVERIFY(!m.contains(-21)); - QCOMPARE(m.take(11).taggedValue(), v); + QT_TEST_EQUALITY_OPS(m.take(11).taggedValue(), v, true); QVERIFY(m.isEmpty()); } @@ -1576,7 +1570,7 @@ void tst_QCborValue::arraySelfAssign() QCOMPARE(a.size(), 2); QCOMPARE(it->toArray().size(), 2); - QCOMPARE(it->toArray().last(), QCborValue(36)); + QT_TEST_EQUALITY_OPS(it->toArray().last(), QCborValue(36), true); } } @@ -1594,12 +1588,12 @@ void tst_QCborValue::mapSelfAssign() QCborValue vm = m; m[1] = vm; // self-assign QCOMPARE(m.size(), 2); - QCOMPARE(m.value(0), v); + QT_TEST_EQUALITY_OPS(m.value(0), v, true); QCborMap m2 = m.value(1).toMap(); // there mustn't be an element with key 1 QCOMPARE(m2.size(), 1); - QCOMPARE(m2.value(0), v); + QT_TEST_EQUALITY_OPS(m2.value(0), v, true); QVERIFY(!m2.contains(1)); } @@ -1611,14 +1605,14 @@ void tst_QCborValue::mapSelfAssign() QCborValueRef rv = m[1]; rv = m; // self-assign (implicit QCborValue creation) QCOMPARE(m.size(), 2); - QCOMPARE(m.value(0), v); + QT_TEST_EQUALITY_OPS(m.value(0), v, true); QCborMap m2 = m.value(1).toMap(); // there must be an element with key 1 QCOMPARE(m2.size(), 2); - QCOMPARE(m2.value(0), v); + QT_TEST_EQUALITY_OPS(m2.value(0), v, true); QVERIFY(m2.contains(1)); - QCOMPARE(m2.value(1), QCborValue()); + QT_TEST_EQUALITY_OPS(m2.value(1), QCborValue(), true); } m = {{0, v}}; @@ -1642,8 +1636,8 @@ void tst_QCborValue::mapSelfAssign() QCOMPARE(m.size(), 2); auto it = m.constEnd() - 1; - QCOMPARE(it.value(), v); - QCOMPARE(it.key(), QCborMap({{0, v}})); + QT_TEST_EQUALITY_OPS(it.value(), v, true); + QT_TEST_EQUALITY_OPS(it.key(), QCborMap({{0, v}}), true); } } @@ -1895,6 +1889,91 @@ void tst_QCborValue::sorting() QVERIFY(vint2.toInteger() > vdouble1.toDouble()); } +void tst_QCborValue::comparison_data() +{ + QTest::addColumn("lhs"); + QTest::addColumn("rhs"); + QTest::addColumn("expectedOrdering"); + + auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) { + QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()), + qPrintable(rhs.toDiagnosticNotation())) + << lhs << rhs << order; + }; + // typical, sorts as expected + addRow(0, 0, Qt::strong_ordering::equivalent); + addRow(1, 0, Qt::strong_ordering::greater); + addRow(0, 1, Qt::strong_ordering::less); + addRow(10.0, 10.0, Qt::strong_ordering::equivalent); + addRow(10.5, 10.8, Qt::strong_ordering::less); + addRow(-10.5, -10.8, Qt::strong_ordering::less); + addRow("Qt","Qt", Qt::strong_ordering::equivalent); + addRow("qt","Qt", Qt::strong_ordering::greater); + + // atypical gotchas + addRow(0, -1, Qt::strong_ordering::less); + addRow(10, 10.0, Qt::strong_ordering::less); + addRow(0, "Qt", Qt::strong_ordering::less); +} + +void tst_QCborValue::comparison() +{ + QFETCH(QCborValue, lhs); + QFETCH(QCborValue, rhs); + QFETCH(Qt::strong_ordering, expectedOrdering); + + QCborArray array{lhs, rhs}; + + QCborValueConstRef lhsCRef = array.constBegin()[0]; + QCborValueConstRef rhsCRef = array.constBegin()[1]; + QCborValueRef lhsRef = array[0]; + QCborValueRef rhsRef = array[1]; + + // QCborValue vs QCborValue + QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedOrdering); + // QCborValueConstRef vs QCborValueConstRef + QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsCRef, expectedOrdering); + // QCborValueRef vs QCborValueRef + QT_TEST_ALL_COMPARISON_OPS(lhsRef, rhsRef, expectedOrdering); + // QCborValue vs QCborValueConstRef (and reverse) + QT_TEST_ALL_COMPARISON_OPS(lhs, rhsCRef, expectedOrdering); + // QCborValue vs QCborValueRef (and reverse) + QT_TEST_ALL_COMPARISON_OPS(lhs, rhsRef, expectedOrdering); + // QCborValueConstRef vs QCborValueRef (and reverse) + QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsRef, expectedOrdering); +} + + +void tst_QCborValue::comparisonMap_data() +{ + QTest::addColumn("left"); + QTest::addColumn("right"); + QTest::addColumn("expectedOrdering"); + + QTest::addRow("map{{0, 1}, {10, 0}}, map{{10, 1}, {10, 0}}") + << QCborMap{{0, 1}, {10, 0}} + << QCborMap{{10, 1}, {10, 0}} + << Qt::strong_ordering::greater; + + QTest::addRow("map{{0, 1}, {0, 0}}, map{{0, 1}, {0, 0}}") + << QCborMap{{0, 1}, {0, 0}} + << QCborMap{{0, 1}, {0, 0}} + << Qt::strong_ordering::equivalent; + + QTest::addRow("map{{0, 1}, {10, 0}}, map{{10, 1}, {10, 0}, {10, 0}}") + << QCborMap{{10, 1}, {10, 0}} + << QCborMap{{0, 1}, {10, 0}, {10, 0}} + << Qt::strong_ordering::less; +} + +void tst_QCborValue::comparisonMap() +{ + QFETCH(QCborMap, left); + QFETCH(QCborMap, right); + QFETCH(Qt::strong_ordering, expectedOrdering); + QT_TEST_ALL_COMPARISON_OPS(left, right, expectedOrdering); +} + static void addCommonCborData() { // valid for both decoding and encoding @@ -2398,7 +2477,7 @@ void tst_QCborValue::extendedTypeValidation() QCborValue decoded = QCborValue::fromCbor(data, &error); QVERIFY2(error.error == QCborError(), qPrintable(error.errorString())); QCOMPARE(error.offset, data.size()); - QCOMPARE(decoded, expected); + QT_TEST_EQUALITY_OPS(decoded, expected, true); QByteArray encoded = decoded.toCbor(); #if QT_VERSION < QT_VERSION_CHECK(6,0,0) @@ -2675,14 +2754,9 @@ template static void cborValueRef_template() QCborArray a = { v }; const ValueRef ref = a[0]; - QCOMPARE(ref, v); + QT_TEST_EQUALITY_OPS(ref, v, true); QVERIFY(ref.compare(v) == 0); QVERIFY(v.compare(ref) == 0); - QVERIFY(v == ref); - QVERIFY(!(ref != v)); - QVERIFY(!(v != ref)); - QVERIFY(!(ref < v)); - QVERIFY(!(v < ref)); // compare properties of the QCborValueRef against the QCborValue it represents QCOMPARE(ref.type(), v.type()); @@ -2771,7 +2845,7 @@ void tst_QCborValue::cborValueRefMutatingArray() QVERIFY(va.isArray()); QCOMPARE(va.toArray().size(), 2); QCOMPARE(va.toArray().first(), 123); - QCOMPARE(va.toArray().last(), v); + QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true); // ensure the array didn't get modified QT_TEST_EQUALITY_OPS(origArray, QCborArray{123}, true); @@ -2789,8 +2863,8 @@ void tst_QCborValue::cborValueRefMutatingArray() QCborValue va = a.at(0); QVERIFY(va.isArray()); QCOMPARE(va.toArray().size(), 2); - QCOMPARE(va.toArray().first(), QCborValue()); - QCOMPARE(va.toArray().last(), v); + QT_TEST_EQUALITY_OPS(va.toArray().first(), QCborValue(), true); + QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true); // ensure the array didn't get modified QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true); @@ -2810,8 +2884,8 @@ void tst_QCborValue::cborValueRefMutatingArray() QCborValue va = a.at(0); QVERIFY(va.isArray()); QCOMPARE(va.toArray().size(), 2); - QCOMPARE(va.toArray().first(), QCborValue()); - QCOMPARE(va.toArray().last(), v); + QT_TEST_EQUALITY_OPS(va.toArray().first(), QCborValue(), true); + QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true); // ensure the array didn't get modified QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true); @@ -3100,61 +3174,6 @@ void tst_QCborValue::testlibFormatting() QCOMPARE(actual, expected); } -void tst_QCborValue::comparison_data() -{ - QTest::addColumn("lhs"); - QTest::addColumn("rhs"); - QTest::addColumn("expectedOrdering"); - - auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) { - QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()), - qPrintable(rhs.toDiagnosticNotation())) - << lhs << rhs << order; - }; - // typical, sorts as expected - addRow(0, 0, Qt::strong_ordering::equivalent); - addRow(1, 0, Qt::strong_ordering::greater); - addRow(0, 1, Qt::strong_ordering::less); - addRow(10.0, 10.0, Qt::strong_ordering::equivalent); - addRow(10.5, 10.8, Qt::strong_ordering::less); - addRow(-10.5, -10.8, Qt::strong_ordering::less); - addRow("Qt","Qt", Qt::strong_ordering::equivalent); - addRow("qt","Qt", Qt::strong_ordering::greater); - - // atypical gotchas - addRow(0, -1, Qt::strong_ordering::less); - addRow(10, 10.0, Qt::strong_ordering::less); - addRow(0, "Qt", Qt::strong_ordering::less); - -} - -void tst_QCborValue::comparison() -{ - QFETCH(QCborValue, lhs); - QFETCH(QCborValue, rhs); - QFETCH(Qt::strong_ordering, expectedOrdering); - - QCborArray array{lhs, rhs}; - - QCborValueConstRef lhsCRef = array.constBegin()[0]; - QCborValueConstRef rhsCRef = array.constBegin()[1]; - QCborValueRef lhsRef = array[0]; - QCborValueRef rhsRef = array[1]; - - // QCborValue vs QCborValue - QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedOrdering); - // QCborValueConstRef vs QCborValueConstRef - QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsCRef, expectedOrdering); - // QCborValueRef vs QCborValueRef - QT_TEST_ALL_COMPARISON_OPS(lhsRef, rhsRef, expectedOrdering); - // QCborValue vs QCborValueConstRef (and reverse) - QT_TEST_ALL_COMPARISON_OPS(lhs, rhsCRef, expectedOrdering); - // QCborValue vs QCborValueRef (and reverse) - QT_TEST_ALL_COMPARISON_OPS(lhs, rhsRef, expectedOrdering); - // QCborValueConstRef vs QCborValueRef (and reverse) - QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsRef, expectedOrdering); -} - QTEST_MAIN(tst_QCborValue) #include "tst_qcborvalue.moc"