From 3c7b507d1c0f9d1fd645ff5244391f9e4aab51eb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 11 Nov 2021 11:10:27 -0800 Subject: [PATCH] QCborValueRef: add a test to confirm that its methods reflect QCborValue This has found several missing const qualifications, a missing QCborMap::Iterator method, and a missing one in QCborValue too. The methods "### TEMPORARY" in this commit are actually removed in two commits. Change-Id: I5e52dc5b093c43a3b678fffd16b6939f62954dc4 Reviewed-by: Sona Kurazyan --- src/corelib/serialization/qcborarray.cpp | 4 +- src/corelib/serialization/qcborarray.h | 6 +- src/corelib/serialization/qcbormap.h | 4 +- src/corelib/serialization/qcborvalue.cpp | 6 +- src/corelib/serialization/qcborvalue.h | 12 +- .../qcborvalue/tst_qcborvalue.cpp | 164 +++++++++++++++++- 6 files changed, 187 insertions(+), 9 deletions(-) diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 11f469dc86..653557544c 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -809,7 +809,7 @@ void QCborArray::detach(qsizetype reserved) */ /*! - \fn QCborValueRef QCborArray::Iterator::operator[](qsizetype j) + \fn QCborValueRef QCborArray::Iterator::operator[](qsizetype j) const Returns a modifiable reference to the item at a position \a j steps forward from the item pointed to by this iterator. @@ -1055,7 +1055,7 @@ void QCborArray::detach(qsizetype reserved) */ /*! - \fn const QCborValueRef QCborArray::ConstIterator::operator[](qsizetype j) + \fn QCborValueRef QCborArray::ConstIterator::operator[](qsizetype j) const Returns the item at a position \a j steps forward from the item pointed to by this iterator. diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index 63f54dc2a5..be22af3985 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -80,7 +80,7 @@ public: QCborValueRef operator*() const { return item; } QCborValueRef *operator->() const { return &item; } - QCborValueRef operator[](qsizetype j) { return { item.d, item.i + j }; } + QCborValueRef operator[](qsizetype j) const { return { item.d, item.i + j }; } bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; } bool operator!=(const Iterator &o) const { return !(*this == o); } @@ -129,7 +129,7 @@ public: const QCborValueRef operator*() const { return item; } const QCborValueRef *operator->() const { return &item; } - const QCborValueRef operator[](qsizetype j) { return { item.d, item.i + j }; } + QCborValueRef operator[](qsizetype j) const { return QCborValueRef{ item.d, item.i + j }; } bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; } bool operator!=(const Iterator &o) const { return !(*this == o); } diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index ed9c2f21d5..965e39b306 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -85,6 +85,7 @@ public: } value_type operator*() const { return { {item.d, item.i - 1}, item }; } + value_type operator[](qsizetype j) const { return *(*this + j); } QCborValueRef *operator->() const { return &item; } QCborValue key() const { return QCborValueRef(item.d, item.i - 1); } QCborValueRef value() const { return item; } @@ -137,6 +138,7 @@ public: } value_type operator*() const { return { {item.d, item.i - 1}, item }; } + value_type operator[](qsizetype j) const { return *(*this + j); } const QCborValueRef *operator->() const { return &item; } QCborValue key() const { return QCborValueRef(item.d, item.i - 1); } QCborValueRef value() const { return item; } diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index ae64db0c3e..adffa05613 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 Intel Corporation. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -2642,6 +2642,10 @@ void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOption { concrete().toCbor(writer, opt); } +void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt) const +{ + concrete().toCbor(writer, opt); +} #endif // QT_CONFIG(cborstreamwriter) void QCborValueRef::assign(QCborValueRef that, const QCborValue &other) diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 6a1558e2b5..f452297cbf 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -371,6 +371,10 @@ public: { return type() == QCborValue::type_helper(st); } + QCborSimpleType toSimpleType(QCborSimpleType defaultValue = QCborSimpleType::Undefined) const + { + return isSimpleType() ? QCborSimpleType(type() & 0xff) : defaultValue; + } QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const { return concrete().tag(defaultValue); } @@ -436,13 +440,19 @@ public: QVariant toVariant() const { return concrete().toVariant(); } QJsonValue toJsonValue() const; + // ### TEMPORARY #if QT_CONFIG(cborstreamwriter) QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) + { return qAsConst(*this).toCbor(opt); } + QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const { return concrete().toCbor(opt); } void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation); + void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const; #endif QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) + { return qAsConst(*this).toDiagnosticNotation(opt); } + QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) const { return concrete().toDiagnosticNotation(opt); } private: diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 753346f706..cb93a701b7 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 Intel Corporation. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -72,6 +72,8 @@ private slots: void arrayMutation(); void arrayMutateWithCopies(); void arrayPrepend(); + void arrayValueRef_data() { basics_data(); } + void arrayValueRef(); void arrayInsertRemove_data() { basics_data(); } void arrayInsertRemove(); void arrayInsertTagged_data() { basics_data(); } @@ -90,6 +92,8 @@ private slots: void mapMutateWithCopies(); void mapStringValues(); void mapStringKeys(); + void mapValueRef_data() { basics_data(); } + void mapValueRef(); void mapInsertRemove_data() { basics_data(); } void mapInsertRemove(); void mapInsertTagged_data() { basics_data(); } @@ -123,6 +127,9 @@ private slots: void toDiagnosticNotation_data(); void toDiagnosticNotation(); + void cborValueRef_data(); + void cborValueRef(); + void datastreamSerialization_data(); void datastreamSerialization(); void streamVariantSerialization(); @@ -303,6 +310,7 @@ static void basicTypeCheck(QCborValue::Type type, const QCborValue &v, const QVa QCOMPARE(v.isDouble(), type == QCborValue::Double); QCOMPARE(v.isDateTime(), type == QCborValue::DateTime); QCOMPARE(v.isUrl(), type == QCborValue::Url); + QCOMPARE(v.isRegularExpression(), type == QCborValue::RegularExpression); QCOMPARE(v.isUuid(), type == QCborValue::Uuid); QCOMPARE(v.isInvalid(), type == QCborValue::Invalid); QCOMPARE(v.isContainer(), type == QCborValue::Array || type == QCborValue::Map); @@ -1225,6 +1233,71 @@ void tst_QCborValue::arrayPrepend() QCOMPARE(a.size(), 2); } +void tst_QCborValue::arrayValueRef() +{ + QFETCH(QCborValue, v); + QCborArray a = { v }; + + // methods that return QCborValueRef + QCOMPARE(a.first(), v); + QCOMPARE(a.last(), v); + QCOMPARE(a[0], v); + QVERIFY(v == a.first()); + QVERIFY(v == a.last()); + QVERIFY(v == a[0]); + + auto iteratorCheck = [&v](auto it) { + QCOMPARE(*it, v); + QCOMPARE(it->type(), v.type()); // just to test operator-> + QCOMPARE(it[0], v); + }; + + iteratorCheck(a.begin()); + if (QTest::currentTestFailed()) + return; + iteratorCheck(a.constBegin()); +} + +void tst_QCborValue::mapValueRef() +{ + QFETCH(QCborValue, v); + QLatin1String stringKey("other string"); + qint64 intKey = 47; + Q_ASSERT(v != stringKey); + Q_ASSERT(v != intKey); + + QCborMap m = { { v, v }, { stringKey, v }, { intKey, v } }; + QCOMPARE(m.size(), 3); + + // methods that return QCborValueRef + QCOMPARE(m[intKey], v); + QCOMPARE(m[stringKey], v); + QCOMPARE(m[v], v); + QVERIFY(v == m[intKey]); + QVERIFY(v == m[stringKey]); + QVERIFY(v == m[v]); + + auto iteratorCheck = [=](auto it) { + QCOMPARE((*it).second, v); + QCOMPARE(it[0].second, v); + QCOMPARE(it[1].second, v); + QCOMPARE(it[2].second, v); + QCOMPARE(it.value(), v); + QCOMPARE(it->type(), v.type()); // just to test operator-> + + // compare keys too + QCOMPARE((*it).first, v); + QCOMPARE(it.key(), v); + QCOMPARE((it + 1).key(), stringKey); + QCOMPARE((it + 2).key(), intKey); + }; + + iteratorCheck(m.begin()); + if (QTest::currentTestFailed()) + return; + iteratorCheck(m.constBegin()); +} + void tst_QCborValue::arrayInsertRemove() { QFETCH(QCborValue, v); @@ -2494,6 +2567,95 @@ void tst_QCborValue::toDiagnosticNotation() QCOMPARE(result, expected); } +void tst_QCborValue::cborValueRef_data() +{ + basics_data(); + + // Add tagged data and non-empty containers (non-basic) + QTest::newRow("Array:nonempty") << QCborValue::Array << QCborValue(QCborArray{0}); + QTest::newRow("Map:nonempty") << QCborValue::Map << QCborValue(QCborMap{ { 0, 1 } }); + QTest::newRow("Tagged") << QCborValue::Tag << QCborValue(QCborKnownTags::Base64, QByteArray()); +} + +void tst_QCborValue::cborValueRef() +{ + const QCborArray otherArray = {2}; + const QCborMap otherMap = { { 2, 21 } }; + const QDateTime otherDateTime = QDateTime::fromSecsSinceEpoch(1636654201); + const QUrl otherUrl("http://example.org"); + const QRegularExpression otherRE("[.]*"); + const QUuid otherUuid = QUuid::createUuid(); + + QFETCH(QCborValue, v); + QCborArray a = { v }; + const QCborValueRef ref = a[0]; + + QCOMPARE(ref, v); + 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()); + QCOMPARE(ref.isInteger(), v.isInteger()); + QCOMPARE(ref.isByteArray(), v.isByteArray()); + QCOMPARE(ref.isString(), v.isString()); + QCOMPARE(ref.isArray(), v.isArray()); + QCOMPARE(ref.isMap(), v.isMap()); + QCOMPARE(ref.isFalse(), v.isFalse()); + QCOMPARE(ref.isTrue(), v.isTrue()); + QCOMPARE(ref.isBool(), v.isBool()); + QCOMPARE(ref.isNull(), v.isNull()); + QCOMPARE(ref.isUndefined(), v.isUndefined()); + QCOMPARE(ref.isDouble(), v.isDouble()); + QCOMPARE(ref.isDateTime(), v.isDateTime()); + QCOMPARE(ref.isUrl(), v.isUrl()); + QCOMPARE(ref.isRegularExpression(), v.isRegularExpression()); + QCOMPARE(ref.isUuid(), v.isUuid()); + QCOMPARE(ref.isInvalid(), v.isInvalid()); + QCOMPARE(ref.isContainer(), v.isContainer()); + QCOMPARE(ref.isSimpleType(), v.isSimpleType()); + QCOMPARE(ref.isSimpleType(QCborSimpleType::False), v.isSimpleType(QCborSimpleType::False)); + QCOMPARE(ref.isSimpleType(QCborSimpleType::True), v.isSimpleType(QCborSimpleType::True)); + QCOMPARE(ref.isSimpleType(QCborSimpleType::Null), v.isSimpleType(QCborSimpleType::Null)); + QCOMPARE(ref.isSimpleType(QCborSimpleType::Undefined), v.isSimpleType(QCborSimpleType::Undefined)); + QCOMPARE(ref.isSimpleType(QCborSimpleType(255)), v.isSimpleType(QCborSimpleType(255))); + + QCOMPARE(ref.tag(), v.tag()); + QCOMPARE(ref.taggedValue(), v.taggedValue()); + + QCOMPARE(ref.toBool(false), v.toBool(false)); + QCOMPARE(ref.toBool(true), v.toBool(true)); + QCOMPARE(ref.toInteger(47), v.toInteger(47)); + QCOMPARE(ref.toDouble(47), v.toDouble(47)); + QCOMPARE(ref.toByteArray("other"), v.toByteArray("other")); + QCOMPARE(ref.toString("other"), v.toString("other")); + QCOMPARE(ref.toArray(otherArray), v.toArray(otherArray)); + QCOMPARE(ref.toMap(otherMap), v.toMap(otherMap)); + QCOMPARE(ref.toDateTime(otherDateTime), v.toDateTime(otherDateTime)); + QCOMPARE(ref.toRegularExpression(otherRE), v.toRegularExpression(otherRE)); + QCOMPARE(ref.toUrl(otherUrl), v.toUrl(otherUrl)); + QCOMPARE(ref.toUuid(otherUuid), v.toUuid(otherUuid)); + QCOMPARE(ref.toSimpleType(QCborSimpleType(254)), v.toSimpleType(QCborSimpleType(254))); + + QCOMPARE(ref.toArray().isEmpty(), v.toArray().isEmpty()); + QCOMPARE(ref.toMap().isEmpty(), v.toMap().isEmpty()); + QCOMPARE(ref[0], qAsConst(v)[0]); + QCOMPARE(ref[QLatin1String("other")], qAsConst(v)[QLatin1String("other")]); + QCOMPARE(ref[QString("other")], qAsConst(v)[QString("other")]); + + if (qIsNaN(v.toDouble())) + QCOMPARE(qIsNaN(ref.toVariant().toDouble()), qIsNaN(v.toVariant().toDouble())); + else + QCOMPARE(ref.toVariant(), v.toVariant()); + QCOMPARE(ref.toJsonValue(), v.toJsonValue()); + QCOMPARE(ref.toCbor(), v.toCbor()); + QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation()); +} void tst_QCborValue::datastreamSerialization_data() {