From 935861e91a68c49414d8fc5fdb035f32991c135b Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Thu, 8 Jul 2021 19:02:02 +0200 Subject: QMap: extend unit tests Extend tests to explicitly check the behavior of empty default-constructed container. Also add some missing tests to increase the code coverage. Task-number: QTBUG-91736 Pick-to: 6.2 6.1 Change-Id: I5b418265fc7cb3e56e44782be7704d642923a8e9 Reviewed-by: Edward Welbourne Reviewed-by: Andrei Golubev --- tests/auto/corelib/tools/qmap/tst_qmap.cpp | 305 ++++++++++++++++++++++++++++- 1 file changed, 301 insertions(+), 4 deletions(-) (limited to 'tests/auto/corelib/tools/qmap/tst_qmap.cpp') diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index d8be138c0e..d433cdaef4 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -47,6 +47,7 @@ private slots: void beginEnd(); void firstLast(); void key(); + void value(); void swap(); @@ -61,8 +62,10 @@ private slots: void take(); void iterators(); + void iteratorsInEmptyMap(); void keyIterator(); void keyValueIterator(); + void keyValueIteratorInEmptyMap(); void keys_values_uniqueKeys(); void qmultimap_specific(); @@ -78,6 +81,7 @@ private slots: void testInsertMultiWithHint(); void eraseValidIteratorOnSharedMap(); void removeElementsInMap(); + void toStdMap(); }; struct IdentityTracker { @@ -179,10 +183,18 @@ void tst_QMap::count() QCOMPARE( map.count(), 0 ); QCOMPARE( map2.count(), 0 ); QCOMPARE( MyClass::count, int(0) ); + QCOMPARE(map.count("key"), 0); + QCOMPARE(map.size(), 0); + QCOMPARE(map2.size(), 0); + QVERIFY(!map.isDetached()); + QVERIFY(!map2.isDetached()); // detach map2["Hallo"] = MyClass( "Fritz" ); QCOMPARE( map.count(), 0 ); + QCOMPARE( map.size(), 0 ); QCOMPARE( map2.count(), 1 ); + QCOMPARE( map2.size(), 1 ); + QVERIFY(!map.isDetached()); #ifndef Q_CC_SUN QCOMPARE( MyClass::count, 1 ); #endif @@ -324,6 +336,7 @@ void tst_QMap::clear() MyMap map; map.clear(); QVERIFY( map.isEmpty() ); + QVERIFY(!map.isDetached()); map.insert( "key", MyClass( "value" ) ); map.clear(); QVERIFY( map.isEmpty() ); @@ -409,6 +422,7 @@ void tst_QMap::key() QMap map1; QCOMPARE(map1.key(1), QString()); QCOMPARE(map1.key(1, def), def); + QVERIFY(!map1.isDetached()); map1.insert("one", 1); QCOMPARE(map1.key(1), QLatin1String("one")); @@ -439,6 +453,7 @@ void tst_QMap::key() QMap map2; QCOMPARE(map2.key("one"), 0); QCOMPARE(map2.key("one", def), def); + QVERIFY(!map2.isDetached()); map2.insert(1, "one"); QCOMPARE(map2.key("one"), 1); @@ -472,6 +487,39 @@ void tst_QMap::key() } } +void tst_QMap::value() +{ + const QString def = "default value"; + QMap map; + QCOMPARE(map.value(1), QString()); + QCOMPARE(map.value(1, def), def); + QVERIFY(!map.isDetached()); + + map.insert(1, "value1"); + QCOMPARE(map.value(1), "value1"); + QCOMPARE(map[1], "value1"); + QCOMPARE(map.value(2), QString()); + QCOMPARE(map.value(2, def), def); + QCOMPARE(map[2], QString()); + QCOMPARE(map.size(), 2); + + map.insert(2, "value2"); + QCOMPARE(map.value(2), "value2"); + QCOMPARE(map[2], "value2"); + + map.insert(1, "value3"); + QCOMPARE(map.value(1), "value3"); + QCOMPARE(map.value(1, def), "value3"); + QCOMPARE(map[1], "value3"); + + const QMap constMap; + QVERIFY(!constMap.isDetached()); + QCOMPARE(constMap.value(1, def), def); + QCOMPARE(constMap[1], QString()); + QCOMPARE(constMap.size(), 0); + QVERIFY(!constMap.isDetached()); +} + void tst_QMap::swap() { QMap m1, m2; @@ -567,13 +615,16 @@ void tst_QMap::empty() QMap map1; QVERIFY(map1.isEmpty()); + QVERIFY(map1.empty()); + QVERIFY(!map1.isDetached()); map1.insert(1, "one"); QVERIFY(!map1.isEmpty()); + QVERIFY(!map1.empty()); map1.clear(); QVERIFY(map1.isEmpty()); - + QVERIFY(map1.empty()); } void tst_QMap::contains() @@ -581,6 +632,9 @@ void tst_QMap::contains() QMap map1; int i; + QVERIFY(!map1.contains(1)); + QVERIFY(!map1.isDetached()); + map1.insert(1, "one"); QVERIFY(map1.contains(1)); @@ -595,6 +649,25 @@ void tst_QMap::contains() void tst_QMap::find() { + { + const QMap constMap; + QCOMPARE(constMap.find(1), constMap.end()); + QVERIFY(!constMap.isDetached()); + + QMap map; + QCOMPARE(map.find(1), map.end()); + + map.insert(1, "value1"); + map.insert(2, "value2"); + map.insert(5, "value5"); + map.insert(1, "value0"); + + QCOMPARE(map.find(1).value(), u"value0"); + QCOMPARE(map.find(5).value(), u"value5"); + QCOMPARE(map.find(2).value(), u"value2"); + QCOMPARE(map.find(4), map.end()); + } + QMultiMap map1; QString testString="Teststring %0"; QString compareString; @@ -628,6 +701,22 @@ void tst_QMap::find() void tst_QMap::constFind() { + { + QMap map; + QCOMPARE(map.constFind(1), map.constEnd()); + QVERIFY(!map.isDetached()); + + map.insert(1, "value1"); + map.insert(2, "value2"); + map.insert(5, "value5"); + map.insert(1, "value0"); + + QCOMPARE(map.constFind(1).value(), QLatin1String("value0")); + QCOMPARE(map.constFind(5).value(), QLatin1String("value5")); + QCOMPARE(map.constFind(2).value(), QLatin1String("value2")); + QCOMPARE(map.constFind(4), map.constEnd()); + } + QMultiMap map1; QString testString="Teststring %0"; QString compareString; @@ -662,6 +751,54 @@ void tst_QMap::constFind() void tst_QMap::lowerUpperBound() { + { + const QMap emptyConstMap; + QCOMPARE(emptyConstMap.lowerBound(1), emptyConstMap.constEnd()); + QCOMPARE(emptyConstMap.upperBound(1), emptyConstMap.constEnd()); + QVERIFY(!emptyConstMap.isDetached()); + + const QMap constMap { qMakePair(1, "one"), + qMakePair(5, "five"), + qMakePair(10, "ten") }; + + QCOMPARE(constMap.lowerBound(-1).key(), 1); + QCOMPARE(constMap.lowerBound(1).key(), 1); + QCOMPARE(constMap.lowerBound(3).key(), 5); + QCOMPARE(constMap.lowerBound(12), constMap.constEnd()); + + QCOMPARE(constMap.upperBound(-1).key(), 1); + QCOMPARE(constMap.upperBound(1).key(), 5); + QCOMPARE(constMap.upperBound(3).key(), 5); + QCOMPARE(constMap.upperBound(12), constMap.constEnd()); + + QMap map; + + map.insert(1, "one"); + map.insert(5, "five"); + map.insert(10, "ten"); + map.insert(3, "three"); + map.insert(7, "seven"); + + QCOMPARE(map.lowerBound(0).key(), 1); + QCOMPARE(map.lowerBound(1).key(), 1); + QCOMPARE(map.lowerBound(2).key(), 3); + QCOMPARE(map.lowerBound(3).key(), 3); + QCOMPARE(map.lowerBound(4).key(), 5); + QCOMPARE(map.lowerBound(5).key(), 5); + QCOMPARE(map.lowerBound(6).key(), 7); + QCOMPARE(map.lowerBound(7).key(), 7); + QCOMPARE(map.lowerBound(10).key(), 10); + QCOMPARE(map.lowerBound(999), map.end()); + + QCOMPARE(map.upperBound(0).key(), 1); + QCOMPARE(map.upperBound(1).key(), 3); + QCOMPARE(map.upperBound(2).key(), 3); + QCOMPARE(map.upperBound(3).key(), 5); + QCOMPARE(map.upperBound(7).key(), 10); + QCOMPARE(map.upperBound(10), map.end()); + QCOMPARE(map.upperBound(999), map.end()); + } + QMultiMap map1; map1.insert(1, "one"); @@ -749,6 +886,8 @@ void tst_QMap::mergeCompare() void tst_QMap::take() { QMap map; + QCOMPARE(map.take(1), QString()); + QVERIFY(!map.isDetached()); map.insert(2, "zwei"); map.insert(3, "drei"); @@ -834,14 +973,47 @@ void tst_QMap::iterators() } } +void tst_QMap::iteratorsInEmptyMap() +{ + QMap map; + using ConstIter = QMap::const_iterator; + ConstIter it1 = map.cbegin(); + ConstIter it2 = map.constBegin(); + QVERIFY(it1 == it2 && it2 == ConstIter()); + QVERIFY(!map.isDetached()); + + ConstIter it3 = map.cend(); + ConstIter it4 = map.constEnd(); + QVERIFY(it3 == it4 && it4 == ConstIter()); + QVERIFY(!map.isDetached()); + + // to call const overloads of begin() and end() + const QMap map2; + ConstIter it5 = map2.begin(); + ConstIter it6 = map2.end(); + QVERIFY(it5 == it6 && it6 == ConstIter()); + QVERIFY(!map2.isDetached()); + + using Iter = QMap::iterator; + Iter it7 = map.begin(); + Iter it8 = map.end(); + QVERIFY(it7 == it8); +} + void tst_QMap::keyIterator() { QMap map; + using KeyIterator = QMap::key_iterator; + KeyIterator it1 = map.keyBegin(); + KeyIterator it2 = map.keyEnd(); + QVERIFY(it1 == it2 && it2 == KeyIterator()); + QVERIFY(!map.isDetached()); + for (int i = 0; i < 100; ++i) map.insert(i, i*100); - QMap::key_iterator key_it = map.keyBegin(); + KeyIterator key_it = map.keyBegin(); QMap::const_iterator it = map.cbegin(); for (int i = 0; i < 100; ++i) { QCOMPARE(*key_it, it.key()); @@ -862,8 +1034,7 @@ void tst_QMap::keyIterator() QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 99), 1); // DefaultConstructible test - typedef QMap::key_iterator keyIterator; - static_assert(std::is_default_constructible::value); + static_assert(std::is_default_constructible::value); } void tst_QMap::keyValueIterator() @@ -925,8 +1096,61 @@ void tst_QMap::keyValueIterator() QCOMPARE(std::count(map.constKeyValueBegin(), map.constKeyValueEnd(), entry_type(key, value)), 1); } +void tst_QMap::keyValueIteratorInEmptyMap() +{ + QMap map; + using ConstKeyValueIter = QMap::const_key_value_iterator; + + ConstKeyValueIter it1 = map.constKeyValueBegin(); + ConstKeyValueIter it2 = map.constKeyValueEnd(); + QVERIFY(it1 == it2 && it2 == ConstKeyValueIter()); + QVERIFY(!map.isDetached()); + + const QMap map2; + ConstKeyValueIter it3 = map2.keyValueBegin(); + ConstKeyValueIter it4 = map2.keyValueEnd(); + QVERIFY(it3 == it4 && it4 == ConstKeyValueIter()); + QVERIFY(!map2.isDetached()); + + using KeyValueIter = QMap::key_value_iterator; + + KeyValueIter it5 = map.keyValueBegin(); + KeyValueIter it6 = map.keyValueEnd(); + QVERIFY(it5 == it6); +} + void tst_QMap::keys_values_uniqueKeys() { + { + QMap map; + QVERIFY(map.keys().isEmpty()); + QVERIFY(map.keys(1).isEmpty()); + QVERIFY(map.values().isEmpty()); + QVERIFY(!map.isDetached()); + + map.insert("one", 1); + QCOMPARE(map.keys(), QStringList({ "one" })); + QCOMPARE(map.keys(1), QStringList({ "one" })); + QCOMPARE(map.values(), QList({ 1 })); + + map.insert("two", 2); + QCOMPARE(map.keys(), QStringList({ "one", "two" })); + QCOMPARE(map.keys(1), QStringList({ "one" })); + QCOMPARE(map.values(), QList({ 1, 2 })); + + map.insert("three", 2); + QCOMPARE(map.keys(), QStringList({ "one", "three", "two" })); + QCOMPARE(map.keys(2), QStringList({ "three", "two" })); + QCOMPARE(map.values(), QList({ 1, 2, 2 })); + + map.insert("one", 0); + QCOMPARE(map.keys(), QStringList({ "one", "three", "two" })); + QCOMPARE(map.keys(1), QStringList()); + QCOMPARE(map.keys(0), QStringList({ "one" })); + QCOMPARE(map.keys(2), QStringList({ "three", "two" })); + QCOMPARE(map.values(), QList({ 0, 2, 2 })); + } + QMultiMap map; QVERIFY(map.keys().isEmpty()); QVERIFY(map.values().isEmpty()); @@ -1073,6 +1297,33 @@ void tst_QMap::const_shared_null() void tst_QMap::equal_range() { + { + const QMap constMap; + QCOMPARE(constMap.equal_range(1), qMakePair(constMap.constEnd(), constMap.constEnd())); + QVERIFY(!constMap.isDetached()); + + QMap map; + QCOMPARE(map.equal_range(1), qMakePair(map.end(), map.end())); + + map.insert(1, "value1"); + map.insert(5, "value5"); + map.insert(1, "value0"); + + auto pair = map.equal_range(1); + QCOMPARE(pair.first.value(), "value0"); + QCOMPARE(pair.second.value(), "value5"); + auto b = map.find(1); + auto e = map.find(5); + QCOMPARE(pair, qMakePair(b, e)); + + pair = map.equal_range(3); + QCOMPARE(pair.first.value(), "value5"); + QCOMPARE(pair.second.value(), "value5"); + QCOMPARE(pair, qMakePair(e, e)); + + QCOMPARE(map.equal_range(10), qMakePair(map.end(), map.end())); + } + QMultiMap map; const QMultiMap &cmap = map; @@ -1302,6 +1553,18 @@ void testDetachWhenInsert() void tst_QMap::insertMap() { + { + QMap map1; + QMap map2; + QVERIFY(map1.isEmpty()); + QVERIFY(map2.isEmpty()); + + map1.insert(map2); + QVERIFY(map1.isEmpty()); + QVERIFY(map2.isEmpty()); + QVERIFY(!map1.isDetached()); + QVERIFY(!map2.isDetached()); + } { QMap map; map.insert(1, 1); @@ -1363,6 +1626,10 @@ void tst_QMap::insertMap() map.insert(map2); QCOMPARE(map.count(), 1); QCOMPARE(map[1], 1); + + QMap map3; + map3.insert(std::move(map2)); + QCOMPARE(map3, map); } { QMap map; @@ -1660,6 +1927,14 @@ void tst_QMap::removeElementsInMap() bool operator<(const SharedInt &other) const { return *m_int < *other.m_int; } }; + { + QMap map; + QCOMPARE(map.remove(1), 0); + QVERIFY(!map.isDetached()); + + auto cnt = map.removeIf([](QMap::iterator) { return true; }); + QCOMPARE(cnt, 0); + } { QMap map { { SharedInt(1), 1 }, @@ -1718,6 +1993,10 @@ void tst_QMap::removeElementsInMap() QCOMPARE(map.size(), 0); QCOMPARE(map2.size(), 4); + + auto cnt = map2.removeIf([](auto it) { return (*it % 2) == 0; }); + QCOMPARE(cnt, 2); + QCOMPARE(map2.size(), 2); } { @@ -1820,5 +2099,23 @@ void tst_QMap::removeElementsInMap() } } +void tst_QMap::toStdMap() +{ + QMap map; + QVERIFY(map.isEmpty()); + auto stdMap = map.toStdMap(); + QVERIFY(stdMap.empty()); + QVERIFY(!map.isDetached()); + + map.insert(1, "value1"); + map.insert(2, "value2"); + map.insert(3, "value3"); + map.insert(1, "value0"); + + const std::map expectedMap { {1, "value0"}, {2, "value2"}, {3, "value3"} }; + stdMap = map.toStdMap(); + QCOMPARE(stdMap, expectedMap); +} + QTEST_APPLESS_MAIN(tst_QMap) #include "tst_qmap.moc" -- cgit v1.2.3