summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/serialization
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/serialization')
-rw-r--r--tests/auto/corelib/serialization/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/serialization/cborlargedatavalidation.cpp4
-rw-r--r--tests/auto/corelib/serialization/json/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/serialization/json/tst_qtjson.cpp267
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp99
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp12
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp793
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt9
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp2
-rw-r--r--tests/auto/corelib/serialization/qdatastream/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp2
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp119
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp8
-rw-r--r--tests/auto/corelib/serialization/qtextstream/BLACKLIST2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/CMakeLists.txt9
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt3
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt3
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt3
-rw-r--r--tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt9
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp110
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/qc14n.h22
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml20
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml20
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml15
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp461
33 files changed, 1650 insertions, 450 deletions
diff --git a/tests/auto/corelib/serialization/CMakeLists.txt b/tests/auto/corelib/serialization/CMakeLists.txt
index b779ae8106..3792336255 100644
--- a/tests/auto/corelib/serialization/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/CMakeLists.txt
@@ -1,17 +1,20 @@
-# Generated from serialization.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(json)
add_subdirectory(qcborstreamreader)
add_subdirectory(qcborstreamwriter)
-add_subdirectory(qcborvalue)
+if(NOT WASM)
+ add_subdirectory(qcborvalue)
+endif()
add_subdirectory(qcborvalue_json)
if(TARGET Qt::Gui)
add_subdirectory(qdatastream)
add_subdirectory(qdatastream_core_pixmap)
endif()
-if(TARGET Qt::Network)
+if(TARGET Qt::Network AND NOT WASM)
add_subdirectory(qtextstream)
endif()
-if(TARGET Qt::Network AND TARGET Qt::Xml AND NOT INTEGRITY AND NOT QNX)
+if(TARGET Qt::Gui AND TARGET Qt::Network AND TARGET Qt::Xml AND NOT INTEGRITY AND NOT QNX AND NOT WASM)
add_subdirectory(qxmlstream)
endif()
diff --git a/tests/auto/corelib/serialization/cborlargedatavalidation.cpp b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp
index ac1305057c..2fe1012f12 100644
--- a/tests/auto/corelib/serialization/cborlargedatavalidation.cpp
+++ b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2020 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtEndian>
@@ -26,7 +26,6 @@ protected:
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *, qint64) override { return -1; }
};
-};
qint64 LargeIODevice::readData(char *data, qint64 maxlen)
{
@@ -118,3 +117,4 @@ void addValidationHugeDevice(qsizetype byteArrayInvalid, qsizetype stringInvalid
addSize("4GB", quint64(1) << 32);
addSize("max", std::numeric_limits<qint64>::max() - sizeof(buf));
}
+} // namespace
diff --git a/tests/auto/corelib/serialization/json/CMakeLists.txt b/tests/auto/corelib/serialization/json/CMakeLists.txt
index 01432873f5..c73a99a3b8 100644
--- a/tests/auto/corelib/serialization/json/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/json/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from json.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_json Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_json LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
set(json_resource_files
"bom.json"
"test.json"
@@ -17,8 +24,9 @@ set(json_resource_files
qt_internal_add_test(tst_json
SOURCES
tst_qtjson.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
+ Qt::TestPrivate
TESTDATA ${json_resource_files}
)
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
index fe97e03690..54ef9be4f2 100644
--- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
@@ -1,8 +1,9 @@
// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2022 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QMap>
#include <QVariantList>
@@ -27,6 +28,7 @@ class tst_QtJson: public QObject
private Q_SLOTS:
void initTestCase();
+ void compareCompiles();
void testValueSimple();
void testNumbers();
void testNumbers_2();
@@ -47,6 +49,8 @@ private Q_SLOTS:
void testArrayNested();
void testArrayNestedEmpty();
void testArrayComfortOperators();
+ void testArrayEquality_data();
+ void testArrayEquality();
void testObjectNestedEmpty();
void testValueRef();
@@ -169,6 +173,31 @@ void tst_QtJson::initTestCase()
testDataDir = QCoreApplication::applicationDirPath();
}
+void tst_QtJson::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QJsonArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::const_iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::iterator,
+ QJsonArray::const_iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::const_iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator,
+ QJsonObject::const_iterator>();
+}
+
void tst_QtJson::testValueSimple()
{
QJsonObject object;
@@ -371,6 +400,7 @@ void tst_QtJson::testNumbers_2()
QVERIFY2(floatValues[power] == floatValues_1[power], QString("floatValues[%1] != floatValues_1[%1]").arg(power).toLatin1());
}
+ QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
// The last value is below min denorm and should round to 0, everything else should contain a value
QVERIFY2(floatValues_1[1075] == 0, "Value after min denorm should round to 0");
@@ -402,6 +432,10 @@ void tst_QtJson::testNumbers_3()
QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
+ QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
+ QT_TEST_EQUALITY_OPS(jDocument1, QJsonDocument(), false);
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(), true);
+
double d1_1(jDocument2.object().value("d1").toDouble());
double d2_1(jDocument2.object().value("d2").toDouble());
QVERIFY(d1_1 != d2_1);
@@ -419,7 +453,8 @@ void tst_QtJson::testNumbers_4()
array << QJsonValue(-9223372036854775808.0);
array << QJsonValue(+18446744073709551616.0);
array << QJsonValue(-18446744073709551616.0);
- const QByteArray json(QJsonDocument(array).toJson());
+ QJsonDocument doc1 = QJsonDocument(array);
+ const QByteArray json(doc1.toJson());
const QByteArray expected =
"[\n"
" 1000000000000000,\n"
@@ -440,7 +475,8 @@ void tst_QtJson::testNumbers_4()
array2 << QJsonValue(Q_INT64_C(-9007199254740992));
array2 << QJsonValue(Q_INT64_C(+9223372036854775807));
array2 << QJsonValue(Q_INT64_C(-9223372036854775807));
- const QByteArray json2(QJsonDocument(array2).toJson());
+ QJsonDocument doc2 = QJsonDocument(array2);
+ const QByteArray json2(doc2.toJson());
const QByteArray expected2 =
"[\n"
" 1000000000000000,\n"
@@ -451,6 +487,8 @@ void tst_QtJson::testNumbers_4()
" -9223372036854775807\n"
"]\n";
QCOMPARE(json2, expected2);
+
+ QT_TEST_EQUALITY_OPS(doc1, doc2, false);
}
void tst_QtJson::testNumberComparisons()
@@ -499,6 +537,7 @@ void tst_QtJson::testObjectSimple()
QJsonValue value(QLatin1String("foo"));
object.insert("value", value);
QCOMPARE(object.value("value"), value);
+ QT_TEST_EQUALITY_OPS(object.value("value"), value, true);
int size = object.size();
object.remove("boolean");
@@ -507,6 +546,7 @@ void tst_QtJson::testObjectSimple()
QJsonValue taken = object.take("value");
QCOMPARE(taken, value);
+ QT_TEST_EQUALITY_OPS(taken, value, true);
QVERIFY2(!object.contains("value"), "key value should have been removed");
QString before = object.value("string").toString();
@@ -636,6 +676,7 @@ void tst_QtJson::testObjectInsertCopies()
QCOMPARE(obj.size(), 2);
QCOMPARE(obj.value("value"), "TEST");
QCOMPARE(obj.value("prop2"), "TEST");
+ QT_TEST_EQUALITY_OPS(rv, obj["value"].toObject(), true);
}
{
QJsonObject obj;
@@ -768,15 +809,20 @@ void tst_QtJson::testValueObject()
void tst_QtJson::testValueArray()
{
QJsonArray array;
+ QJsonArray otherArray = {"wrong value"};
+ QJsonValue value(array);
+ QCOMPARE(value.toArray(), array);
+ QCOMPARE(value.toArray(otherArray), array);
+
array.append(999.);
array.append(QLatin1String("test"));
array.append(true);
-
- QJsonValue value(array);
+ value = array;
// if we don't modify the original JsonArray, toArray()
// on the JsonValue should return the same object (non-detached).
QCOMPARE(value.toArray(), array);
+ QCOMPARE(value.toArray(otherArray), array);
// if we modify the original array, it should detach
array.append(QLatin1String("test"));
@@ -786,14 +832,28 @@ void tst_QtJson::testValueArray()
void tst_QtJson::testObjectNested()
{
QJsonObject inner, outer;
+ QJsonObject otherObject = {{"wrong key", "wrong value"}};
+ QJsonValue v = inner;
+ QCOMPARE(v.toObject(), inner);
+ QCOMPARE(v.toObject(otherObject), inner);
+ QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
+ QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
+
inner.insert("number", 999.);
outer.insert("nested", inner);
+ QT_TEST_EQUALITY_OPS(outer, inner, false);
// if we don't modify the original JsonObject, value()
// should return the same object (non-detached).
QJsonObject value = outer.value("nested").toObject();
+ v = value;
QCOMPARE(value, inner);
QCOMPARE(value.value("number").toDouble(), 999.);
+ QCOMPARE(v.toObject(), inner);
+ QCOMPARE(v.toObject(otherObject), inner);
+ QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
+ QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
+ QCOMPARE(v["number"].toDouble(), 999.);
// if we modify the original object, it should detach and not
// affect the nested object
@@ -818,6 +878,7 @@ void tst_QtJson::testObjectNested()
QCOMPARE(outer.value("nested").toObject().value("nested").toObject(), twoDeep);
QCOMPARE(outer.value("nested").toObject().value("nested").toObject().value("boolean").toBool(),
true);
+ QT_TEST_EQUALITY_OPS(outer.value("nested").toObject().value("nested").toObject(), twoDeep, true);
}
void tst_QtJson::testArrayNested()
@@ -843,6 +904,7 @@ void tst_QtJson::testArrayNested()
object.insert("boolean", true);
outer.append(object);
QCOMPARE(outer.last().toObject(), object);
+ QT_TEST_EQUALITY_OPS(outer.last().toObject(), object, true);
QCOMPARE(outer.last().toObject().value("boolean").toBool(), true);
// two deep arrays
@@ -862,6 +924,7 @@ void tst_QtJson::testArrayNestedEmpty()
QJsonValue val = object.value("inner");
QJsonArray value = object.value("inner").toArray();
QVERIFY(QJsonDocument(value).isArray());
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0);
QCOMPARE(value, inner);
QCOMPARE(value.size(), 0);
@@ -879,14 +942,46 @@ void tst_QtJson::testObjectNestedEmpty()
object.insert("inner2", inner2);
QJsonObject value = object.value("inner").toObject();
QVERIFY(QJsonDocument(value).isObject());
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0);
QCOMPARE(value, inner);
+ QT_TEST_EQUALITY_OPS(value, inner, true);
QCOMPARE(value.size(), 0);
object.insert("count", 0.);
QCOMPARE(object.value("inner").toObject().size(), 0);
QCOMPARE(object.value("inner").type(), QJsonValue::Object);
}
+void tst_QtJson::testArrayEquality_data()
+{
+ QTest::addColumn<QJsonArray>("array1");
+ QTest::addColumn<QJsonArray>("array2");
+ QTest::addColumn<bool>("expectedResult");
+ QTest::addRow("QJsonArray(), QJsonArray{665, 666, 667}")
+ << QJsonArray() << QJsonArray{665, 666, 667} << false;
+ QTest::addRow("QJsonArray(), QJsonArray{}")
+ << QJsonArray() << QJsonArray{} <<true;
+ QTest::addRow("QJsonArray(), QJsonArray{123, QLatin1String(\"foo\")}")
+ << QJsonArray() << QJsonArray{123, QLatin1String("foo")} << false;
+ QTest::addRow(
+ "QJsonArray{123,QLatin1String(\"foo\")}, QJsonArray{123,QLatin1String(\"foo\")}")
+ << QJsonArray{123, QLatin1String("foo")}
+ << QJsonArray{123, QLatin1String("foo")}
+ << true;
+}
+
+void tst_QtJson::testArrayEquality()
+{
+ QFETCH(QJsonArray, array1);
+ QFETCH(QJsonArray, array2);
+ QFETCH(bool, expectedResult);
+
+ QJsonValue value = QJsonValue(array1);
+
+ QT_TEST_EQUALITY_OPS(array1, array2, expectedResult);
+ QT_TEST_EQUALITY_OPS(value, array2, expectedResult);
+}
+
void tst_QtJson::testArrayComfortOperators()
{
QJsonArray first;
@@ -926,7 +1021,7 @@ void tst_QtJson::testValueRef()
QCOMPARE(object.value(QLatin1String("null")), QJsonValue());
object[QLatin1String("null")] = 100.;
QCOMPARE(object.value(QLatin1String("null")).type(), QJsonValue::Double);
- QJsonValue val = qAsConst(object)[QLatin1String("null")];
+ QJsonValue val = std::as_const(object)[QLatin1String("null")];
QCOMPARE(val.toDouble(), 100.);
QCOMPARE(object.size(), 2);
@@ -983,6 +1078,12 @@ void tst_QtJson::testValueRefComparison()
// val <> val
CHECK(a0, a0, a1);
+ QT_TEST_EQUALITY_OPS(r0, r1, false);
+ QT_TEST_EQUALITY_OPS(r0, c0, true);
+ QT_TEST_EQUALITY_OPS(c0, r1, false);
+ QT_TEST_EQUALITY_OPS(a0, c0, true);
+ QT_TEST_EQUALITY_OPS(a0, r1, false);
+
#undef CHECK
#undef CHECK_IMPL
}
@@ -1011,17 +1112,20 @@ void tst_QtJson::testObjectIteration()
for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it) {
QJsonValue value = it.value();
QCOMPARE((double)it.key().toInt(), value.toDouble());
+ QT_TEST_EQUALITY_OPS(it, QJsonObject::iterator(), false);
}
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonValue val = *object2.begin();
auto next = object2.erase(object2.begin());
QCOMPARE(object.size(), 10);
QCOMPARE(object2.size(), 9);
QVERIFY(next == object2.begin());
+ QT_TEST_EQUALITY_OPS(next, object2.begin(), true);
double d = 1; // we erased the first item
for (auto it = object2.constBegin(); it != object2.constEnd(); ++it, d += 1) {
@@ -1036,6 +1140,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonValue val = *(object2.end() - 1);
auto next = object2.erase(object2.end() - 1);
@@ -1055,6 +1160,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonObject::iterator it = object2.find(QString::number(5));
QJsonValue val = *it;
@@ -1078,6 +1184,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject::Iterator it = object.begin();
it += 5;
+ QT_TEST_ALL_COMPARISON_OPS(it, object.begin(), Qt::strong_ordering::greater);
QCOMPARE(QJsonValue(it.value()).toDouble(), 5.);
it -= 3;
QCOMPARE(QJsonValue(it.value()).toDouble(), 2.);
@@ -1092,10 +1199,14 @@ void tst_QtJson::testObjectIteration()
it += 5;
QCOMPARE(QJsonValue(it.value()).toDouble(), 5.);
it -= 3;
+ QT_TEST_ALL_COMPARISON_OPS(object.constBegin(), it, Qt::strong_ordering::less);
QCOMPARE(QJsonValue(it.value()).toDouble(), 2.);
QJsonObject::ConstIterator it2 = it + 5;
+ QT_TEST_EQUALITY_OPS(it, it2, false);
QCOMPARE(QJsonValue(it2.value()).toDouble(), 7.);
it2 = it - 1;
+ QT_TEST_ALL_COMPARISON_OPS(it2, it, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it2, it - 2, Qt::strong_ordering::greater);
QCOMPARE(QJsonValue(it2.value()).toDouble(), 1.);
}
@@ -1104,6 +1215,17 @@ void tst_QtJson::testObjectIteration()
it = object.erase(it);
QCOMPARE(object.size() , 0);
QCOMPARE(it, object.end());
+ QT_TEST_ALL_COMPARISON_OPS(it, object.end(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(it, object.constEnd(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(it, object.begin(),
+ Qt::strong_ordering::equal); // because object is empty
+ QT_TEST_ALL_COMPARISON_OPS(it, object.constBegin(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::Iterator(),
+ QJsonObject::Iterator(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(),
+ QJsonObject::Iterator(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(),
+ QJsonObject::ConstIterator(), Qt::strong_ordering::equal);
}
void tst_QtJson::testArrayIteration()
@@ -1117,7 +1239,11 @@ void tst_QtJson::testArrayIteration()
int i = 0;
for (QJsonArray::iterator it = array.begin(); it != array.end(); ++it, ++i) {
QJsonValue value = (*it);
+ QJsonArray::iterator it1 = it;
QCOMPARE((double)i, value.toDouble());
+ QT_TEST_EQUALITY_OPS(QJsonArray::iterator(), QJsonArray::iterator(), true);
+ QT_TEST_EQUALITY_OPS(QJsonArray::iterator(), it, false);
+ QT_TEST_EQUALITY_OPS(it1, it, true);
}
QCOMPARE(array.begin()->toDouble(), array.constBegin()->toDouble());
@@ -1172,6 +1298,13 @@ void tst_QtJson::testArrayIteration()
QCOMPARE(QJsonValue(*it2).toDouble(), 7.);
it2 = it - 1;
QCOMPARE(QJsonValue(*it2).toDouble(), 1.);
+ QT_TEST_EQUALITY_OPS(it, it2, false);
+ it = array.begin();
+ QT_TEST_EQUALITY_OPS(it, array.begin(), true);
+ it2 = it + 5;
+ QT_TEST_ALL_COMPARISON_OPS(it2, it, Qt::strong_ordering::greater);
+ it += 5;
+ QT_TEST_EQUALITY_OPS(it, it2, true);
}
{
@@ -1191,6 +1324,26 @@ void tst_QtJson::testArrayIteration()
it = array.erase(it);
QCOMPARE(array.size() , 0);
QCOMPARE(it, array.end());
+ QT_TEST_EQUALITY_OPS(it, array.end(), true);
+
+ {
+ int i = 0;
+ for (QJsonArray::const_iterator it = array.constBegin();
+ it != array.constEnd(); ++it, ++i) {
+ QJsonArray::const_iterator it1 = it;
+ QT_TEST_EQUALITY_OPS(QJsonArray::const_iterator(), QJsonArray::const_iterator(), true);
+ QT_TEST_EQUALITY_OPS(QJsonArray::const_iterator(), it, false);
+ QT_TEST_EQUALITY_OPS(it1, it, true);
+ }
+ }
+
+ {
+ QJsonArray::iterator nonConstIt = array.begin();
+ QJsonArray::const_iterator it = array.constBegin();
+ QT_TEST_EQUALITY_OPS(nonConstIt, it, true);
+ it+=1;
+ QT_TEST_ALL_COMPARISON_OPS(nonConstIt, it, Qt::strong_ordering::less);
+ }
}
void tst_QtJson::testObjectFind()
@@ -1284,6 +1437,8 @@ void tst_QtJson::testDocument()
QCOMPARE(doc5.isObject(), false);
QCOMPARE(doc5.array().size(), 1);
QCOMPARE(doc5.array().at(0), QJsonValue(23));
+
+ QT_TEST_EQUALITY_OPS(doc2, doc3, true);
}
void tst_QtJson::nullValues()
@@ -1655,7 +1810,8 @@ void tst_QtJson::fromVariantHash()
void tst_QtJson::toVariantMap()
{
- QCOMPARE(QMetaType::Type(QJsonValue(QJsonObject()).toVariant().type()), QMetaType::QVariantMap); // QTBUG-32524
+ QCOMPARE(QMetaType::Type(QJsonValue(QJsonObject()).toVariant().typeId()),
+ QMetaType::QVariantMap); // QTBUG-32524
QJsonObject object;
QVariantMap map = object.toVariantMap();
@@ -1675,7 +1831,7 @@ void tst_QtJson::toVariantMap()
QCOMPARE(map.size(), 3);
QCOMPARE(map.value("Key"), QVariant(QString("Value")));
QCOMPARE(map.value("null"), QVariant::fromValue(nullptr));
- QCOMPARE(map.value("Array").type(), QVariant::List);
+ QCOMPARE(map.value("Array").typeId(), QMetaType::QVariantList);
QVariantList list = map.value("Array").toList();
QCOMPARE(list.size(), 4);
QCOMPARE(list.at(0), QVariant(true));
@@ -1704,7 +1860,7 @@ void tst_QtJson::toVariantHash()
QCOMPARE(hash.size(), 3);
QCOMPARE(hash.value("Key"), QVariant(QString("Value")));
QCOMPARE(hash.value("null"), QVariant::fromValue(nullptr));
- QCOMPARE(hash.value("Array").type(), QVariant::List);
+ QCOMPARE(hash.value("Array").typeId(), QMetaType::QVariantList);
QVariantList list = hash.value("Array").toList();
QCOMPARE(list.size(), 4);
QCOMPARE(list.at(0), QVariant(true));
@@ -1715,7 +1871,8 @@ void tst_QtJson::toVariantHash()
void tst_QtJson::toVariantList()
{
- QCOMPARE(QMetaType::Type(QJsonValue(QJsonArray()).toVariant().type()), QMetaType::QVariantList); // QTBUG-32524
+ QCOMPARE(QMetaType::Type(QJsonValue(QJsonArray()).toVariant().typeId()),
+ QMetaType::QVariantList); // QTBUG-32524
QJsonArray array;
QVariantList list = array.toVariantList();
@@ -1735,7 +1892,7 @@ void tst_QtJson::toVariantList()
QCOMPARE(list.size(), 3);
QCOMPARE(list[0], QVariant(QString("Value")));
QCOMPARE(list[1], QVariant::fromValue(nullptr));
- QCOMPARE(list[2].type(), QVariant::List);
+ QCOMPARE(list[2].typeId(), QMetaType::QVariantList);
QVariantList vlist = list[2].toList();
QCOMPARE(vlist.size(), 4);
QCOMPARE(vlist.at(0), QVariant(true));
@@ -2419,7 +2576,7 @@ void tst_QtJson::parseDuplicateKeys()
void tst_QtJson::testParser()
{
QFile file(testDataDir + "/test.json");
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray testJson = file.readAll();
QJsonDocument doc = QJsonDocument::fromJson(testJson);
@@ -2475,6 +2632,13 @@ void tst_QtJson::testCompaction()
}
QCOMPARE(obj.size(), 1);
QCOMPARE(obj.value(QLatin1String("foo")).toString(), QLatin1String("bar"));
+
+ QJsonObject obj2;
+
+ QT_TEST_EQUALITY_OPS(obj, obj2, false);
+ QT_TEST_EQUALITY_OPS(QJsonObject(), obj2, true);
+ obj2 = obj;
+ QT_TEST_EQUALITY_OPS(obj, obj2, true);
}
void tst_QtJson::testDebugStream()
@@ -2754,57 +2918,57 @@ void tst_QtJson::testDetachBug()
void tst_QtJson::valueEquals()
{
QCOMPARE(QJsonValue(), QJsonValue());
- QVERIFY(QJsonValue() != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue() != QJsonValue(true));
- QVERIFY(QJsonValue() != QJsonValue(1.));
- QVERIFY(QJsonValue() != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue() != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(true), QJsonValue(true));
- QVERIFY(QJsonValue(true) != QJsonValue(false));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(true) != QJsonValue());
- QVERIFY(QJsonValue(true) != QJsonValue(1.));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(false), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(1), QJsonValue(1));
- QVERIFY(QJsonValue(1) != QJsonValue(2));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(2), false);
QCOMPARE(QJsonValue(1), QJsonValue(1.));
- QVERIFY(QJsonValue(1) != QJsonValue(1.1));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(1) != QJsonValue());
- QVERIFY(QJsonValue(1) != QJsonValue(true));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(1.1), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(1.), QJsonValue(1.));
- QVERIFY(QJsonValue(1.) != QJsonValue(2.));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(1.) != QJsonValue());
- QVERIFY(QJsonValue(1.) != QJsonValue(true));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(2.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(QJsonArray()), QJsonValue(QJsonArray()));
QJsonArray nonEmptyArray;
nonEmptyArray.append(true);
- QVERIFY(QJsonValue(QJsonArray()) != nonEmptyArray);
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue());
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(true));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(1.));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), nonEmptyArray, false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(QJsonObject()), QJsonValue(QJsonObject()));
QJsonObject nonEmptyObject;
nonEmptyObject.insert("Key", true);
- QVERIFY(QJsonValue(QJsonObject()) != nonEmptyObject);
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue());
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(true));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(1.));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonArray()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), nonEmptyObject, false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonArray()), false);
QCOMPARE(QJsonValue("foo"), QJsonValue(QLatin1String("foo")));
QCOMPARE(QJsonValue("foo"), QJsonValue(QString("foo")));
@@ -2997,7 +3161,7 @@ void tst_QtJson::documentEquals()
void tst_QtJson::bom()
{
QFile file(testDataDir + "/bom.json");
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray json = file.readAll();
// Import json document into a QJsonDocument
@@ -3318,7 +3482,7 @@ void tst_QtJson::documentFromVariant()
// As JSON arrays they should be equal.
QCOMPARE(da1.array(), da2.array());
-
+ QT_TEST_EQUALITY_OPS(da1, da2, true);
QMap <QString, QVariant> map;
map["key"] = string;
@@ -3334,6 +3498,7 @@ void tst_QtJson::documentFromVariant()
// As JSON objects they should be equal.
QCOMPARE(do1.object(), do2.object());
+ QT_TEST_EQUALITY_OPS(do1, do2, true);
}
void tst_QtJson::parseErrorOffset_data()
@@ -3432,6 +3597,7 @@ void tst_QtJson::streamSerializationQJsonDocument()
QDataStream load(buffer);
load >> output;
QCOMPARE(output, document);
+ QT_TEST_EQUALITY_OPS(output, document, true);
}
void tst_QtJson::streamSerializationQJsonArray_data()
@@ -3821,6 +3987,7 @@ void tst_QtJson::noLeakOnNameClash()
QVERIFY2(!expected.isNull(), qPrintable(error.errorString()));
QCOMPARE(doc, expected);
+ QT_TEST_EQUALITY_OPS(doc, expected, true);
// It should not leak.
// In particular it should not forget to deref the container for the inner objects.
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt
index 276474ba37..29a935977b 100644
--- a/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt
@@ -1,15 +1,22 @@
-# Generated from qcborstreamreader.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcborstreamreader Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborstreamreader LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcborstreamreader
SOURCES
tst_qcborstreamreader.cpp
INCLUDE_DIRECTORIES
../../../../../src/3rdparty/tinycbor/src
- ../../../../../src/3rdparty/tinycbor/tests/parser
- PUBLIC_LIBRARIES
+ ../../../../../src/3rdparty/tinycbor/tests
+ LIBRARIES
Qt::CorePrivate
)
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
index afd02dc6b7..63cfbce75f 100644
--- a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
+++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
@@ -1,12 +1,10 @@
// Copyright (C) 2020 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborstream.h>
#include <QTest>
#include <QBuffer>
-#include <QtCore/private/qbytearray_p.h>
-
class tst_QCborStreamReader : public QObject
{
Q_OBJECT
@@ -88,7 +86,7 @@ template<> char *toString<QCborStreamReader::Type>(const QCborStreamReader::Type
QT_END_NAMESPACE
// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
-#include "data.cpp"
+#include "parser/data.cpp"
void tst_QCborStreamReader::initTestCase_data()
{
@@ -657,6 +655,7 @@ void tst_QCborStreamReader::strings()
QCOMPARE(reader.currentStringChunkSize(), qsizetype(reader.length()));
int chunks = 0;
+ QByteArray fullString;
forever {
QCborStreamReader::StringResult<QByteArray> controlData;
if (reader.isString()) {
@@ -667,6 +666,7 @@ void tst_QCborStreamReader::strings()
controlData = controlReader.readByteArray();
}
QVERIFY(controlData.status != QCborStreamReader::Error);
+ fullString += controlData.data;
for (int i = 0; i < 10; ++i) {
// this call must work several times with the same result
@@ -689,6 +689,43 @@ void tst_QCborStreamReader::strings()
if (!isChunked)
QCOMPARE(chunks, 1);
+
+ // Now re-do and compare with toString() and toByteArray(), against
+ // the control data we calculated above
+ reader.reset();
+ QVERIFY(reader.isString() || reader.isByteArray());
+ if (reader.isByteArray()) {
+ QByteArray prefix("some prefix");
+ QByteArray ba = prefix;
+ QVERIFY(reader.readAndAppendToByteArray(ba));
+ QCOMPARE(ba, prefix + fullString);
+ } else {
+ QString prefix("some prefix");
+ QString str = prefix;
+ QVERIFY(reader.readAndAppendToString(str));
+ QCOMPARE(str, prefix + QString::fromUtf8(fullString));
+ }
+
+ // Re-do again using the UTF-8 interface.
+ reader.reset();
+ QVERIFY(reader.isString() || reader.isByteArray());
+ if (reader.isString()) {
+ QByteArray prefix("some prefix");
+ QByteArray utf8 = prefix;
+ QVERIFY(reader.readAndAppendToUtf8String(utf8));
+ QCOMPARE(utf8, prefix + fullString);
+
+ reader.reset();
+ fullString = prefix;
+ forever {
+ auto r = reader.readUtf8String();
+ QCOMPARE_NE(r.status, QCborStreamReader::Error);
+ fullString += r.data;
+ if (r.status == QCborStreamReader::EndOfString)
+ break;
+ }
+ QCOMPARE(fullString, utf8);
+ }
}
void tst_QCborStreamReader::tags_data()
@@ -881,7 +918,7 @@ void tst_QCborStreamReader::validation_data()
// Add QCborStreamReader-specific limitations due to use of QByteArray and
// QString, which are allocated by QArrayData::allocate().
const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max();
- const qsizetype MinInvalid = MaxByteArraySize + 1;
+ const qsizetype MinInvalid = QByteArray::max_size() + 1;
addValidationColumns();
addValidationData(MinInvalid);
@@ -908,11 +945,57 @@ void tst_QCborStreamReader::validation()
reader.reset();
QVERIFY(!reader.next());
QCOMPARE(reader.lastError(), error);
+
+ // check toString() and toByteArray() too
+ if (reader.isString() || reader.isByteArray()) {
+ reader.reset();
+ if (reader.isString()) {
+ QString prefix = "some prefix";
+ QString str = prefix;
+ QVERIFY(!reader.readAndAppendToString(str));
+ QVERIFY(str.startsWith(prefix)); // but may have decoded some
+ } else if (reader.isByteArray()) {
+ QByteArray prefix = "some prefix";
+ QByteArray ba = prefix;
+ QVERIFY(!reader.readAndAppendToByteArray(ba));
+ QVERIFY(ba.startsWith(prefix)); // but may have decoded some
+ }
+ QCOMPARE(reader.lastError(), error);
+
+ reader.reset();
+ if (reader.isString())
+ QVERIFY(reader.readAllString().isNull());
+ else
+ QVERIFY(reader.readAllByteArray().isNull());
+ }
+
+ reader.reset();
+
+ // and the UTF-8 API
+ if (reader.isString()) {
+ QByteArray prefix = "some prefix";
+ QByteArray ba = prefix;
+ QVERIFY(!reader.readAndAppendToUtf8String(ba));
+ QVERIFY(ba.startsWith(prefix)); // but may have decoded some
+ QCOMPARE(reader.lastError(), error);
+
+ reader.reset();
+ QVERIFY(reader.readAllUtf8String().isNull());
+
+ reader.reset();
+ auto r = reader.readUtf8String();
+ for ( ; r.status == QCborStreamReader::Ok; r = reader.readUtf8String()) {
+ // while the data is valid...
+ QVERIFY(!r.data.isNull());
+ }
+ QCOMPARE_NE(r.status, QCborStreamReader::EndOfString);
+ QCOMPARE(reader.lastError(), error);
+ }
}
void tst_QCborStreamReader::hugeDeviceValidation_data()
{
- addValidationHugeDevice(MaxByteArraySize + 1, MaxStringSize + 1);
+ addValidationHugeDevice(QByteArray::max_size() + 1, QString::max_size() + 1);
}
void tst_QCborStreamReader::hugeDeviceValidation()
@@ -927,6 +1010,10 @@ void tst_QCborStreamReader::hugeDeviceValidation()
QSKIP("This test tries to allocate a huge memory buffer,"
" which Address Sanitizer flags as a problem");
#endif
+#if defined(Q_OS_WASM)
+ QSKIP("This test tries to allocate a huge memory buffer,"
+ " causes problem on WebAssembly platform which has limited resources.");
+#endif // Q_OS_WASM
QFETCH(QSharedPointer<QIODevice>, device);
QFETCH(CborError, expectedError);
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt b/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt
index 2796dc214c..c1a9a87677 100644
--- a/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qcborstreamwriter.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcborstreamwriter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborstreamwriter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcborstreamwriter
SOURCES
tst_qcborstreamwriter.cpp
INCLUDE_DIRECTORIES
- ../../../../../src/3rdparty/tinycbor/tests/encoder
+ ../../../../../src/3rdparty/tinycbor/tests
)
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
index 5651cc3987..45e241ef5c 100644
--- a/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QCborStreamWriter>
@@ -29,7 +29,7 @@ private Q_SLOTS:
// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/encoder/data.cpp)
typedef quint64 CborTag;
-#include "data.cpp"
+#include "encoder/data.cpp"
void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
{
@@ -81,9 +81,9 @@ void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
list = v.value<IndeterminateLengthArray>();
writer.startArray();
} else {
- writer.startArray(list.length());
+ writer.startArray(list.size());
}
- for (const QVariant &v2 : qAsConst(list))
+ for (const QVariant &v2 : std::as_const(list))
encodeVariant(writer, v2);
QVERIFY(writer.endArray());
return;
@@ -94,9 +94,9 @@ void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
map = v.value<IndeterminateLengthMap>();
writer.startMap();
} else {
- writer.startMap(map.length());
+ writer.startMap(map.size());
}
- for (auto pair : qAsConst(map)) {
+ for (auto pair : std::as_const(map)) {
encodeVariant(writer, pair.first);
encodeVariant(writer, pair.second);
}
diff --git a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt
index 9233888671..4b72396489 100644
--- a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt
@@ -1,15 +1,23 @@
-# Generated from qcborvalue.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcborvalue Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborvalue LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcborvalue
SOURCES
tst_qcborvalue.cpp
INCLUDE_DIRECTORIES
../../../../../src/3rdparty/tinycbor/src
../../../../../src/3rdparty/tinycbor/tests/parser
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
+ Qt::TestPrivate
)
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index 6c128016ba..23b25834b9 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -1,19 +1,23 @@
// Copyright (C) 2022 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborvalue.h>
#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
#include <QBuffer>
#include <QCborStreamReader>
#include <QCborStreamWriter>
+#include <QDateTime>
#include <QtEndian>
-
-#include <QtCore/private/qbytearray_p.h>
+#include <QTimeZone>
Q_DECLARE_METATYPE(QCborKnownTags)
Q_DECLARE_METATYPE(QCborValue)
Q_DECLARE_METATYPE(QCborValue::EncodingOptions)
+using namespace Qt::StringLiterals;
+
class tst_QCborValue : public QObject
{
Q_OBJECT
@@ -25,6 +29,7 @@ private slots:
void tagged();
void extendedTypes_data();
void extendedTypes();
+ void compareCompiles();
void copyCompare_data() { basics_data(); }
void copyCompare();
@@ -75,7 +80,10 @@ private slots:
void mapComplexKeys();
void mapNested();
+ void sorting_data();
void sorting();
+ void comparisonMap_data();
+ void comparisonMap();
void toCbor_data();
void toCbor();
@@ -389,7 +397,7 @@ void tst_QCborValue::extendedTypes_data()
QTest::addColumn<QCborValue>("correctedTaggedValue");
QCborValue v(QCborValue::Invalid);
QDateTime dt = QDateTime::currentDateTimeUtc();
- QDateTime dtTzOffset(dt.date(), dt.time(), Qt::OffsetFromUTC, dt.offsetFromUtc());
+ QDateTime dtTzOffset(dt.date(), dt.time(), QTimeZone::fromSecondsAheadOfUtc(dt.offsetFromUtc()));
QUuid uuid = QUuid::createUuid();
// non-correcting extended types (tagged value remains unchanged)
@@ -413,7 +421,7 @@ void tst_QCborValue::extendedTypes_data()
<< QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v;
// correcting extended types
- QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), Qt::UTC);
+ QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), QTimeZone::UTC);
QUrl url("https://example.com/\xc2\xa9 ");
QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t
<< QCborValue(dtNoMsecs.toSecsSinceEpoch())
@@ -424,10 +432,11 @@ void tst_QCborValue::extendedTypes_data()
QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {}))
<< QCborKnownTags::DateTimeString
<< QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000");
- QTest::newRow("DateTime::TzOffset") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC))
- << QCborKnownTags::DateTimeString
- << QCborValue("2018-01-01T09:00:00.000+00:00")
- << QCborValue("2018-01-01T09:00:00.000Z");
+ QTest::newRow("DateTime::TzOffset")
+ << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
+ << QCborKnownTags::DateTimeString
+ << QCborValue("2018-01-01T09:00:00.000+00:00")
+ << QCborValue("2018-01-01T09:00:00.000Z");
QTest::newRow("Url:NotNormalized") << QCborValue(url) << QCborKnownTags::Url
<< QCborValue("HTTPS://EXAMPLE.COM/%c2%a9%20")
<< QCborValue(url.toString());
@@ -442,6 +451,35 @@ void tst_QCborValue::extendedTypes_data()
<< QCborValue(uuid.toRfc4122() + "\1\2\3\4") << QCborValue(uuid.toRfc4122());
}
+void tst_QCborValue::compareCompiles()
+{
+ // homogeneous types
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::ConstIterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::Iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::ConstIterator>();
+
+ // QCborValue, Ref and ConstRef
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueConstRef, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef, QCborValue>();
+
+ // QCbor{Array,Map} <=> QCborValue{,Ref,ConstRef}
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator,
+ QCborArray::ConstIterator>();
+}
+
void tst_QCborValue::extendedTypes()
{
QFETCH(QCborValue, extended);
@@ -469,9 +507,13 @@ void tst_QCborValue::copyCompare()
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wself-move")
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301
+QT_WARNING_DISABLE_GCC("-Wself-move")
+#endif
// self-moving
v = std::move(v);
QCOMPARE(v, other); // make sure it's still valid
+ QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal);
QT_WARNING_POP
// moving
@@ -483,24 +525,15 @@ QT_WARNING_POP
other = v;
v = other;
-
QCOMPARE(v.compare(other), 0);
- QCOMPARE(v, other);
- QVERIFY(!(v != other));
- QVERIFY(!(v < other));
-#if 0 && __has_include(<compare>)
- QVERIFY(v <= other);
- QVERIFY(v >= other);
- QVERIFY(!(v > other));
-#endif
+ QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal);
if (v.isUndefined())
other = nullptr;
else
other = {};
QVERIFY(v.type() != other.type());
- QVERIFY(!(v == other));
- QVERIFY(v != other);
+ QT_TEST_EQUALITY_OPS(v, other, false);
// they're different types, so they can't compare equal
QVERIFY(v.compare(other) != 0);
@@ -530,9 +563,8 @@ void tst_QCborValue::arrayDefaultInitialization()
QVERIFY(a.at(0).isUndefined());
QCOMPARE(a.constBegin(), a.constEnd());
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
QCborValue v(a);
QVERIFY(v.isArray());
@@ -541,7 +573,7 @@ void tst_QCborValue::arrayDefaultInitialization()
QCborArray a2 = v.toArray();
QVERIFY(a2.isEmpty());
- QCOMPARE(a2, a);
+ QT_TEST_EQUALITY_OPS(a2, a, true);
auto front = v[0];
QVERIFY(front.isUndefined());
front = 1;
@@ -581,9 +613,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());
@@ -596,7 +627,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()
@@ -604,9 +635,8 @@ void tst_QCborValue::arrayEmptyInitializerList()
QCborArray a{};
QVERIFY(a.isEmpty());
QCOMPARE(a.size(), 0);
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
}
void tst_QCborValue::mapEmptyInitializerList()
@@ -614,9 +644,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()
@@ -626,9 +655,8 @@ void tst_QCborValue::arrayEmptyDetach()
QVERIFY(a.isEmpty());
QCOMPARE(a.size(), 0);
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
QCborValue v(a);
QVERIFY(v.isArray());
@@ -647,9 +675,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());
@@ -658,7 +685,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()
@@ -719,6 +746,13 @@ void tst_QCborValue::mapNonEmptyDetach()
{ QCborMap copy(m); auto it = m.find(QLatin1String("3")); QVERIFY(it == m.end()); }
{ QCborMap copy(m); auto it = m.find(QString("3")); QVERIFY(it == m.end()); }
{ QCborMap copy(m); auto it = m.find(QCborValue(3)); QVERIFY(it == m.end()); }
+
+ QT_TEST_EQUALITY_OPS(m.constBegin(), m.constEnd(), false);
+ QT_TEST_EQUALITY_OPS(m.begin(), m.end(), false);
+ QT_TEST_EQUALITY_OPS(m.constFind(3), m.constEnd(), true);
+ QT_TEST_EQUALITY_OPS(m.find(3), m.end(), true);
+ QT_TEST_EQUALITY_OPS(m.find(3), m.constEnd(), true);
+ QT_TEST_EQUALITY_OPS(m.constFind(3), m.end(), true);
}
void tst_QCborValue::arrayInitializerList()
@@ -734,10 +768,9 @@ void tst_QCborValue::arrayInitializerList()
QCOMPARE(a.at(5), QCborValue(QCborValue::Undefined));
QCOMPARE(a.at(6), QCborValue(1.0));
- QVERIFY(a == a);
- QVERIFY(a != QCborArray{});
- QVERIFY(QCborArray{} != a);
- QVERIFY(a == QCborArray({0, -1, false, true, nullptr, {}, 1.0}));
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray{}, false);
+ QT_TEST_EQUALITY_OPS(a, QCborArray({0, -1, false, true, nullptr, {}, 1.0}), true);
QCborValue v = a;
QCOMPARE(v[0], QCborValue(0));
@@ -766,12 +799,17 @@ void tst_QCborValue::arrayInitializerList()
// iterators
auto it = a.constBegin();
auto end = a.constEnd();
+ QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less);
QCOMPARE(end - it, 7);
QCOMPARE(it + 7, end);
+ QT_TEST_EQUALITY_OPS(it + 7, end, true);
QVERIFY(it->isInteger());
QCOMPARE(*it, QCborValue(0));
QCOMPARE(it[1], QCborValue(-1));
QCOMPARE(*(it + 2), QCborValue(false));
+ QT_TEST_EQUALITY_OPS(*it, QCborValue(0), true);
+ QT_TEST_EQUALITY_OPS(it[1], QCborValue(-1), true);
+ QT_TEST_EQUALITY_OPS(*(it + 2), QCborValue(false), true);
it += 3;
QCOMPARE(*it, QCborValue(true));
++it;
@@ -782,10 +820,28 @@ void tst_QCborValue::arrayInitializerList()
QCOMPARE(*end, QCborValue(1.0));
end--;
QCOMPARE(it, end);
+ QT_TEST_EQUALITY_OPS(it, end, true);
+ QT_TEST_EQUALITY_OPS(it, QCborArray::ConstIterator(), false);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), end, false);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::ConstIterator(), true);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::Iterator(), true);
+
+ {
+ auto it = a.begin();
+ auto it1 = a.constBegin();
+ auto end = a.end();
+ QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it1, end, Qt::strong_ordering::less);
+ QT_TEST_EQUALITY_OPS(it + 7, end, true);
+ QT_TEST_EQUALITY_OPS(it1 + 7, end, true);
+ QT_TEST_EQUALITY_OPS(it, QCborArray::Iterator(), false);
+ QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), end, false);
+ QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), QCborArray::ConstIterator(), true);
+ }
// range for
int i = 0;
- for (const QCborValue v : qAsConst(a)) {
+ for (const QCborValue v : std::as_const(a)) {
QVERIFY(!v.isInvalid());
QCOMPARE(v.isUndefined(), i == 5); // 6th element is Undefined
++i;
@@ -797,10 +853,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;
{
@@ -885,7 +940,7 @@ void tst_QCborValue::mapSimpleInitializerList()
// range for
int i = 0;
- for (auto pair : qAsConst(m)) {
+ for (auto pair : std::as_const(m)) {
QVERIFY(!pair.first.isUndefined());
QVERIFY(!pair.second.isUndefined());
++i;
@@ -900,11 +955,6 @@ template <typename T> static void mapFromArray_template(T key)
if (v.isMap())
return; // already a map, nothing will happen
- auto ignoreMessage = [type]() {
- if (type == QCborValue::Array)
- QTest::ignoreMessage(QtWarningMsg, "Using CBOR array as map forced conversion");
- };
-
// verify forced conversions work
// (our only Array row is an empty array, so it doesn't produce the warning)
QCborValue v2 = v;
@@ -918,7 +968,7 @@ template <typename T> static void mapFromArray_template(T key)
// non-empty array conversions
QCborValue va = QCborArray{v};
v2 = va;
- ignoreMessage();
+ QTest::ignoreMessage(QtWarningMsg, "Using CBOR array as map forced conversion");
QVERIFY(v2[key].isUndefined());
QCOMPARE(v2.type(), QCborValue::Map);
QCOMPARE(va.type(), QCborValue::Array);
@@ -965,8 +1015,8 @@ void tst_QCborValue::arrayMutation()
QVERIFY(v == a.at(0));
}
- QVERIFY(a == a);
- QVERIFY(a == QCborArray{true});
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray{true}, true);
QCborArray a2 = a;
a.append(nullptr);
@@ -1088,27 +1138,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());
- QCOMPARE(v, QCborArray({1, 2, 3}));
- QCOMPARE(m, QCborMap({{42, QCborArray{1, 2, 3}}}));
+ QT_TEST_EQUALITY_OPS(v, QCborArray({1, 2, 3}), true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{42, QCborArray{1, 2, 3}}}), true);
// container -> simple
v = true;
@@ -1116,8 +1166,7 @@ void tst_QCborValue::mapMutation()
QVERIFY(v.isTrue());
QCOMPARE(m, QCborMap({{42, true}}));
QVERIFY(m.begin()->isTrue());
- QVERIFY(m.begin().value() == v);
- QVERIFY(v == m.begin().value());
+ QT_TEST_EQUALITY_OPS(m.begin().value(), v, true);
}
QVERIFY(m == QCborMap({{42, true}}));
@@ -1139,18 +1188,27 @@ void tst_QCborValue::mapMutation()
m2 = m;
auto it = m.begin(); // detaches again
auto end = m.end();
+ auto it1 = m.constBegin(); // detaches again
+ auto end2 = m.constEnd();
QCOMPARE(end - it, 2);
+ QT_TEST_ALL_COMPARISON_OPS(it, it + 1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it, it1 + 1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it, it - 1, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(it, it1 - 1, Qt::strong_ordering::greater);
+ QT_TEST_EQUALITY_OPS(it, it1, true);
QCOMPARE(it + 2, end);
- QCOMPARE(it.key(), QCborValue(42));
- QCOMPARE(it.value(), QCborValue(2.5));
- QCOMPARE((++it).value(), QCborValue(nullptr));
- QCOMPARE(it.key(), QCborValue(nullptr));
- QVERIFY(m2 == m);
- QVERIFY(m == m2);
+ QT_TEST_EQUALITY_OPS(it + 2, end, true);
+ QT_TEST_EQUALITY_OPS(it + 2, end2, true);
+ QT_TEST_EQUALITY_OPS(it1 + 2, end2, true);
+ QT_TEST_EQUALITY_OPS(it.key(), QCborValue(42), true);
+ 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);
+ 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);
@@ -1197,11 +1255,13 @@ void tst_QCborValue::mapMutateWithCopies()
// see QTBUG-83366
QCborMap map;
map[QLatin1String("value")] = "TEST";
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("value")], "TEST", true);
QCOMPARE(map.size(), 1);
QCOMPARE(map.value("value"), "TEST");
QCborValue v = map.value("value");
map[QLatin1String("prop2")] = v;
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("prop2")], v, true);
QCOMPARE(map.size(), 2);
QCOMPARE(map.value("value"), "TEST");
QCOMPARE(map.value("prop2"), "TEST");
@@ -1215,6 +1275,7 @@ void tst_QCborValue::mapMutateWithCopies()
// same as previous, but this is a QJsonValueRef
QCborValueRef rv = map[QLatin1String("prop2")];
rv = map[QLatin1String("value")];
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("value")], rv, true);
QCOMPARE(map.size(), 2);
QCOMPARE(map.value("value"), "TEST");
QCOMPARE(map.value("prop2"), "TEST");
@@ -1229,6 +1290,7 @@ void tst_QCborValue::mapMutateWithCopies()
// after we create the source QCborValueRef
QCborValueRef rv = map[QLatin1String("value")];
map[QLatin1String("prop2")] = rv;
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("prop2")], rv, true);
QCOMPARE(map.size(), 2);
QCOMPARE(map.value("value"), "TEST");
QCOMPARE(map.value("prop2"), "TEST");
@@ -1255,8 +1317,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);
}
@@ -1266,17 +1328,19 @@ 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]);
+ QT_TEST_EQUALITY_OPS(a.first(), v, true);
+ QT_TEST_EQUALITY_OPS(a.last(), v, true);
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());
@@ -1294,17 +1358,17 @@ void tst_QCborValue::arrayValueRefLargeKey()
a[LargeKey + 1] = 123;
QCborValue v(a);
- QCOMPARE(qAsConst(v)[LargeKey], QCborValue());
- QCOMPARE(qAsConst(v)[LargeKey + 1], 123);
- QCOMPARE(v[LargeKey], QCborValue());
+ QT_TEST_EQUALITY_OPS(std::as_const(v)[LargeKey], QCborValue(), true);
+ QCOMPARE(std::as_const(v)[LargeKey + 1], 123);
+ 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(qAsConst(ref)[LargeKey], QCborValue());
- QCOMPARE(qAsConst(ref)[LargeKey + 1], 123);
- QCOMPARE(ref[LargeKey], QCborValue());
+ QT_TEST_EQUALITY_OPS(std::as_const(ref)[LargeKey], QCborValue(), true);
+ QCOMPARE(std::as_const(ref)[LargeKey + 1], 123);
+ QT_TEST_EQUALITY_OPS(ref[LargeKey], QCborValue(), true);
QCOMPARE(ref[LargeKey + 1], 123);
QCOMPARE(ref.type(), QCborValue::Array);
}
@@ -1321,9 +1385,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]);
@@ -1356,28 +1420,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());
}
@@ -1386,14 +1450,15 @@ void tst_QCborValue::arrayStringElements()
QCborArray a{"Hello"};
a.append(QByteArray("Hello"));
a.append(QLatin1String("World"));
- QVERIFY(a == a);
- QVERIFY(a == QCborArray({QLatin1String("Hello"),
- QByteArray("Hello"), QStringLiteral("World")}));
+
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray({QLatin1String("Hello"),
+ QByteArray("Hello"), QStringLiteral("World")}), true);
QCborValueRef r1 = a[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 = a.at(1);
QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
@@ -1402,11 +1467,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");
@@ -1418,12 +1483,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"));
@@ -1432,7 +1497,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");
@@ -1450,14 +1515,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());
@@ -1475,8 +1538,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);
@@ -1489,10 +1551,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));
@@ -1513,12 +1573,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());
}
@@ -1532,13 +1592,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());
}
@@ -1567,7 +1627,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);
}
}
@@ -1585,12 +1645,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));
}
@@ -1602,14 +1662,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}};
@@ -1633,8 +1693,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);
}
}
@@ -1713,57 +1773,73 @@ void tst_QCborValue::arrayNested()
{
QCborArray a1 = { 42, 47 };
QCborArray a2 = { QCborValue(a1) };
+ QCborArray a3 = { 41, 47 };
+ QCborArray a4 = { 41, 47, 87 };
QCOMPARE(a2.size(), 1);
- const QCborValue &first = qAsConst(a2).first();
+ const QCborValue &first = std::as_const(a2).first();
QVERIFY(first.isArray());
QCOMPARE(first.toArray(wrongArray).size(), 2);
QCOMPARE(first.toArray(wrongArray).first(), 42);
QCOMPARE(first.toArray(wrongArray).last(), 47);
+ QT_TEST_ALL_COMPARISON_OPS(a1, a3, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a4, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a2, Qt::strong_ordering::greater);
}
{
QCborArray a1 = { 42, 47 };
QCborArray a2 = { QCborValue(a1) };
+ QCborArray a3 = { 41, 47 };
+ QCborArray a4 = { 41, 47, 87 };
QCOMPARE(a2.size(), 1);
QCborValueRef first = a2.first();
QVERIFY(first.isArray());
QCOMPARE(first.toArray(wrongArray).size(), 2);
QCOMPARE(first.toArray(wrongArray).first(), 42);
QCOMPARE(first.toArray(wrongArray).last(), 47);
+ QT_TEST_ALL_COMPARISON_OPS(a1, a3, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a4, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a2, Qt::strong_ordering::greater);
}
{
QCborArray a1;
a1 = { QCborValue(a1) }; // insert it into itself
QCOMPARE(a1.size(), 1);
- const QCborValue &first = qAsConst(a1).first();
+ const QCborValue &first = std::as_const(a1).first();
QVERIFY(first.isArray());
- QCOMPARE(first, QCborArray());
- QCOMPARE(first.toArray(wrongArray), QCborArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
}
{
QCborArray a1;
a1 = { QCborValue(a1) }; // insert it into itself
QCborValueRef first = a1.first();
QVERIFY(first.isArray());
- QCOMPARE(first, QCborArray());
- QCOMPARE(first.toArray(wrongArray), QCborArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
}
{
QCborArray a1;
a1.append(a1); // insert into itself
QCOMPARE(a1.size(), 1);
- const QCborValue &first = qAsConst(a1).first();
+ const QCborValue &first = std::as_const(a1).first();
QVERIFY(first.isArray());
- QCOMPARE(first, QCborArray());
- QCOMPARE(first.toArray(), QCborArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
}
{
QCborArray a1;
a1.append(a1); // insert into itself
QCborValueRef first = a1.first();
QVERIFY(first.isArray());
- QCOMPARE(first, QCborArray());
- QCOMPARE(first.toArray(), QCborArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
}
}
@@ -1792,8 +1868,24 @@ void tst_QCborValue::mapNested()
}
}
-void tst_QCborValue::sorting()
+void tst_QCborValue::sorting_data()
{
+ // CBOR data comparisons are done as if we were comparing their canonically
+ // (deterministic) encoded forms in the byte stream, including the Major
+ // Type. That has a few surprises noted below:
+ // 1) because the length of a string precedes it, effectively strings are
+ // sorted by their UTF-8 length before their contents
+ // 2) because negative integers are stored in negated form, they sort in
+ // descending order (i.e. by absolute value)
+ // 3) negative integers (Major Type 1) sort after all positive integers
+ // (Major Type 0)
+ // Effectively, this means integers are sorted as sign+magnitude.
+ // 4) floating point types (Major Type 7) sort after all integers
+
+ QTest::addColumn<QCborValue>("lhs");
+ QTest::addColumn<QCborValue>("rhs");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
QCborValue vundef, vnull(nullptr);
QCborValue vtrue(true), vfalse(false);
QCborValue vint1(1), vint2(2);
@@ -1802,7 +1894,8 @@ void tst_QCborValue::sorting()
QCborValue vs2("Hello"), vs3("World"), vs1("foo");
QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0});
QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}});
- QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc());
+ QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC));
+ QCborValue vdt2(QDateTime::currentDateTimeUtc());
QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()),
vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays...
vtagged3(QCborKnownTags::Signature, 0),
@@ -1811,67 +1904,262 @@ void tst_QCborValue::sorting()
QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/"));
QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid());
QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255));
- QCborValue vdouble1(1.5), vdouble2(qInf());
+ QCborValue vdouble1(1.5), vdouble2(qInf()), vdouble3(qQNaN());
QCborValue vndouble1(-1.5), vndouble2(-qInf());
-#define CHECK_ORDER(v1, v2) \
- QVERIFY(v1 < v2); \
- QVERIFY(!(v2 < v2))
+ auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) {
+ QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()),
+ qPrintable(rhs.toDiagnosticNotation()))
+ << lhs << rhs << order;
+ };
+ auto addSelfCmp = [](QCborValue v) {
+ QTest::addRow("self-%s", qPrintable(v.toDiagnosticNotation()))
+ << v << v << Qt::strong_ordering::equal;
+ };
+
+ // self compares
+ addSelfCmp(vundef);
+ addSelfCmp(vnull);
+ addSelfCmp(vfalse);
+ addSelfCmp(vtrue);
+ addSelfCmp(vint1);
+ addSelfCmp(vint2);
+ addSelfCmp(vneg1);
+ addSelfCmp(vneg2);
+ addSelfCmp(vba1);
+ addSelfCmp(vba2);
+ addSelfCmp(vba3);
+ addSelfCmp(vs1);
+ addSelfCmp(vs2);
+ addSelfCmp(vs3);
+ addSelfCmp(va1);
+ addSelfCmp(va2);
+ addSelfCmp(va3);
+ addSelfCmp(vm1);
+ addSelfCmp(vm2);
+ addSelfCmp(vm3);
+ addSelfCmp(vdt1);
+ addSelfCmp(vdt2);
+ addSelfCmp(vtagged1);
+ addSelfCmp(vtagged2);
+ addSelfCmp(vtagged3);
+ addSelfCmp(vtagged4);
+ addSelfCmp(vtagged5);
+ addSelfCmp(vurl1);
+ addSelfCmp(vurl2);
+ addSelfCmp(vuuid1);
+ addSelfCmp(vuuid2);
+ addSelfCmp(vsimple1);
+ addSelfCmp(vsimple32);
+ addSelfCmp(vsimple255);
+ addSelfCmp(vdouble1);
+ addSelfCmp(vdouble2);
+ addSelfCmp(vdouble3); // surprise: NaNs do compare
+ addSelfCmp(vndouble1);
+ addSelfCmp(vndouble2);
// intra-type comparisons
- CHECK_ORDER(vfalse, vtrue);
- CHECK_ORDER(vsimple1, vsimple32);
- CHECK_ORDER(vsimple32, vsimple255);
- CHECK_ORDER(vint1, vint2);
- CHECK_ORDER(vdouble1, vdouble2);
- CHECK_ORDER(vndouble1, vndouble2);
- // note: shorter length sorts first
- CHECK_ORDER(vba1, vba2);
- CHECK_ORDER(vba2, vba3);
- CHECK_ORDER(vs1, vs2);
- CHECK_ORDER(vs2, vs3);
- CHECK_ORDER(va1, va2);
- CHECK_ORDER(va2, va3);
- CHECK_ORDER(vm1, vm2);
- CHECK_ORDER(vm2, vm3);
- CHECK_ORDER(vdt1, vdt2);
- CHECK_ORDER(vtagged1, vtagged2);
- CHECK_ORDER(vtagged2, vtagged3);
- CHECK_ORDER(vtagged3, vtagged4);
- CHECK_ORDER(vtagged4, vtagged5);
- CHECK_ORDER(vurl1, vurl2);
- CHECK_ORDER(vuuid1, vuuid2);
-
- // surprise 1: CBOR sorts integrals by absolute value
- CHECK_ORDER(vneg1, vneg2);
-
- // surprise 2: CBOR sorts negatives after positives (sign+magnitude)
- CHECK_ORDER(vint2, vneg1);
- QVERIFY(vint2.toInteger() > vneg1.toInteger());
- CHECK_ORDER(vdouble2, vndouble1);
- QVERIFY(vdouble2.toDouble() > vndouble1.toDouble());
+ addRow(vfalse, vtrue, Qt::strong_ordering::less);
+ addRow(vsimple1, vsimple32, Qt::strong_ordering::less);
+ addRow(vsimple32, vsimple255, Qt::strong_ordering::less);
+ addRow(vint1, vint2, Qt::strong_ordering::less);
+ addRow(vdouble1, vdouble2, Qt::strong_ordering::less);
+ addRow(vdouble2, vdouble3, Qt::strong_ordering::less); // surprise: NaNs do compare
+ addRow(vndouble1, vndouble2, Qt::strong_ordering::less); // surprise: -1.5 < -inf
+ addRow(va1, va2, Qt::strong_ordering::less);
+ addRow(va2, va3, Qt::strong_ordering::less);
+ addRow(vm1, vm2, Qt::strong_ordering::less);
+ addRow(vm2, vm3, Qt::strong_ordering::less);
+ addRow(vdt1, vdt2, Qt::strong_ordering::less);
+ addRow(vtagged1, vtagged2, Qt::strong_ordering::less);
+ addRow(vtagged2, vtagged3, Qt::strong_ordering::less);
+ addRow(vtagged3, vtagged4, Qt::strong_ordering::less);
+ addRow(vtagged4, vtagged5, Qt::strong_ordering::less);
+ addRow(vurl1, vurl2, Qt::strong_ordering::less);
+ addRow(vuuid1, vuuid2, Qt::strong_ordering::less);
+
+ // surprise 1: CBOR sorts strings by length first
+ addRow(vba1, vba2, Qt::strong_ordering::less);
+ addRow(vba2, vba3, Qt::strong_ordering::less);
+ addRow(vs1, vs2, Qt::strong_ordering::less);
+ addRow(vs2, vs3, Qt::strong_ordering::less);
+
+ // surprise 2: CBOR sorts integrals by absolute value
+ addRow(vneg1, vneg2, Qt::strong_ordering::less);
+
+ // surprise 3: CBOR sorts negatives after positives (sign+magnitude)
+ addRow(vint2, vneg1, Qt::strong_ordering::less);
+ addRow(vdouble2, vndouble1, Qt::strong_ordering::less);
// inter-type comparisons
- CHECK_ORDER(vneg2, vba1);
- CHECK_ORDER(vba3, vs1);
- CHECK_ORDER(vs3, va1);
- CHECK_ORDER(va2, vm1);
- CHECK_ORDER(vm2, vdt1);
- CHECK_ORDER(vdt2, vtagged1);
- CHECK_ORDER(vtagged2, vurl1);
- CHECK_ORDER(vurl1, vuuid1);
- CHECK_ORDER(vuuid2, vtagged3);
- CHECK_ORDER(vtagged4, vsimple1);
- CHECK_ORDER(vsimple1, vfalse);
- CHECK_ORDER(vtrue, vnull);
- CHECK_ORDER(vnull, vundef);
- CHECK_ORDER(vundef, vsimple32);
- CHECK_ORDER(vsimple255, vdouble1);
+ addRow(vneg2, vba1, Qt::strong_ordering::less);
+ addRow(vba3, vs1, Qt::strong_ordering::less);
+ addRow(vs3, va1, Qt::strong_ordering::less);
+ addRow(va2, vm1, Qt::strong_ordering::less);
+ addRow(vm2, vdt1, Qt::strong_ordering::less);
+ addRow(vdt2, vtagged1, Qt::strong_ordering::less);
+ addRow(vtagged2, vurl1, Qt::strong_ordering::less);
+ addRow(vurl1, vuuid1, Qt::strong_ordering::less);
+ addRow(vuuid2, vtagged3, Qt::strong_ordering::less);
+ addRow(vtagged4, vsimple1, Qt::strong_ordering::less);
+ addRow(vsimple1, vfalse, Qt::strong_ordering::less);
+ addRow(vtrue, vnull, Qt::strong_ordering::less);
+ addRow(vnull, vundef, Qt::strong_ordering::less);
+ addRow(vundef, vsimple32, Qt::strong_ordering::less);
+ addRow(vsimple255, vdouble1, Qt::strong_ordering::less);
// which shows all doubles sorted after integrals
- CHECK_ORDER(vint2, vdouble1);
- QVERIFY(vint2.toInteger() > vdouble1.toDouble());
-#undef CHECK_ORDER
+ addRow(vint2, vdouble1, Qt::strong_ordering::less);
+
+ // Add some non-US-ASCII strings. In the current implementation, QCborValue
+ // can store a string as either US-ASCII, UTF-8, or UTF-16, so let's exercise
+ // those comparisons.
+
+ // we don't have a QUtf8StringView constructor, so work around it
+ auto utf8string = [](QByteArray str) {
+ Q_ASSERT(str.size() < 24);
+ str.prepend(char(QCborValue::String) + str.size());
+ return QCborValue::fromCbor(str);
+ };
+
+ auto addStringCmp = [&](const char *prefix, const char *tag, QUtf8StringView lhs,
+ QUtf8StringView rhs) {
+ // CBOR orders strings by UTF-8 length
+ auto order = Qt::compareThreeWay(lhs.size(), rhs.size());
+ if (is_eq(order))
+ order = compareThreeWay(lhs, rhs);
+ Q_ASSERT(is_eq(order) || is_lt(order)); // please keep lhs <= rhs!
+
+ QCborValue lhs_utf8 = utf8string(QByteArrayView(lhs).toByteArray());
+ QCborValue rhs_utf8 = utf8string(QByteArrayView(rhs).toByteArray());
+ QCborValue lhs_utf16 = QString::fromUtf8(lhs);
+ QCborValue rhs_utf16 = QString::fromUtf8(rhs);
+
+ QTest::addRow("string-%s%s:utf8-utf8", prefix, tag) << lhs_utf8 << rhs_utf8 << order;
+ QTest::addRow("string-%s%s:utf8-utf16", prefix, tag) << lhs_utf8 << rhs_utf16 << order;
+ QTest::addRow("string-%s%s:utf16-utf8", prefix, tag) << lhs_utf16 << rhs_utf8 << order;
+ QTest::addRow("string-%s%s:utf16-utf16", prefix, tag) << lhs_utf16 << rhs_utf16 << order;
+ };
+ auto addStringCmpSameLength = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) {
+ Q_ASSERT(lhs.size() == rhs.size());
+ addStringCmp("samelength-", tag, lhs, rhs);
+ };
+ auto addStringCmpShorter = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) {
+ Q_ASSERT(lhs.size() < rhs.size());
+ addStringCmp("shorter-", tag, lhs, rhs);
+ };
+
+ // ascii-only is already tested
+ addStringCmp("equal-", "1continuation", "ab\u00A0c", "ab\u00A0c");
+ addStringCmp("equal-", "2continuation", "ab\u0800", "ab\u0800");
+ addStringCmp("equal-", "3continuation", "a\U00010000", "a\U00010000");
+
+ // these strings all have the same UTF-8 length (5 bytes)
+ addStringCmpSameLength("less-ascii", "abcde", "ab\u00A0c");
+ addStringCmpSameLength("less-1continuation", "ab\u00A0c", "ab\u07FFc");
+ addStringCmpSameLength("less-2continuation", "ab\u0800", "ab\uFFFC");
+ addStringCmpSameLength("less-3continuation", "a\U00010000", "a\U0010FFFC");
+ addStringCmpSameLength("less-0-vs-1continuation", "abcde", "ab\u00A0c");
+ addStringCmpSameLength("less-0-vs-2continuation", "abcde", "ab\u0800");
+ addStringCmpSameLength("less-0-vs-3continuation", "abcde", "a\U00010000");
+ addStringCmpSameLength("less-1-vs-2continuation", "ab\u00A0c", "ab\uFFFC");
+ addStringCmpSameLength("less-1-vs-3continuation", "ab\u00A0c", "a\U00010000");
+ addStringCmpSameLength("less-2-vs-3continuation", "ab\u0800", "a\U00010000");
+ addStringCmpSameLength("less-2-vs-3continuation_surrogate", "a\uFFFCz", "a\U00010000"); // even though U+D800 < U+FFFC
+
+ // these strings have different lengths in UTF-8
+ // (0continuation already tested)
+ addStringCmpShorter("1continuation", "ab\u00A0", "ab\u00A0c");
+ addStringCmpShorter("2continuation", "ab\u0800", "ab\u0800c");
+ addStringCmpShorter("3continuation", "ab\U00010000", "ab\U00010000c");
+ // most of these have the same length in UTF-16!
+ addStringCmpShorter("0-vs-1continuation", "abc", "ab\u00A0");
+ addStringCmpShorter("0-vs-2continuation", "abcd", "ab\u0800");
+ addStringCmpShorter("0-vs-3continuation", "abcde", "ab\U00010000");
+ addStringCmpShorter("1-vs-2continuation", "ab\u00A0", "ab\u0800");
+ addStringCmpShorter("1-vs-3continuation", "abc\u00A0", "ab\U00010000");
+ addStringCmpShorter("2-vs-3continuation", "ab\u0800", "ab\U00010000");
+
+ // lhs is 4xUTF-16 and 8xUTF-8; rhs is 3xUTF-16 but 9xUTF-8
+ addStringCmpShorter("3x2-vs-2x3continuation", "\U00010000\U00010000", "\u0800\u0800\u0800");
+
+ // slight surprising because normally rhs would sort first ("aa" vs "ab" prefix)
+ // (0continuation_surprise already tested)
+ addStringCmpShorter("1continuation_surprise", "ab\u00A0", "aa\u00A0c");
+ addStringCmpShorter("2continuation_surprise", "ab\u0800", "aa\u0800c");
+ addStringCmpShorter("3continuation_surprise", "ab\U00010000", "aa\U00010000c");
+ addStringCmpShorter("0-vs-1continuation_surprise", "abc", "aa\u00A0");
+ addStringCmpShorter("0-vs-2continuation_surprise", "abcd", "aa\u0800");
+ addStringCmpShorter("0-vs-3continuation_surprise", "abcde", "aa\U00010000");
+ addStringCmpShorter("1-vs-2continuation_surprise", "ab\u00A0", "aa\u0800");
+ addStringCmpShorter("1-vs-3continuation_surprise", "abc\u00A0", "aa\U00010000");
+ addStringCmpShorter("2-vs-3continuation_surprise", "ab\u0800", "aa\U00010000");
+}
+
+void tst_QCborValue::sorting()
+{
+ QFETCH(QCborValue, lhs);
+ QFETCH(QCborValue, rhs);
+ QFETCH(Qt::strong_ordering, expectedOrdering);
+
+ // do a QCOMPARE first so we get a proper QTest error in case QCborValue is
+ // broken
+ if (expectedOrdering == Qt::strong_ordering::equal)
+ QCOMPARE_EQ(lhs, rhs);
+ else if (expectedOrdering == Qt::strong_ordering::less)
+ QCOMPARE_LT(lhs, rhs);
+ else if (expectedOrdering == Qt::strong_ordering::greater)
+ QCOMPARE_GT(lhs, rhs);
+
+ 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<QCborMap>("left");
+ QTest::addColumn<QCborMap>("right");
+ QTest::addColumn<Qt::strong_ordering>("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()
@@ -1897,7 +2185,6 @@ static void addCommonCborData()
QTest::newRow("simple0") << QCborValue(QCborValue::SimpleType) << raw("\xe0") << noxfrm;
QTest::newRow("simple1") << QCborValue(QCborSimpleType(1)) << raw("\xe1") << noxfrm;
- QTest::newRow("simple255") << QCborValue(QCborSimpleType(255)) << raw("\xf8\xff") << noxfrm;
QTest::newRow("Undefined") << QCborValue() << raw("\xf7") << noxfrm;
QTest::newRow("Null") << QCborValue(nullptr) << raw("\xf6") << noxfrm;
QTest::newRow("True") << QCborValue(true) << raw("\xf5") << noxfrm;
@@ -1960,15 +2247,16 @@ static void addCommonCborData()
QTest::newRow("DateTime") << QCborValue(dt) // this is UTC
<< "\xc0\x78\x18" + dt.toString(Qt::ISODateWithMs).toLatin1()
<< noxfrm;
- QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC))
+ QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
<< raw("\xc0\x78\x18" "2018-01-01T09:00:00.000Z")
<< noxfrm;
- QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::LocalTime))
+ QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}))
<< raw("\xc0\x77" "2018-01-01T09:00:00.000")
<< noxfrm;
- QTest::newRow("DateTime+01:00") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::OffsetFromUTC, 3600))
- << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
- << noxfrm;
+ QTest::newRow("DateTime+01:00")
+ << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::fromSecondsAheadOfUtc(3600)))
+ << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
+ << noxfrm;
QTest::newRow("Url:Empty") << QCborValue(QUrl()) << raw("\xd8\x20\x60") << noxfrm;
QTest::newRow("Url") << QCborValue(QUrl("HTTPS://example.com/{%30%31}?q=%3Ca+b%20%C2%A9%3E&%26"))
<< raw("\xd8\x20\x78\x27" "https://example.com/{01}?q=<a+b \xC2\xA9>&%26")
@@ -2076,21 +2364,29 @@ void tst_QCborValue::fromCbor_data()
QTest::newRow("String:Chunked:Empty") << QCborValue(QString())
<< raw("\x7f\xff");
- QTest::newRow("DateTime:NoMilli") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
- << raw("\xc0\x74" "2018-01-10T06:24:37Z");
+ QTest::newRow("DateTime:NoMilli")
+ << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
+ << raw("\xc0\x74" "2018-01-10T06:24:37Z");
// date-only is only permitted local time
- QTest::newRow("DateTime:NoTime:Local") << QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0), Qt::LocalTime))
- << raw("\xc0\x6a" "2020-04-15");
- QTest::newRow("DateTime:24:00:00") << QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), Qt::UTC))
- << raw("\xc0\x74" "2020-04-15T24:00:00Z");
- QTest::newRow("DateTime:+00:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC))
- << raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00");
- QTest::newRow("DateTime:+01:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::OffsetFromUTC, 60*60))
- << raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00");
- QTest::newRow("UnixTime_t:Integer") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
- << raw("\xc1\x1a\x5a\x55\xb1\xa5");
- QTest::newRow("UnixTime_t:Double") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC))
- << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
+ QTest::newRow("DateTime:NoTime:Local")
+ << QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0)))
+ << raw("\xc0\x6a" "2020-04-15");
+ QTest::newRow("DateTime:24:00:00")
+ << QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), QTimeZone::UTC))
+ << raw("\xc0\x74" "2020-04-15T24:00:00Z");
+ QTest::newRow("DateTime:+00:00")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
+ << raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00");
+ QTest::newRow("DateTime:+01:00")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125,
+ QTimeZone::fromSecondsAheadOfUtc(60 * 60)))
+ << raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00");
+ QTest::newRow("UnixTime_t:Integer")
+ << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
+ << raw("\xc1\x1a\x5a\x55\xb1\xa5");
+ QTest::newRow("UnixTime_t:Double")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
+ << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
QTest::newRow("Url:NotNormalized") << QCborValue(QUrl("https://example.com/\xc2\xa9 "))
<< raw("\xd8\x20\x78\x1dHTTPS://EXAMPLE.COM/%c2%a9%20");
@@ -2210,7 +2506,7 @@ void tst_QCborValue::validation_data()
// Add QCborStreamReader-specific limitations due to use of QByteArray and
// QString, which are allocated by QArrayData::allocate().
const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max();
- const qsizetype MinInvalid = MaxByteArraySize + 1 - sizeof(QByteArray::size_type);
+ const qsizetype MinInvalid = QByteArray::max_size() + 1 - sizeof(QByteArray::size_type);
addValidationColumns();
addValidationData(MinInvalid);
addValidationLargeData(MinInvalid, MaxInvalid);
@@ -2297,7 +2593,7 @@ void tst_QCborValue::extendedTypeValidation_data()
// representation, which means it can't represent dates before year 1 or
// after year 9999.
{
- QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), Qt::UTC);
+ QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), QTimeZone::UTC);
QTest::newRow("UnixTime_t:negative-year")
<< encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1)
<< QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch());
@@ -2369,7 +2665,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)
@@ -2383,11 +2679,16 @@ void tst_QCborValue::hugeDeviceValidation_data()
{
// because QCborValue will attempt to retain the original string in UTF-8,
// the size which it can't store is actually the byte array size
- addValidationHugeDevice(MaxByteArraySize + 1, MaxByteArraySize + 1);
+ addValidationHugeDevice(QByteArray::max_size() + 1, QByteArray::max_size() + 1);
}
void tst_QCborValue::hugeDeviceValidation()
{
+#if defined(Q_OS_WASM)
+ QSKIP("This test tries to allocate a huge memory buffer,"
+ " causes problem on WebAssembly platform which has limited resources.");
+#endif // Q_OS_WASM
+
QFETCH(QSharedPointer<QIODevice>, device);
QFETCH(CborError, expectedError);
QCborError error = { QCborError::Code(expectedError) };
@@ -2641,14 +2942,9 @@ template <typename ValueRef> 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());
@@ -2695,9 +2991,9 @@ template <typename ValueRef> static void cborValueRef_template()
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")]);
+ QCOMPARE(ref[0], std::as_const(v)[0]);
+ QCOMPARE(ref[QLatin1String("other")], std::as_const(v)[QLatin1String("other")]);
+ QCOMPARE(ref[QString("other")], std::as_const(v)[QString("other")]);
if (qIsNaN(v.toDouble()))
QCOMPARE(qIsNaN(ref.toVariant().toDouble()), qIsNaN(v.toVariant().toDouble()));
@@ -2737,10 +3033,10 @@ 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
- QCOMPARE(origArray, QCborArray{123});
+ QT_TEST_EQUALITY_OPS(origArray, QCborArray{123}, true);
}
{
QCborArray emptyArray;
@@ -2755,11 +3051,11 @@ 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
- QCOMPARE(emptyArray, QCborArray());
+ QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true);
}
{
QCborArray emptyArray = { 123, 456 };
@@ -2776,11 +3072,11 @@ 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
- QCOMPARE(emptyArray, QCborArray());
+ QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true);
}
}
@@ -2908,6 +3204,7 @@ void tst_QCborValue::streamVariantSerialization()
load >> output;
QCOMPARE(output.userType(), QMetaType::QCborArray);
QCOMPARE(qvariant_cast<QCborArray>(output), array);
+ QT_TEST_EQUALITY_OPS(qvariant_cast<QCborArray>(output), array, true);
}
{
QCborMap obj{{"foo", 42}};
@@ -2938,7 +3235,7 @@ void tst_QCborValue::debugOutput_data()
QTest::addColumn<QCborValue>("v");
QTest::addColumn<QString>("expected");
- QDateTime dt(QDate(2020, 4, 18), QTime(13, 41, 22, 123), Qt::UTC);
+ QDateTime dt(QDate(2020, 4, 18), QTime(13, 41, 22, 123), QTimeZone::UTC);
QBitArray bits = QBitArray::fromBits("\x79\x03", 11);
QTest::newRow("Undefined") << QCborValue() << "QCborValue()";
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt
index 213732e04d..14ac0514f9 100644
--- a/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qcborvalue_json.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcborvalue_json Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborvalue_json LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcborvalue_json
SOURCES
tst_qcborvalue_json.cpp
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
index 3e5ee74a00..941bfa4008 100644
--- a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 Intel Corporation.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborvalue.h>
#include <QTest>
diff --git a/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt
index 361ababd4c..ebbb232362 100644
--- a/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qdatastream.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdatastream Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatastream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
list(APPEND test_data "datastream.q42")
list(APPEND test_data "typedef.q5")
@@ -11,7 +18,7 @@ list(APPEND test_data "typedef.q5")
qt_internal_add_test(tst_qdatastream
SOURCES
tst_qdatastream.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
TESTDATA ${test_data}
)
diff --git a/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp
index 4ad15a3535..6cc2755d8a 100644
--- a/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp
+++ b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDataStream>
diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
index e63bc01cda..77ca884897 100644
--- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QBuffer>
@@ -134,6 +134,7 @@ private slots:
void stream_atEnd();
void stream_writeError();
+ void stream_writeSizeLimitExceeded();
void stream_QByteArray2();
@@ -295,6 +296,8 @@ static int NColorRoles[] = {
QPalette::PlaceholderText + 1, // Qt_5_12
QPalette::PlaceholderText + 1, // Qt_5_13, Qt_5_14, Qt_5_15
QPalette::PlaceholderText + 1, // Qt_6_0
+ QPalette::Accent + 1, // Qt_6_6
+ QPalette::Accent + 1, // Qt_6_7
0 // add the correct value for Qt_5_14 here later
};
@@ -960,10 +963,10 @@ static void QBitArrayData(QBitArray *b, int index)
case 18: filler = "1111111111111111111111111111111111111111111111111111111111111111"; break;
}
- b->resize(filler.length());
+ b->resize(filler.size());
b->fill(0); // reset all bits to zero
- for (int i = 0; i < filler.length(); ++i) {
+ for (int i = 0; i < filler.size(); ++i) {
if (filler.at(i) == '1')
b->setBit(i, true);
}
@@ -1205,15 +1208,15 @@ void tst_QDataStream::readQCursor(QDataStream *s)
QCOMPARE(d5.hotSpot(), test.hotSpot());
// Comparing non-null QBitmaps will fail. Upcast them first to pass.
- QCOMPARE(d5.bitmap(Qt::ReturnByValue).isNull(), test.bitmap(Qt::ReturnByValue).isNull());
+ QCOMPARE(d5.bitmap().isNull(), test.bitmap().isNull());
QCOMPARE(
- static_cast<QPixmap>(d5.bitmap(Qt::ReturnByValue)),
- static_cast<QPixmap>(test.bitmap(Qt::ReturnByValue))
+ static_cast<QPixmap>(d5.bitmap()),
+ static_cast<QPixmap>(test.bitmap())
);
- QCOMPARE(d5.mask(Qt::ReturnByValue).isNull(), test.mask(Qt::ReturnByValue).isNull());
+ QCOMPARE(d5.mask().isNull(), test.mask().isNull());
QCOMPARE(
- static_cast<QPixmap>(d5.mask(Qt::ReturnByValue)),
- static_cast<QPixmap>(test.mask(Qt::ReturnByValue))
+ static_cast<QPixmap>(d5.mask()),
+ static_cast<QPixmap>(test.mask())
);
}
#endif
@@ -2188,6 +2191,19 @@ void tst_QDataStream::stream_writeError()
TEST_WRITE_ERROR(.writeRawData("test", 4))
}
+void tst_QDataStream::stream_writeSizeLimitExceeded()
+{
+ QByteArray ba;
+ QDataStream ds(&ba, QDataStream::ReadWrite);
+ // Set the version that supports only 32-bit data size
+ ds.setVersion(QDataStream::Qt_6_6);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ const qint64 size = qint64(std::numeric_limits<quint32>::max()) + 1;
+ ds.writeBytes("", size);
+ QCOMPARE(ds.status(), QDataStream::SizeLimitExceeded);
+ QVERIFY(ba.isEmpty());
+}
+
void tst_QDataStream::stream_QByteArray2()
{
QByteArray ba;
@@ -2392,8 +2408,8 @@ void tst_QDataStream::setVersion()
*/
// revise the test if new color roles or color groups are added
- QVERIFY(QPalette::NColorRoles == QPalette::PlaceholderText + 1);
- QCOMPARE(int(QPalette::NColorGroups), 3);
+ QCOMPARE(QPalette::NColorRoles, QPalette::Accent + 1);
+ QCOMPARE(static_cast<int>(QPalette::NColorGroups), 3);
QByteArray ba2;
QPalette pal1, pal2;
@@ -2794,7 +2810,6 @@ void tst_QDataStream::status_charptr_QByteArray_data()
QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("badsize 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
- QTest::newRow("size -1") << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
}
@@ -2817,17 +2832,35 @@ void tst_QDataStream::status_charptr_QByteArray()
{
QDataStream stream(&data, QIODevice::ReadOnly);
char *buf;
- uint len;
+ qint64 len;
stream.readBytes(buf, len);
- QCOMPARE((int)len, expectedString.size());
+ QCOMPARE(len, qint64(expectedString.size()));
QCOMPARE(QByteArray(buf, len), expectedString);
QCOMPARE(int(stream.status()), expectedStatus);
delete [] buf;
}
+#if QT_DEPRECATED_SINCE(6, 11)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ {
+ // check that old overload still works as expected
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ char *buf;
+ auto cleanup = qScopeGuard([&buf] {
+ delete [] buf;
+ });
+ uint len;
+ stream.readBytes(buf, len);
+
+ QCOMPARE(len, expectedString.size());
+ QCOMPARE(QByteArray(buf, len), expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+ }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 11)
{
QDataStream stream(&data, QIODevice::ReadOnly);
- QByteArray buf;
+ QByteArray buf = "Content to be overwritten";
stream >> buf;
if (data.startsWith("\xff\xff\xff\xff")) {
@@ -2896,12 +2929,20 @@ void tst_QDataStream::status_QString_data()
QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
QTest::newRow("badsize 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
- QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
- QTest::newRow("size MAX") << QByteArray("\x7f\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("32 bit size should be 64 bit") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
- // corrupt data
+#if QT_POINTER_SIZE != 4
+ // past end on 64 bit platforms
+ QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::ReadPastEnd << QString();
+#else
+ // too big for 32 bit platforms
+ QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::SizeLimitExceeded << QString();
+#endif
+ // too big on both 32 and 64 bit platforms because qsizetype is signed
+ QTest::newRow("64 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xfe", 12) << (int) QDataStream::SizeLimitExceeded << QString();
+
+ // corrupt data because QChar is 16 bit => even size required
QTest::newRow("corrupt1") << QByteArray("yyyy") << (int) QDataStream::ReadCorruptData << QString();
- QTest::newRow("size -3") << QByteArray("\xff\xff\xff\xfd", 4) << (int) QDataStream::ReadCorruptData << QString();
}
void tst_QDataStream::status_QString()
@@ -2911,7 +2952,7 @@ void tst_QDataStream::status_QString()
QFETCH(QString, expectedString);
QDataStream stream(&data, QIODevice::ReadOnly);
- QString str;
+ QString str = "Content to be overwritten";
stream >> str;
QCOMPARE(str.size(), expectedString.size());
@@ -2975,6 +3016,8 @@ void tst_QDataStream::status_QBitArray_data()
QTest::newRow("badsize 16") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
QTest::newRow("badsize 17") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray();
QTest::newRow("badsize 32") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize INT_MAX") << QDataStream::Qt_5_15 << QByteArray("\x7f\xff\xff\xff\xff\xff\xff", 7) << int(QDataStream::ReadPastEnd) << QBitArray(); // size accepted
+ QTest::addRow("badsize INT_MAX + 1") << QDataStream::Qt_5_15 << QByteArray("\x80\x00\x00\x01" "\xff\xff\xff", 7) << int(QDataStream::ReadCorruptData) << QBitArray(); // size rejected
QTest::newRow("new badsize 0") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
QTest::newRow("new badsize 9") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x09\xff", 9) << (int) QDataStream::ReadPastEnd << QBitArray();
QTest::newRow("new badsize 0x10000") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00", 9) << (int) QDataStream::ReadPastEnd << QBitArray();
@@ -3004,7 +3047,7 @@ void tst_QDataStream::status_QBitArray()
QDataStream stream(&data, QIODevice::ReadOnly);
stream.setVersion(version);
- QBitArray str;
+ QBitArray str(255, true);
stream >> str;
if (sizeof(qsizetype) == sizeof(int))
@@ -3071,7 +3114,9 @@ void tst_QDataStream::status_QHash_QMap()
hash2.insert("L", "MN");
// ok
+ hash = hash2;
MAP_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, StringHash());
+ hash = hash2;
MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 12), QDataStream::Ok, QDataStream::Ok, hash1);
MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J\x00\x00\x00\x02\x00K"
"\x00\x00\x00\x02\x00L\x00\x00\x00\x04\x00M\x00N", 30), QDataStream::Ok, QDataStream::Ok, hash2);
@@ -3152,7 +3197,9 @@ void tst_QDataStream::status_QList_QVector()
someList.append("J");
someList.append("MN");
+ list = someList;
LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, List());
+ list = someList;
LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::Ok, QDataStream::Ok, listWithEmptyString);
LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J"
"\x00\x00\x00\x04\x00M\x00N", 18), QDataStream::Ok, QDataStream::Ok, someList);
@@ -3220,6 +3267,13 @@ void tst_QDataStream::streamRealDataTypes()
path.arcTo(4, 5, 6, 7, 8, 9);
path.quadTo(1, 2, 3, 4);
+ QPainterPath otherPath;
+ otherPath.arcTo(10, 4, 5, 6, 7, 8);
+ otherPath.lineTo(9, 0);
+ otherPath.cubicTo(0, 0, 10, 10, 20, 20);
+ otherPath.quadTo(2, 4, 5, 6);
+ QCOMPARE(otherPath.elementCount(), 12);
+
QColor color(64, 64, 64);
color.setAlphaF(0.5);
QRadialGradient radialGradient(5, 6, 7, 8, 9);
@@ -3251,17 +3305,17 @@ void tst_QDataStream::streamRealDataTypes()
file.close();
}
- QPointF point;
- QRectF rect;
- QPolygonF polygon;
+ QPointF point(1, 2);
+ QRectF rect(1, 2, 5, 6);
+ QPolygonF polygon {{3, 4}, {5, 6}};
QTransform transform;
- QPainterPath p;
+ QPainterPath p = otherPath;
QPicture pict;
- QTextLength textLength;
- QColor col;
- QBrush rGrad;
- QBrush cGrad;
- QPen pen;
+ QTextLength textLength(QTextLength::FixedLength, 2.5);
+ QColor col(128, 128, 127);
+ QBrush rGrad(Qt::CrossPattern);
+ QBrush cGrad(Qt::CrossPattern);
+ QPen pen(conicalBrush, 10);
QVERIFY(file.open(QIODevice::ReadOnly));
QDataStream stream(&file);
@@ -3882,17 +3936,18 @@ void tst_QDataStream::typedefQt5Compat()
QTemporaryDir dir;
QVERIFY(dir.isValid());
QFile file(dir.filePath(u"typedef.q6"_s));
- file.open(QIODevice::WriteOnly);
+ QVERIFY(file.open(QIODevice::WriteOnly));
QDataStream stream(&file);
stream.setVersion(QDataStream::Qt_5_15);
CustomPair p {42, 100};
stream << QVariant::fromValue(p);
file.close();
- file.open(QIODevice::ReadOnly);
+ QVERIFY(file.open(QIODevice::ReadOnly));
QCOMPARE(file.readAll(), qt5Data);
}
}
QTEST_MAIN(tst_QDataStream)
+
#include "tst_qdatastream.moc"
diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt b/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt
index b77b8212fb..d0622c642c 100644
--- a/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qdatastream_core_pixmap.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdatastream_core_pixmap Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatastream_core_pixmap LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdatastream_core_pixmap
SOURCES
tst_qdatastream_core_pixmap.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
)
diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
index 1b11782bbd..f17da27f1c 100644
--- a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
+++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
@@ -1,11 +1,11 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtGui/QPixmap>
#include <QtGui/QImage>
-class tst_QDataStream : public QObject
+class tst_QDataStreamPixmap : public QObject
{
Q_OBJECT
@@ -13,7 +13,7 @@ private slots:
void stream_with_pixmap();
};
-void tst_QDataStream::stream_with_pixmap()
+void tst_QDataStreamPixmap::stream_with_pixmap()
{
// This is a QVariantMap with a 3x3 red QPixmap and two strings inside
const QByteArray ba = QByteArray::fromBase64(
@@ -37,6 +37,6 @@ void tst_QDataStream::stream_with_pixmap()
QCOMPARE(map["z"].toString(), QString("there"));
}
-QTEST_GUILESS_MAIN(tst_QDataStream)
+QTEST_GUILESS_MAIN(tst_QDataStreamPixmap)
#include "tst_qdatastream_core_pixmap.moc"
diff --git a/tests/auto/corelib/serialization/qtextstream/BLACKLIST b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
index aef7d7aa26..cb76e0454d 100644
--- a/tests/auto/corelib/serialization/qtextstream/BLACKLIST
+++ b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
@@ -1,5 +1,3 @@
-[stillOpenWhenAtEnd]
-windows-7sp1
# QTBUG-87410
[readStdin]
android
diff --git a/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt
index 15798c963f..ac3dc91555 100644
--- a/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt
@@ -1,4 +1,11 @@
-# Generated from qtextstream.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextstream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
add_subdirectory(test)
add_subdirectory(stdinProcess)
diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt
index 785785d43a..bcfb0aaf4e 100644
--- a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from readAllStdinProcess.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## readAllStdinProcess Binary:
diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
index 5491191ca3..01f47d758f 100644
--- a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QTextStream>
diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt
index 897444c9af..39af3a3048 100644
--- a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from readLineStdinProcess.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## readLineStdinProcess Binary:
diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
index 84d1b48c28..8f81f5a720 100644
--- a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt
index 73eccd1ed8..7e964bbfb2 100644
--- a/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from stdinProcess.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## stdinProcess Binary:
diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
index 00498dd7b5..b8a274ed0f 100644
--- a/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QTextStream>
diff --git a/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt
index 1db76f274f..588a49fcf0 100644
--- a/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
#####################################################################
## tst_qtextstream Test:
#####################################################################
@@ -15,13 +18,17 @@ qt_internal_add_test(tst_qtextstream
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
SOURCES
../tst_qtextstream.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Network
Qt::TestPrivate
TESTDATA ${test_data}
QT_TEST_SERVER_LIST "cyrus"
)
+if(QT_FEATURE_sanitize_address)
+ set_property(TEST tst_qtextstream APPEND PROPERTY ENVIRONMENT "QTEST_FUNCTION_TIMEOUT=900000")
+endif()
+
# Resources:
set(qtextstream_resource_files
"../resources/big_endian/"
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index 6d80efe956..411084a36c 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -12,6 +12,7 @@
#include <QDebug>
#include <QElapsedTimer>
#include <QFile>
+#include <QTemporaryFile>
#include <QStringConverter>
#include <QTcpSocket>
#include <QTemporaryDir>
@@ -202,6 +203,9 @@ private slots:
void textModeOnEmptyRead();
+ void autodetectUnicode_data();
+ void autodetectUnicode();
+
private:
void generateLineData(bool for_QString);
void generateAllData(bool for_QString);
@@ -546,7 +550,7 @@ void tst_QTextStream::readLineMaxlen()
QFile::remove("testfile");
QFile file("testfile");
if (useDevice) {
- file.open(QIODevice::ReadWrite);
+ QVERIFY(file.open(QIODevice::ReadWrite));
file.write(input.toUtf8());
file.seek(0);
stream.setDevice(&file);
@@ -931,7 +935,8 @@ void tst_QTextStream::lineCount_data()
QTest::newRow("buffersize+1 line") << QByteArray(16384, '\n') << 16384;
QTest::newRow("buffersize+2 line") << QByteArray(16385, '\n') << 16385;
- QFile file(m_rfc3261FilePath); file.open(QFile::ReadOnly);
+ QFile file(m_rfc3261FilePath);
+ QVERIFY(file.open(QFile::ReadOnly));
QTest::newRow("rfc3261") << file.readAll() << 15067;
}
@@ -942,7 +947,7 @@ void tst_QTextStream::lineCount()
QFETCH(int, lineCount);
QFile out("out.txt");
- out.open(QFile::WriteOnly);
+ QVERIFY(out.open(QFile::WriteOnly));
QTextStream lineReader(data);
int lines = 0;
@@ -1404,18 +1409,18 @@ void tst_QTextStream::pos3LargeFile()
{
QFile file(testFileName);
- file.open(QIODevice::WriteOnly | QIODevice::Text);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
QTextStream out( &file );
// NOTE: The unusual spacing is to ensure non-1-character whitespace.
QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
// Approximate 50kb text file
- const int NbLines = (50*1024) / lineString.length() + 1;
+ const int NbLines = (50*1024) / lineString.size() + 1;
for (int line = 0; line < NbLines; ++line)
out << lineString;
// File is automatically flushed and closed on destruction.
}
QFile file(testFileName);
- file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream in( &file );
const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int value;
@@ -1512,7 +1517,7 @@ void tst_QTextStream::read()
{
QFile::remove("testfile");
QFile file("testfile");
- file.open(QFile::WriteOnly);
+ QVERIFY(file.open(QFile::WriteOnly));
file.write("4.15 abc ole");
file.close();
@@ -1534,7 +1539,7 @@ void tst_QTextStream::read()
// File larger than QTEXTSTREAM_BUFFERSIZE
QFile::remove("testfile");
QFile file("testfile");
- file.open(QFile::WriteOnly);
+ QVERIFY(file.open(QFile::WriteOnly));
for (int i = 0; i < 16384 / 8; ++i)
file.write("01234567");
file.write("0");
@@ -1590,8 +1595,8 @@ void tst_QTextStream::forceSign()
// ------------------------------------------------------------------------------
void tst_QTextStream::read0d0d0a()
{
- QFile file("task113817.txt");
- file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QFile file(QFINDTESTDATA("task113817.txt"));
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream stream(&file);
while (!stream.atEnd())
@@ -1755,7 +1760,7 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary()
"\342\200\223"
"\342\200\223");
- data.open(QFile::WriteOnly | QFile::Truncate);
+ QVERIFY(data.open(QFile::WriteOnly | QFile::Truncate));
{
QTextStream out(&data);
out.setEncoding(QStringConverter::Utf8);
@@ -1767,7 +1772,7 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary()
}
data.close();
- data.open(QFile::ReadOnly);
+ QVERIFY(data.open(QFile::ReadOnly));
QTextStream in(&data);
QFETCH(bool, useLocale);
@@ -2649,13 +2654,27 @@ void tst_QTextStream::manipulators_data()
QTest::addColumn<QString>("textData");
QTest::addColumn<QByteArray>("result");
- QTest::newRow("no flags") << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
- QTest::newRow("rightadjust") << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
- QTest::newRow("leftadjust") << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
- QTest::newRow("showpos") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
- QTest::newRow("showpos2") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
- QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
- QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase | QTextStream::UppercaseBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
+ QTest::newRow("no flags")
+ << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
+ QTest::newRow("rightadjust")
+ << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five")
+ << QByteArray(" 5 5 five");
+ QTest::newRow("leftadjust")
+ << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five")
+ << QByteArray("5 5 five ");
+ QTest::newRow("showpos-wide")
+ << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 <<
+ QString("five") << QByteArray(" +5 +5 five");
+ QTest::newRow("showpos-pi")
+ << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 <<
+ QString("five") << QByteArray("+3.14 -5 five");
+ QTest::newRow("hex-lower")
+ << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 <<
+ QString("five") << QByteArray(" 3.14 -0x5 five");
+ QTest::newRow("hex-upper")
+ << 16 << int(QTextStream::AlignRight)
+ << int(QTextStream::ShowBase | QTextStream::UppercaseBase)
+ << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
}
// ------------------------------------------------------------------------------
@@ -3043,6 +3062,57 @@ void tst_QTextStream::textModeOnEmptyRead()
QVERIFY(file.isTextModeEnabled());
}
+void tst_QTextStream::autodetectUnicode_data()
+{
+ QTest::addColumn<QStringConverter::Encoding>("encoding");
+ QTest::newRow("Utf8") << QStringConverter::Utf8;
+ QTest::newRow("Utf16BE") << QStringConverter::Utf16BE;
+ QTest::newRow("Utf16LE") << QStringConverter::Utf16LE;
+ QTest::newRow("Utf32BE") << QStringConverter::Utf32BE;
+ QTest::newRow("Utf32LE") << QStringConverter::Utf32LE;
+}
+
+void tst_QTextStream::autodetectUnicode()
+{
+ QFETCH(QStringConverter::Encoding, encoding);
+
+ QTemporaryFile file;
+ QVERIFY(file.open());
+
+ QString original("HelloWorld👋");
+
+ {
+ QTextStream out(&file);
+ out.setGenerateByteOrderMark(true);
+ out.setEncoding(encoding);
+ out << original;
+ }
+ file.seek(0);
+ {
+ QTextStream in(&file);
+ QString actual;
+ in >> actual;
+ QCOMPARE(actual, original);
+ QCOMPARE(in.encoding(), encoding);
+ }
+ file.seek(0);
+ // Again, but change order of calls to QTextStream...
+ {
+ QTextStream out(&file);
+ out.setEncoding(encoding);
+ out.setGenerateByteOrderMark(true);
+ out << original;
+ }
+ file.seek(0);
+ {
+ QTextStream in(&file);
+ QString actual;
+ in >> actual;
+ QCOMPARE(actual, original);
+ QCOMPARE(in.encoding(), encoding);
+ }
+}
+
// ------------------------------------------------------------------------------
diff --git a/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt b/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt
index f3602c92fb..30c86491ff 100644
--- a/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt
+++ b/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt
@@ -1,20 +1,33 @@
-# Generated from qxmlstream.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qxmlstream Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qxmlstream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
data/* XML-Test-Suite/*)
+file(GLOB_RECURSE tokenError
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ tokenError/*)
+
qt_internal_add_test(tst_qxmlstream
SOURCES
tst_qxmlstream.cpp
LIBRARIES
Qt::Network
- Qt::Xml
- Qt::GuiPrivate
- TESTDATA ${test_data}
+ Qt::CorePrivate
+ Qt::TestPrivate
+ TESTDATA
+ ${test_data}
+ ${tokenError}
)
diff --git a/tests/auto/corelib/serialization/qxmlstream/qc14n.h b/tests/auto/corelib/serialization/qxmlstream/qc14n.h
index 0a06f0185d..5ae87f1a7a 100644
--- a/tests/auto/corelib/serialization/qxmlstream/qc14n.h
+++ b/tests/auto/corelib/serialization/qxmlstream/qc14n.h
@@ -1,10 +1,11 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-QT_FORWARD_DECLARE_CLASS(QIODevice)
-QT_FORWARD_DECLARE_CLASS(QString)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QtCore/QDebug>
#include <QtCore/QFlags>
+#include <QtCore/QXmlStreamReader>
+
+#include <algorithm>
class QC14N
{
@@ -93,18 +94,11 @@ bool QC14N::isAttributesEqual(const QXmlStreamReader &r1,
const QXmlStreamAttributes &attrs1 = r1.attributes();
const QXmlStreamAttributes &attrs2 = r2.attributes();
- const int len = attrs1.size();
-
- if(len != attrs2.size())
+ if (attrs1.size() != attrs2.size())
return false;
- for(int i = 0; i < len; ++i)
- {
- if(!attrs2.contains(attrs1.at(i)))
- return false;
- }
-
- return true;
+ auto existsInOtherList = [&attrs2](const auto &attr) { return attrs2.contains(attr); };
+ return std::all_of(attrs1.cbegin(), attrs1.cend(), existsInOtherList);
}
bool QC14N::isDifferent(const QXmlStreamReader &r1,
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
new file mode 100644
index 0000000000..1c3ca4e271
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statement, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+ <!-- invalid DTD in XML body follows -->
+ <!DOCTYPE DTDTEST [
+ <!ELEMENT RESULT (CASE+)>
+ <!ATTLIST RESULT OUTPUT CDATA #REQUIRED>
+ ]>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
new file mode 100644
index 0000000000..cd398c0f9f
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY iff "&hArr;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<!-- invalid second DTD follows -->
+<!DOCTYPE SECOND [
+ <!ELEMENT SECONDATTRIBUTE (#PCDATA)>
+ <!ENTITY on "&#8728;">
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
new file mode 100644
index 0000000000..1b61a3f062
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
@@ -0,0 +1,15 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
index 2799e7a999..b90d05b0fa 100644
--- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDirIterator>
@@ -8,14 +8,17 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QUrl>
#include <QXmlStreamReader>
#include <QBuffer>
#include <QStack>
-#include <QtGui/private/qzipreader_p.h>
+#include <private/qzipreader_p.h>
#include "qc14n.h"
+using namespace Qt::StringLiterals;
+
Q_DECLARE_METATYPE(QXmlStreamReader::ReadElementTextBehaviour)
static const char *const catalogFile = "XML-Test-Suite/xmlconf/finalCatalog.xml";
@@ -92,8 +95,8 @@ static QByteArray makeCanonical(const QString &filename,
bool testIncremental = false)
{
QFile file(filename);
- file.open(QIODevice::ReadOnly);
-
+ if (!file.open(QIODevice::ReadOnly))
+ qFatal("Could not open file %s", qPrintable(filename));
QXmlStreamReader reader;
QByteArray buffer;
@@ -540,6 +543,8 @@ public:
private slots:
void initTestCase();
void cleanupTestCase();
+ void compareCompiles();
+ void runTestSuite();
void reportFailures() const;
void reportFailures_data();
void checkBaseline() const;
@@ -558,6 +563,7 @@ private slots:
void setEntityResolver();
void readFromQBuffer() const;
void readFromQBufferInvalid() const;
+ void readFromLatin1String() const;
void readNextStartElement() const;
void readElementText() const;
void readElementText_data() const;
@@ -566,6 +572,14 @@ private slots:
void hasAttribute() const;
void writeWithUtf8Codec() const;
void writeWithStandalone() const;
+ void writeCharacters_data() const;
+ void writeCharacters() const;
+ void writeAttribute_data() const;
+ void writeAttribute() const;
+ void writeBadCharactersUtf8_data() const;
+ void writeBadCharactersUtf8() const;
+ void writeBadCharactersUtf16_data() const;
+ void writeBadCharactersUtf16() const;
void entitiesAndWhitespace_1() const;
void entitiesAndWhitespace_2() const;
void testFalsePrematureError() const;
@@ -578,12 +592,20 @@ private slots:
void invalidStringCharacters_data() const;
void invalidStringCharacters() const;
void hasError() const;
+ void readBack_data() const;
void readBack() const;
void roundTrip() const;
void roundTrip_data() const;
+ void test_fastScanName_data() const;
+ void test_fastScanName() const;
void entityExpansionLimit() const;
+ void tokenErrorHandling_data() const;
+ void tokenErrorHandling() const;
+ void checkStreamNotationDeclarations() const;
+ void checkStreamEntityDeclarations() const;
+
private:
static QByteArray readFile(const QString &filename);
@@ -620,7 +642,22 @@ void tst_QXmlStream::initTestCase()
QFile::remove(destinationPath); // copy will fail if file exists
QVERIFY(QFile::copy(fileInfo.filePath(), destinationPath));
}
+}
+
+void tst_QXmlStream::cleanupTestCase()
+{
+}
+void tst_QXmlStream::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamAttribute>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNamespaceDeclaration>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNotationDeclaration>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamEntityDeclaration>();
+}
+
+void tst_QXmlStream::runTestSuite()
+{
QFile file(m_tempDir.filePath(catalogFile));
QVERIFY2(file.open(QIODevice::ReadOnly),
qPrintable(QString::fromLatin1("Failed to open the test suite catalog; %1").arg(file.fileName())));
@@ -628,10 +665,6 @@ void tst_QXmlStream::initTestCase()
QVERIFY(m_handler.runTests(&file));
}
-void tst_QXmlStream::cleanupTestCase()
-{
-}
-
void tst_QXmlStream::reportFailures() const
{
QFETCH(bool, isError);
@@ -642,7 +675,7 @@ void tst_QXmlStream::reportFailures() const
void tst_QXmlStream::reportFailures_data()
{
- const int len = m_handler.failures.count();
+ const int len = m_handler.failures.size();
QTest::addColumn<bool>("isError");
QTest::addColumn<QString>("description");
@@ -679,7 +712,7 @@ void tst_QXmlStream::checkBaseline_data() const
QTest::addColumn<QString>("expected");
QTest::addColumn<QString>("output");
- const int len = m_handler.missedBaselines.count();
+ const int len = m_handler.missedBaselines.size();
for(int i = 0; i < len; ++i)
{
@@ -708,7 +741,7 @@ void tst_QXmlStream::reportSuccess_data() const
{
QTest::addColumn<bool>("isError");
- const int len = m_handler.successes.count();
+ const int len = m_handler.successes.size();
for (int i = 0; i < len; ++i) {
const QByteArray testName = QByteArray::number(i) + ". " + m_handler.successes.at(i).toLatin1();
@@ -722,7 +755,8 @@ void tst_QXmlStream::reportSuccess_data() const
QByteArray tst_QXmlStream::readFile(const QString &filename)
{
QFile file(filename);
- file.open(QIODevice::ReadOnly);
+ if (!file.open(QIODevice::ReadOnly))
+ qFatal("Could not open file %s", qPrintable(filename));
QXmlStreamReader reader;
@@ -873,12 +907,17 @@ void tst_QXmlStream::addExtraNamespaceDeclarations()
}
{
QXmlStreamReader xml(data);
- xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared", "blabla"));
- xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared_too", "foofoo"));
+ QXmlStreamNamespaceDeclaration undeclared("undeclared", "blabla");
+ QXmlStreamNamespaceDeclaration undeclared_too("undeclared_too", "blabla");
+ xml.addExtraNamespaceDeclaration(undeclared);
+ xml.addExtraNamespaceDeclaration(undeclared_too);
while (!xml.atEnd()) {
xml.readNext();
}
QVERIFY2(!xml.hasError(), xml.errorString().toLatin1().constData());
+ QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, false);
+ undeclared = undeclared_too;
+ QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, true);
}
}
@@ -1099,6 +1138,25 @@ void tst_QXmlStream::readFromQBufferInvalid() const
QVERIFY(reader.hasError());
}
+void tst_QXmlStream::readFromLatin1String() const
+{
+ const auto in = "<a>M\xE5rten</a>"_L1;
+ {
+ QXmlStreamReader reader(in);
+ QVERIFY(reader.readNextStartElement());
+ QString text = reader.readElementText();
+ QCOMPARE(text, "M\xE5rten"_L1);
+ }
+ // Same as above, but with addData()
+ {
+ QXmlStreamReader reader;
+ reader.addData(in);
+ QVERIFY(reader.readNextStartElement());
+ QString text = reader.readElementText();
+ QCOMPARE(text, "M\xE5rten"_L1);
+ }
+}
+
void tst_QXmlStream::readNextStartElement() const
{
QLatin1String in("<?xml version=\"1.0\"?><A><!-- blah --><B><C/></B><B attr=\"value\"/>text</A>");
@@ -1115,6 +1173,10 @@ void tst_QXmlStream::readNextStartElement() const
}
QCOMPARE(amountOfB, 2);
+
+ // well-formed document end follows
+ QVERIFY(!reader.readNextStartElement());
+ QCOMPARE(reader.error(), QXmlStreamReader::NoError);
}
void tst_QXmlStream::readElementText() const
@@ -1232,8 +1294,20 @@ void tst_QXmlStream::hasAttributeSignature() const
void tst_QXmlStream::hasAttribute() const
{
- QXmlStreamReader reader(QLatin1String("<e xmlns:p='http://example.com/2' xmlns='http://example.com/' "
- "attr1='value' attr2='value2' p:attr3='value3' emptyAttr=''><noAttributes/></e>"));
+ auto xml = QStringLiteral("<e"
+ " xmlns:p='http://example.com/2'"
+ " xmlns='http://example.com/'"
+ " attr1='value'"
+ " attr2='value2'"
+ " p:attr3='value3'"
+ " emptyAttr=''"
+ " atträbute='meep'"
+ " α='β'"
+ " >"
+ " <noAttributes/>"
+ "</e>");
+
+ QXmlStreamReader reader(xml);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartDocument);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement);
@@ -1244,8 +1318,18 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(atts.hasAttribute(QLatin1String("attr2")));
QVERIFY(atts.hasAttribute(QLatin1String("p:attr3")));
QVERIFY(atts.hasAttribute(QLatin1String("emptyAttr")));
+ QVERIFY(atts.hasAttribute(QLatin1String("attr\xE4""bute")));
+ // α is not representable in L1...
QVERIFY(!atts.hasAttribute(QLatin1String("DOESNOTEXIST")));
+ /* string literals (UTF-8/16) */
+ QVERIFY(atts.hasAttribute(u8"atträbute"));
+ QVERIFY(atts.hasAttribute( u"atträbute"));
+ QVERIFY(atts.hasAttribute(u8"α"));
+ QVERIFY(atts.hasAttribute( u"α"));
+ QVERIFY(!atts.hasAttribute(u8"β"));
+ QVERIFY(!atts.hasAttribute( u"β"));
+
/* Test with an empty & null namespaces. */
QVERIFY(atts.hasAttribute(QString(), QLatin1String("attr2"))); /* A null string. */
QVERIFY(atts.hasAttribute(QLatin1String(""), QLatin1String("attr2"))); /* An empty string. */
@@ -1254,6 +1338,8 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(atts.hasAttribute(QString::fromLatin1("attr1")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("attr2")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("p:attr3")));
+ QVERIFY(atts.hasAttribute(QStringLiteral("atträbute")));
+ QVERIFY(atts.hasAttribute(QStringLiteral("α")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("emptyAttr")));
QVERIFY(!atts.hasAttribute(QString::fromLatin1("DOESNOTEXIST")));
@@ -1267,6 +1353,7 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(!atts.hasAttribute(QLatin1String("WRONG_NAMESPACE"), QString::fromLatin1("attr3")));
/* Invoke on an QXmlStreamAttributes that has no attributes at all. */
+ QCOMPARE(reader.readNext(), QXmlStreamReader::Characters);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement);
const QXmlStreamAttributes &atts2 = reader.attributes();
@@ -1285,6 +1372,15 @@ void tst_QXmlStream::hasAttribute() const
reader.readNext();
QVERIFY(!reader.hasError());
+
+ QXmlStreamAttribute attrValue1(QLatin1String("http://example.com/"), QString::fromLatin1("attr1"));
+ QXmlStreamAttribute attrValue2 = atts.at(0);
+ QT_TEST_EQUALITY_OPS(atts.at(0), QXmlStreamAttribute(), false);
+ QT_TEST_EQUALITY_OPS(atts.at(0), attrValue1, false);
+ QT_TEST_EQUALITY_OPS(atts.at(0), attrValue2, true);
+ QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, false);
+ attrValue1 = attrValue2;
+ QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, true);
}
void tst_QXmlStream::writeWithUtf8Codec() const
@@ -1319,6 +1415,143 @@ void tst_QXmlStream::writeWithStandalone() const
}
}
+static void writeCharacters_data_common()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+
+ QTest::newRow("empty") << QString() << QString();
+
+ // invalid content
+ QTest::newRow("null-character") << u"\0"_s << QString();
+ QTest::newRow("vertical-tab") << "\v" << QString();
+ QTest::newRow("form-feed") << "\f" << QString();
+ QTest::newRow("esc") << "\x1f" << QString();
+ QTest::newRow("U+FFFE") << u"\xfffe"_s << QString();
+ QTest::newRow("U+FFFF") << u"\xffff"_s << QString();
+
+ // simple strings
+ QTest::newRow("us-ascii") << "Hello, world" << "Hello, world";
+ QTest::newRow("latin1") << "Bokmål" << "Bokmål";
+ QTest::newRow("nonlatin1") << "Ελληνικά" << "Ελληνικά";
+ QTest::newRow("nonbmp") << u"\U00010000"_s << u"\U00010000"_s;
+
+ // escaped content
+ QTest::newRow("less-than") << "<" << "&lt;";
+ QTest::newRow("greater-than") << ">" << "&gt;";
+ QTest::newRow("ampersand") << "&" << "&amp;";
+ QTest::newRow("quote") << "\"" << "&quot;";
+}
+
+template <typename Execute, typename Transform>
+static void writeCharacters_common(Execute &&exec, Transform &&transform)
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QStringView utf16 = input;
+ QByteArray utf8ba = input.toUtf8();
+ QUtf8StringView utf8(utf8ba);
+
+ // may be invalid if input is not Latin1
+ QByteArray l1ba = input.toLatin1();
+ QLatin1StringView l1(l1ba);
+ if (l1 != input)
+ l1 = {};
+
+ auto write = [&](auto input) -> std::optional<QString> {
+ QString result;
+ QXmlStreamWriter writer(&result);
+ writer.writeStartElement("a");
+ exec(writer, input);
+ writer.writeEndElement();
+ if (writer.hasError())
+ return std::nullopt;
+ return result;
+ };
+
+ if (input.isNull() != output.isNull()) {
+ // error
+ QCOMPARE(write(utf16), std::nullopt);
+ QCOMPARE(write(utf8), std::nullopt);
+ if (!l1.isEmpty())
+ QCOMPARE(write(l1), std::nullopt);
+ } else {
+ output = transform(output);
+ QCOMPARE(write(utf16), output);
+ QCOMPARE(write(utf8), output);
+ if (!l1.isEmpty())
+ QCOMPARE(write(l1), output);
+ }
+}
+
+void tst_QXmlStream::writeCharacters_data() const
+{
+ writeCharacters_data_common();
+ QTest::newRow("tab") << "\t" << "\t";
+ QTest::newRow("newline") << "\n" << "\n";
+ QTest::newRow("carriage-return") << "\r" << "\r";
+}
+
+void tst_QXmlStream::writeCharacters() const
+{
+ auto exec = [](QXmlStreamWriter &writer, auto input) {
+ writer.writeCharacters(input);
+ };
+ auto transform = [](auto output) { return "<a>" + output + "</a>"; };
+ writeCharacters_common(exec, transform);
+}
+
+void tst_QXmlStream::writeAttribute_data() const
+{
+ writeCharacters_data_common();
+ QTest::newRow("tab") << "\t" << "&#9;";
+ QTest::newRow("newline") << "\n" << "&#10;";
+ QTest::newRow("carriage-return") << "\r" << "&#13;";
+}
+
+void tst_QXmlStream::writeAttribute() const
+{
+ auto exec = [](QXmlStreamWriter &writer, auto input) {
+ writer.writeAttribute("b", input);
+ };
+ auto transform = [](auto output) { return "<a b=\"" + output + "\"/>"; };
+ writeCharacters_common(exec, transform);
+}
+
+#include "../../io/qurlinternal/utf8data.cpp"
+void tst_QXmlStream::writeBadCharactersUtf8_data() const
+{
+ QTest::addColumn<QByteArray>("input");
+ loadInvalidUtf8Rows();
+}
+
+void tst_QXmlStream::writeBadCharactersUtf8() const
+{
+ QFETCH(QByteArray, input);
+ QString target;
+ QXmlStreamWriter writer(&target);
+ writer.writeTextElement("a", QUtf8StringView(input));
+ QVERIFY(writer.hasError());
+}
+
+void tst_QXmlStream::writeBadCharactersUtf16_data() const
+{
+ QTest::addColumn<QString>("input");
+ QTest::addRow("low-surrogate") << u"\xdc00"_s;
+ QTest::addRow("high-surrogate") << u"\xd800"_s;
+ QTest::addRow("inverted-surrogate-pair") << u"\xdc00\xd800"_s;
+ QTest::addRow("high-surrogate+non-surrogate") << u"\xd800z"_s;
+}
+
+void tst_QXmlStream::writeBadCharactersUtf16() const
+{
+ QFETCH(QString, input);
+ QString target;
+ QXmlStreamWriter writer(&target);
+ writer.writeTextElement("a", input);
+ QVERIFY(writer.hasError());
+}
+
void tst_QXmlStream::entitiesAndWhitespace_1() const
{
QXmlStreamReader reader(QLatin1String("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><test>&extEnt;</test>"));
@@ -1638,41 +1871,64 @@ void tst_QXmlStream::invalidStringCharacters_data() const
//
}
-static bool isValidSingleTextChar(const ushort c)
+static bool isValidSingleTextChar(char32_t c)
{
- // Conforms to https://www.w3.org/TR/REC-xml/#NT-Char - except for the high range, which is done
- // with surrogates.
+ // Conforms to https://www.w3.org/TR/REC-xml/#NT-Char
// Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
- static const QPair<ushort, ushort> validRanges[] = {
- QPair<ushort, ushort>(0x9, 0xb),
- QPair<ushort, ushort>(0xd, 0xe),
- QPair<ushort, ushort>(0x20, 0xd800),
- QPair<ushort, ushort>(0xe000, 0xfffe)
+ constexpr struct { char32_t lo, hi; } validRanges[] = {
+ {0x9, 0xA},
+ {0xD, 0xD},
+ {0x20, 0xD7ff},
+ {0xE000, 0xFFFD},
+ {0x1'0000, 0x10'FFFF},
};
- for (const QPair<ushort, ushort> &range : validRanges) {
- if (c >= range.first && c < range.second)
+ for (const auto range : validRanges) {
+ if (c >= range.lo && c <= range.hi)
return true;
}
return false;
}
+void tst_QXmlStream::readBack_data() const
+{
+ QTest::addColumn<int>("plane");
+
+ // Check all 17 Unicode planes. Split into separate executions lest the
+ // test function times out in asan builds.
+
+ for (int i = 0; i < 17; ++i)
+ QTest::addRow("plane-%02d", i) << i;
+}
+
void tst_QXmlStream::readBack() const
{
- for (ushort c = 0; c < std::numeric_limits<ushort>::max(); ++c) {
- QBuffer buffer;
+ QFETCH(const int, plane);
+
+ constexpr qsizetype MaxChunkSizeWhenEncoding = 512; // from qxmlstream.cpp
+ QBuffer buffer;
+ QString text = QString(513, 'a'); // one longer than the internal conversion buffer
+
+ for (char16_t i = 0; i < (std::numeric_limits<char16_t>::max)(); ++i) {
+
+ const char32_t c = (plane << 16) + i;
+
+ // end chunk in invalid character, split surrogates:
+ const auto pair = QChar::fromUcs4(c);
+ text.resize(MaxChunkSizeWhenEncoding + 1 - pair.size());
+ text += pair;
- QVERIFY(buffer.open(QIODevice::WriteOnly));
+ QVERIFY(buffer.open(QIODevice::WriteOnly|QIODevice::Truncate));
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
- writer.writeTextElement("a", QString(QChar(c)));
+ writer.writeTextElement("a", text);
writer.writeEndDocument();
buffer.close();
- if (writer.hasError()) {
- QVERIFY2(!isValidSingleTextChar(c), QByteArray::number(c));
+ if (!isValidSingleTextChar(c)) {
+ QVERIFY2(writer.hasError(), QByteArray::number(c));
} else {
- QVERIFY2(isValidSingleTextChar(c), QByteArray::number(c));
+ QVERIFY2(!writer.hasError(), QByteArray::number(c));
QVERIFY(buffer.open(QIODevice::ReadOnly));
QXmlStreamReader reader(&buffer);
do {
@@ -1694,6 +1950,22 @@ void tst_QXmlStream::roundTrip_data() const
"<child xmlns:unknown=\"http://mydomain\">Text</child>"
"</father>"
"</root>\n";
+
+ // When a namespace is introduced by an attribute of an element,
+ // that element can exercise the namespace in its tag.
+ // This used (QTBUG-75456) to lead to the namespace definition
+ // being wrongly duplicated, with a new name.
+ QTest::newRow("QTBUG-75456") <<
+ "<?xml version=\"1.0\"?>"
+ "<abc:root xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:abc=\"ns1\">"
+ "<abc:parent>"
+ "<abc:child xmlns:unknown=\"http://mydomain\">Text</abc:child>"
+ "</abc:parent>"
+ "<def:parent xmlns:def=\"ns2\" id=\"test\">"
+ "<def:child id=\"Timmy\">More text</def:child>"
+ "<def:child id=\"Jimmy\">Even more text</def:child>"
+ "</def:parent>"
+ "</abc:root>\n";
}
void tst_QXmlStream::entityExpansionLimit() const
@@ -1753,5 +2025,126 @@ void tst_QXmlStream::roundTrip() const
QCOMPARE(out, in);
}
+void tst_QXmlStream::test_fastScanName_data() const
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QXmlStreamReader::Error>("errorType");
+
+ // 4096 is the limit in QXmlStreamReaderPrivate::fastScanName()
+
+ QByteArray arr = "<a:" + QByteArray("b").repeated(4096 - 1);
+ QTest::newRow("data1") << arr << QXmlStreamReader::PrematureEndOfDocumentError;
+
+ arr = "<a:" + QByteArray("b").repeated(4096);
+ QTest::newRow("data2") << arr << QXmlStreamReader::NotWellFormedError;
+
+ arr = "<" + QByteArray("a").repeated(4000) + ":" + QByteArray("b").repeated(96);
+ QTest::newRow("data3") << arr << QXmlStreamReader::PrematureEndOfDocumentError;
+
+ arr = "<" + QByteArray("a").repeated(4000) + ":" + QByteArray("b").repeated(96 + 1);
+ QTest::newRow("data4") << arr << QXmlStreamReader::NotWellFormedError;
+
+ arr = "<" + QByteArray("a").repeated(4000 + 1) + ":" + QByteArray("b").repeated(96);
+ QTest::newRow("data5") << arr << QXmlStreamReader::NotWellFormedError;
+}
+
+void tst_QXmlStream::test_fastScanName() const
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QXmlStreamReader::Error, errorType);
+
+ QXmlStreamReader reader(data);
+ QXmlStreamReader::TokenType tokenType;
+ while (!reader.atEnd())
+ tokenType = reader.readNext();
+
+ QCOMPARE(tokenType, QXmlStreamReader::Invalid);
+ QCOMPARE(reader.error(), errorType);
+}
+
+void tst_QXmlStream::tokenErrorHandling_data() const
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QXmlStreamReader::Error>("expectedError");
+ QTest::addColumn<QString>("errorKeyWord");
+
+ constexpr auto invalid = QXmlStreamReader::Error::UnexpectedElementError;
+ constexpr auto valid = QXmlStreamReader::Error::NoError;
+ QTest::newRow("DtdInBody") << "dtdInBody.xml" << invalid << "DTD";
+ QTest::newRow("multipleDTD") << "multipleDtd.xml" << invalid << "second DTD";
+ QTest::newRow("wellFormed") << "wellFormed.xml" << valid << "";
+}
+
+void tst_QXmlStream::tokenErrorHandling() const
+{
+ QFETCH(const QString, fileName);
+ QFETCH(const QXmlStreamReader::Error, expectedError);
+ QFETCH(const QString, errorKeyWord);
+
+ const QDir dir(QFINDTESTDATA("tokenError"));
+ QFile file(dir.absoluteFilePath(fileName));
+
+ // Cross-compiling: Files may not be found when running test standalone
+ // QSKIP in that case, because the tested functionality is platform independent.
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QCOMPARE(reader.error(), expectedError);
+ if (expectedError != QXmlStreamReader::Error::NoError)
+ QVERIFY(reader.errorString().contains(errorKeyWord));
+}
+
+void tst_QXmlStream::checkStreamNotationDeclarations() const
+{
+ QString fileName("12.xml");
+ const QDir dir(QFINDTESTDATA("data"));
+ QFile file(dir.absoluteFilePath(fileName));
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QVERIFY(!reader.hasError());
+ QXmlStreamNotationDeclaration notation1, notation2, notation3;
+ QT_TEST_EQUALITY_OPS(notation1, notation2, true);
+ const auto notationDeclarations = reader.notationDeclarations();
+ if (notationDeclarations.count() >= 2) {
+ notation1 = notationDeclarations.at(0);
+ notation2 = notationDeclarations.at(1);
+ notation3 = notationDeclarations.at(1);
+ }
+ QT_TEST_EQUALITY_OPS(notation1, notation2, false);
+ QT_TEST_EQUALITY_OPS(notation3, notation2, true);
+}
+
+void tst_QXmlStream::checkStreamEntityDeclarations() const
+{
+ QString fileName("5.xml");
+ const QDir dir(QFINDTESTDATA("data"));
+ QFile file(dir.absoluteFilePath(fileName));
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QVERIFY(!reader.hasError());
+ QXmlStreamEntityDeclaration entity;
+ QT_TEST_EQUALITY_OPS(entity, QXmlStreamEntityDeclaration(), true);
+
+ const auto entityDeclarations = reader.entityDeclarations();
+ if (entityDeclarations.count() >= 2) {
+ entity = entityDeclarations.at(1);
+ QT_TEST_EQUALITY_OPS(entityDeclarations.at(0), entityDeclarations.at(1), false);
+ QT_TEST_EQUALITY_OPS(entity, entityDeclarations.at(1), true);
+ }
+}
#include "tst_qxmlstream.moc"
-// vim: et:ts=4:sw=4:sts=4