diff options
Diffstat (limited to 'tests/auto/corelib/serialization/json/tst_qtjson.cpp')
-rw-r--r-- | tests/auto/corelib/serialization/json/tst_qtjson.cpp | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 3e58dd03cc..fbf0eacbd5 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -68,6 +68,7 @@ private Q_SLOTS: void testObjectNestedEmpty(); void testValueRef(); + void testValueRefComparison(); void testObjectIteration(); void testArrayIteration(); @@ -176,6 +177,8 @@ private Q_SLOTS: void fromToVariantConversions_data(); void fromToVariantConversions(); + void noLeakOnNameClash(); + private: QString testDataDir; }; @@ -729,15 +732,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")); @@ -747,14 +755,23 @@ 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); + inner.insert("number", 999.); outer.insert("nested", inner); // 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); + QCOMPARE(v["number"].toDouble(), 999.); // if we modify the original object, it should detach and not // affect the nested object @@ -908,6 +925,57 @@ void tst_QtJson::testValueRef() QCOMPARE(object.value(QLatin1String("key")), QJsonValue(42)); } +void tst_QtJson::testValueRefComparison() +{ + QJsonValue a0 = 42.; + QJsonValue a1 = QStringLiteral("142"); + +#define CHECK_IMPL(lhs, rhs, ineq) \ + QCOMPARE(lhs, rhs); \ + QVERIFY(!(lhs != rhs)); \ + QVERIFY(lhs != ineq); \ + QVERIFY(!(lhs == ineq)); \ + QVERIFY(ineq != rhs); \ + QVERIFY(!(ineq == rhs)); \ + /* end */ + +#define CHECK(lhs, rhs, ineq) \ + do { \ + CHECK_IMPL(lhs, rhs, ineq) \ + CHECK_IMPL(qAsConst(lhs), rhs, ineq) \ + CHECK_IMPL(lhs, qAsConst(rhs), ineq) \ + CHECK_IMPL(qAsConst(lhs), qAsConst(rhs), ineq) \ + } while (0) + + // check that the (in)equality operators aren't ambiguous in C++20: + QJsonArray a = {a0, a1}; + + Q_STATIC_ASSERT((std::is_same<decltype(a[0]), QJsonValueRef>::value)); + + auto r0 = a.begin()[0]; + auto r1 = a.begin()[1]; + auto c0 = qAsConst(a).begin()[0]; + // ref <> ref + CHECK(r0, r0, r1); + // cref <> ref + CHECK(c0, r0, r1); + // ref <> cref + CHECK(r0, c0, r1); + // ref <> val + CHECK(r0, a0, r1); + // cref <> val + CHECK(c0, a0, r1); + // val <> ref + CHECK(a0, r0, a1); + // val <> cref + CHECK(a0, c0, a1); + // val <> val + CHECK(a0, a0, a1); + +#undef CHECK +#undef CHECK_IMPL +} + void tst_QtJson::testObjectIteration() { QJsonObject object; @@ -3685,5 +3753,23 @@ void tst_QtJson::fromToVariantConversions() } } +void tst_QtJson::noLeakOnNameClash() +{ + QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}"); + QVERIFY(!doc.isNull()); + const QJsonObject obj = doc.object(); + + // Removed the duplicate key. + QCOMPARE(obj.length(), 1); + + // Retained the last of the duplicates. + const QJsonValue val = obj.begin().value(); + QVERIFY(val.isDouble()); + QCOMPARE(val.toDouble(), 0.0); + + // It should not leak. + // In particular it should not forget to deref the container for the inner object. +} + QTEST_MAIN(tst_QtJson) #include "tst_qtjson.moc" |