summaryrefslogtreecommitdiffstats
path: root/tests/auto/qhash/tst_qhash.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qhash/tst_qhash.cpp')
-rw-r--r--tests/auto/qhash/tst_qhash.cpp1233
1 files changed, 1233 insertions, 0 deletions
diff --git a/tests/auto/qhash/tst_qhash.cpp b/tests/auto/qhash/tst_qhash.cpp
new file mode 100644
index 0000000..73dfe075
--- /dev/null
+++ b/tests/auto/qhash/tst_qhash.cpp
@@ -0,0 +1,1233 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+
+#if QT_VERSION >= 0x040000
+#include <qhash.h>
+#include <qmap.h>
+#endif
+
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QHash : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QHash();
+ virtual ~tst_QHash() {}
+
+private slots:
+ void insert1();
+ void erase();
+ void key();
+
+ void count(); // copied from tst_QMap
+ void clear(); // copied from tst_QMap
+ void empty(); // copied from tst_QMap
+ void find(); // copied from tst_QMap
+ void constFind(); // copied from tst_QMap
+ void contains(); // copied from tst_QMap
+ void take(); // copied from tst_QMap
+ void operator_eq(); // copied from tst_QMap
+ void rehash_isnt_quadratic();
+ void dont_need_default_constructor();
+ void qhash();
+ void qmultihash_specific();
+
+ void compare();
+#if QT_VERSION > 0x040100
+ void compare2();
+#endif // QT_VERSION
+ void iterators(); // sligthly modified from tst_QMap
+ void keys_values_uniqueKeys(); // slightly modified from tst_QMap
+ void noNeedlessRehashes();
+};
+
+struct Foo {
+ static int count;
+ Foo():c(count) { ++count; }
+ Foo(const Foo& o):c(o.c) { ++count; }
+ ~Foo() { --count; }
+ int c;
+ int data[8];
+};
+
+tst_QHash::tst_QHash()
+{}
+
+int Foo::count = 0;
+
+//copied from tst_QMap.cpp
+class MyClass
+{
+public:
+ MyClass() { ++count;
+// qDebug("creating MyClass count=%d", count);
+ }
+ MyClass( const QString& c) {
+ count++; str = c;
+// qDebug("creating MyClass '%s' count = %d", str.latin1(), count);
+ }
+ ~MyClass() {
+ count--;
+// qDebug("deleting MyClass '%s' count = %d", str.latin1(), count);
+ }
+ MyClass( const MyClass& c ) {
+ count++; str = c.str;
+// qDebug("creating MyClass '%s' count = %d", str.latin1(), count);
+ }
+ MyClass &operator =(const MyClass &o) {
+// qDebug("copying MyClass '%s'", o.str.latin1());
+ str = o.str; return *this;
+ }
+
+ QString str;
+ static int count;
+};
+
+int MyClass::count = 0;
+
+typedef QHash<QString, MyClass> MyMap;
+
+//void tst_QMap::count()
+void tst_QHash::count()
+{
+ {
+ MyMap map;
+ MyMap map2( map );
+ QCOMPARE( map.count(), 0 );
+ QCOMPARE( map2.count(), 0 );
+ QCOMPARE( MyClass::count, 0 );
+ // detach
+ map2["Hallo"] = MyClass( "Fritz" );
+ QCOMPARE( map.count(), 0 );
+ QCOMPARE( map2.count(), 1 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 1 );
+#endif
+ }
+ QCOMPARE( MyClass::count, 0 );
+
+ {
+ typedef QHash<QString, MyClass> Map;
+ Map map;
+ QCOMPARE( map.count(), 0);
+ map.insert( "Torben", MyClass("Weis") );
+ QCOMPARE( map.count(), 1 );
+ map.insert( "Claudia", MyClass("Sorg") );
+ QCOMPARE( map.count(), 2 );
+ map.insert( "Lars", MyClass("Linzbach") );
+ map.insert( "Matthias", MyClass("Ettrich") );
+ map.insert( "Sue", MyClass("Paludo") );
+ map.insert( "Eirik", MyClass("Eng") );
+ map.insert( "Haavard", MyClass("Nord") );
+ map.insert( "Arnt", MyClass("Gulbrandsen") );
+ map.insert( "Paul", MyClass("Tvete") );
+ QCOMPARE( map.count(), 9 );
+ map.insert( "Paul", MyClass("Tvete 1") );
+ map.insert( "Paul", MyClass("Tvete 2") );
+ map.insert( "Paul", MyClass("Tvete 3") );
+ map.insert( "Paul", MyClass("Tvete 4") );
+ map.insert( "Paul", MyClass("Tvete 5") );
+ map.insert( "Paul", MyClass("Tvete 6") );
+
+ QCOMPARE( map.count(), 9 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ Map map2( map );
+ QVERIFY( map2.count() == 9 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ map2.insert( "Kay", MyClass("Roemer") );
+ QVERIFY( map2.count() == 10 );
+ QVERIFY( map.count() == 9 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 19 );
+#endif
+
+ map2 = map;
+ QVERIFY( map.count() == 9 );
+ QVERIFY( map2.count() == 9 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ map2.insert( "Kay", MyClass("Roemer") );
+ QVERIFY( map2.count() == 10 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 19 );
+#endif
+
+ map2.clear();
+ QVERIFY( map.count() == 9 );
+ QVERIFY( map2.count() == 0 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ map2 = map;
+ QVERIFY( map.count() == 9 );
+ QVERIFY( map2.count() == 9 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ map2.clear();
+ QVERIFY( map.count() == 9 );
+ QVERIFY( map2.count() == 0 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 9 );
+#endif
+
+ map.remove( "Lars" );
+ QVERIFY( map.count() == 8 );
+ QVERIFY( map2.count() == 0 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 8 );
+#endif
+
+ map.remove( "Mist" );
+ QVERIFY( map.count() == 8 );
+ QVERIFY( map2.count() == 0 );
+#ifndef Q_CC_SUN
+ QCOMPARE( MyClass::count, 8 );
+#endif
+ }
+ QVERIFY( MyClass::count == 0 );
+
+ {
+ typedef QHash<QString,MyClass> Map;
+ Map map;
+ map["Torben"] = MyClass("Weis");
+#ifndef Q_CC_SUN
+ QVERIFY( MyClass::count == 1 );
+#endif
+ QVERIFY( map.count() == 1 );
+
+ (void)map["Torben"].str;
+ (void)map["Lars"].str;
+#ifndef Q_CC_SUN
+ QVERIFY( MyClass::count == 2 );
+#endif
+ QVERIFY( map.count() == 2 );
+
+ const Map& cmap = map;
+ (void)cmap["Depp"].str;
+#ifndef Q_CC_SUN
+ QVERIFY( MyClass::count == 2 );
+#endif
+ QVERIFY( map.count() == 2 );
+ QVERIFY( cmap.count() == 2 );
+ }
+ QCOMPARE( MyClass::count, 0 );
+ {
+ for ( int i = 0; i < 100; ++i )
+ {
+ QHash<int, MyClass> map;
+ for (int j = 0; j < i; ++j)
+ map.insert(j, MyClass(QString::number(j)));
+ }
+ QCOMPARE( MyClass::count, 0 );
+ }
+ QCOMPARE( MyClass::count, 0 );
+}
+void tst_QHash::insert1()
+{
+ const char *hello = "hello";
+ const char *world = "world";
+ const char *allo = "allo";
+ const char *monde = "monde";
+
+ {
+ typedef QHash<QString, QString> Hash;
+ Hash hash;
+ QString key;
+ for (int i = 0; i < 10; ++i) {
+ key[0] = i + '0';
+ for (int j = 0; j < 10; ++j) {
+ key[1] = j + '0';
+ hash.insert(key, "V" + key);
+ }
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ key[0] = i + '0';
+ for (int j = 0; j < 10; ++j) {
+ key[1] = j + '0';
+ hash.remove(key);
+ }
+ }
+ }
+
+ {
+ typedef QHash<int, const char *> Hash;
+ Hash hash;
+ hash.insert(1, hello);
+ hash.insert(2, world);
+
+ QVERIFY(hash.size() == 2);
+ QVERIFY(!hash.isEmpty());
+
+ {
+ Hash hash2 = hash;
+ hash2 = hash;
+ hash = hash2;
+ hash2 = hash2;
+ hash = hash;
+ hash2.clear();
+ hash2 = hash2;
+ QVERIFY(hash2.size() == 0);
+ QVERIFY(hash2.isEmpty());
+ }
+ QVERIFY(hash.size() == 2);
+
+ {
+ Hash hash2 = hash;
+ hash2[1] = allo;
+ hash2[2] = monde;
+
+ QVERIFY(hash2[1] == allo);
+ QVERIFY(hash2[2] == monde);
+ QVERIFY(hash[1] == hello);
+ QVERIFY(hash[2] == world);
+
+ hash2[1] = hash[1];
+ hash2[2] = hash[2];
+
+ QVERIFY(hash2[1] == hello);
+ QVERIFY(hash2[2] == world);
+
+ hash[1] = hash[1];
+ QVERIFY(hash[1] == hello);
+ }
+ {
+ Hash hash2 = hash;
+ hash2.detach();
+ hash2.remove(1);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(1);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(0);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(2);
+ QVERIFY(hash2.size() == 0);
+ QVERIFY(hash.size() == 2);
+ }
+
+ hash.detach();
+
+ {
+ Hash::iterator it1 = hash.find(1);
+ QVERIFY(it1 != hash.end());
+
+ Hash::iterator it2 = hash.find(0);
+ QVERIFY(it2 != hash.begin());
+ QVERIFY(it2 == hash.end());
+
+ *it1 = monde;
+ QVERIFY(*it1 == monde);
+ QVERIFY(hash[1] == monde);
+
+ *it1 = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(hash[1] == hello);
+
+ hash[1] = monde;
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == monde);
+ QVERIFY(*it1 == monde);
+ QVERIFY(hash[1] == monde);
+
+ hash[1] = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(hash[1] == hello);
+ }
+
+ {
+ const Hash hash2 = hash;
+
+ Hash::const_iterator it1 = hash2.find(1);
+ QVERIFY(it1 != hash2.end());
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == hello);
+ QVERIFY(*it1 == hello);
+
+ Hash::const_iterator it2 = hash2.find(2);
+ QVERIFY(it1 != it2);
+ QVERIFY(it1 != hash2.end());
+ QVERIFY(it2 != hash2.end());
+
+ int count = 0;
+ it1 = hash2.begin();
+ while (it1 != hash2.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+
+ count = 0;
+ it1 = hash.begin();
+ while (it1 != hash.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+ }
+
+ {
+ QVERIFY(hash.contains(1));
+ QVERIFY(hash.contains(2));
+ QVERIFY(!hash.contains(0));
+ QVERIFY(!hash.contains(3));
+ }
+
+ {
+ QVERIFY(hash.value(1) == hello);
+ QVERIFY(hash.value(2) == world);
+ QVERIFY(hash.value(3) == 0);
+ QVERIFY(hash.value(1, allo) == hello);
+ QVERIFY(hash.value(2, allo) == world);
+ QVERIFY(hash.value(3, allo) == allo);
+ QVERIFY(hash.value(0, monde) == monde);
+ }
+
+ {
+ QHash<int,Foo> hash;
+ for (int i = 0; i < 10; i++)
+ hash.insert(i, Foo());
+ QVERIFY(Foo::count == 10);
+ hash.remove(7);
+ QVERIFY(Foo::count == 9);
+
+ }
+ QVERIFY(Foo::count == 0);
+ {
+ QHash<int, int*> hash;
+ QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
+ }
+ }
+}
+
+void tst_QHash::erase()
+{
+ QHash<int, int> h1;
+ h1.insert(1, 2);
+ h1.erase(h1.begin());
+ QVERIFY(h1.size() == 0);
+ QVERIFY(h1.begin() == h1.end());
+ h1.insert(3, 4);
+ QVERIFY(*h1.begin() == 4);
+ h1.insert(5, 6);
+ QVERIFY(h1.size() == 2);
+ QHash<int, int>::iterator it1 = h1.begin();
+ ++it1;
+ it1 = h1.erase(it1);
+ QVERIFY(it1 == h1.end());
+ h1.insert(7, 8);
+ h1.insert(9, 10);
+ it1 = h1.begin();
+ int n = 0;
+ while (it1 != h1.end()) {
+ it1 = h1.erase(it1);
+ ++n;
+ }
+ QVERIFY(n == 3);
+ QHash<int, int> h2;
+ h2.insertMulti(20, 41);
+ h2.insertMulti(20, 42);
+ QVERIFY(h2.size() == 2);
+ it1 = h2.erase(h2.begin());
+ it1 = h2.erase(h2.begin());
+ QVERIFY(it1 == h2.end());
+}
+
+void tst_QHash::key()
+{
+ {
+ QString def("default value");
+
+ QHash<QString, int> hash1;
+ QCOMPARE(hash1.key(1), QString());
+ QCOMPARE(hash1.key(1, def), def);
+
+ hash1.insert("one", 1);
+ QCOMPARE(hash1.key(1), QString("one"));
+ QCOMPARE(hash1.key(1, def), QString("one"));
+ QCOMPARE(hash1.key(2), QString());
+ QCOMPARE(hash1.key(2, def), def);
+
+ hash1.insert("two", 2);
+ QCOMPARE(hash1.key(1), QString("one"));
+ QCOMPARE(hash1.key(1, def), QString("one"));
+ QCOMPARE(hash1.key(2), QString("two"));
+ QCOMPARE(hash1.key(2, def), QString("two"));
+ QCOMPARE(hash1.key(3), QString());
+ QCOMPARE(hash1.key(3, def), def);
+
+ hash1.insert("deux", 2);
+ QCOMPARE(hash1.key(1), QString("one"));
+ QCOMPARE(hash1.key(1, def), QString("one"));
+ QVERIFY(hash1.key(2) == "deux" || hash1.key(2) == "two");
+ QVERIFY(hash1.key(2, def) == "deux" || hash1.key(2, def) == "two");
+ QCOMPARE(hash1.key(3), QString());
+ QCOMPARE(hash1.key(3, def), def);
+ }
+
+ {
+ int def = 666;
+
+ QHash<int, QString> hash2;
+ QCOMPARE(hash2.key("one"), 0);
+ QCOMPARE(hash2.key("one", def), def);
+
+ hash2.insert(1, "one");
+ QCOMPARE(hash2.key("one"), 1);
+ QCOMPARE(hash2.key("one", def), 1);
+ QCOMPARE(hash2.key("two"), 0);
+ QCOMPARE(hash2.key("two", def), def);
+
+ hash2.insert(2, "two");
+ QCOMPARE(hash2.key("one"), 1);
+ QCOMPARE(hash2.key("one", def), 1);
+ QCOMPARE(hash2.key("two"), 2);
+ QCOMPARE(hash2.key("two", def), 2);
+ QCOMPARE(hash2.key("three"), 0);
+ QCOMPARE(hash2.key("three", def), def);
+
+ hash2.insert(3, "two");
+ QCOMPARE(hash2.key("one"), 1);
+ QCOMPARE(hash2.key("one", def), 1);
+ QCOMPARE(hash2.key("two"), 2);
+ QCOMPARE(hash2.key("two", def), 2);
+ QCOMPARE(hash2.key("three"), 0);
+ QCOMPARE(hash2.key("three", def), def);
+
+ hash2.insert(-1, "two");
+ QCOMPARE(hash2.key("two"), -1);
+ QCOMPARE(hash2.key("two", def), -1);
+
+ hash2.insert(0, "zero");
+ QCOMPARE(hash2.key("zero"), 0);
+ QCOMPARE(hash2.key("zero", def), 0);
+ }
+}
+
+// copied from tst_QMap
+void tst_QHash::clear()
+{
+ {
+ MyMap map;
+ map.clear();
+ QVERIFY( map.isEmpty() );
+ map.insert( "key", MyClass( "value" ) );
+ map.clear();
+ QVERIFY( map.isEmpty() );
+ map.insert( "key0", MyClass( "value0" ) );
+ map.insert( "key0", MyClass( "value1" ) );
+ map.insert( "key1", MyClass( "value2" ) );
+ map.clear();
+ QVERIFY( map.isEmpty() );
+ }
+ QCOMPARE( MyClass::count, int(0) );
+}
+//copied from tst_QMap
+void tst_QHash::empty()
+{
+ QHash<int, QString> map1;
+
+ QVERIFY(map1.isEmpty());
+
+ map1.insert(1, "one");
+ QVERIFY(!map1.isEmpty());
+
+ map1.clear();
+ QVERIFY(map1.isEmpty());
+
+}
+
+//copied from tst_QMap
+void tst_QHash::find()
+{
+ QHash<int, QString> map1;
+ QString testString="Teststring %0";
+ QString compareString;
+ int i,count=0;
+
+ //QVERIFY(map1.find(1) == map1.end());
+
+ map1.insert(1,"Mensch");
+ map1.insert(1,"Mayer");
+ map1.insert(2,"Hej");
+
+ QVERIFY(map1.find(1).value() == "Mayer");
+ QVERIFY(map1.find(2).value() == "Hej");
+
+ for(i = 3; i < 10; ++i) {
+ compareString = testString.arg(i);
+ map1.insertMulti(4, compareString);
+ }
+
+ QHash<int, QString>::const_iterator it=map1.find(4);
+
+ for(i = 9; i > 2 && it != map1.end() && it.key() == 4; --i) {
+ compareString = testString.arg(i);
+ QVERIFY(it.value() == compareString);
+ ++it;
+ ++count;
+ }
+ QCOMPARE(count, 7);
+}
+
+// copied from tst_QMap
+void tst_QHash::constFind()
+{
+ QHash<int, QString> map1;
+ QString testString="Teststring %0";
+ QString compareString;
+ int i,count=0;
+
+ QVERIFY(map1.constFind(1) == map1.constEnd());
+
+ map1.insert(1,"Mensch");
+ map1.insert(1,"Mayer");
+ map1.insert(2,"Hej");
+
+ QVERIFY(map1.constFind(1).value() == "Mayer");
+ QVERIFY(map1.constFind(2).value() == "Hej");
+
+ for(i = 3; i < 10; ++i) {
+ compareString = testString.arg(i);
+ map1.insertMulti(4, compareString);
+ }
+
+ QHash<int, QString>::const_iterator it=map1.constFind(4);
+
+ for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ compareString = testString.arg(i);
+ QVERIFY(it.value() == compareString);
+ ++it;
+ ++count;
+ }
+ QCOMPARE(count, 7);
+}
+
+// copied from tst_QMap
+void tst_QHash::contains()
+{
+ QHash<int, QString> map1;
+ int i;
+
+ map1.insert(1, "one");
+ QVERIFY(map1.contains(1));
+
+ for(i=2; i < 100; ++i)
+ map1.insert(i, "teststring");
+ for(i=99; i > 1; --i)
+ QVERIFY(map1.contains(i));
+
+ map1.remove(43);
+ QVERIFY(!map1.contains(43));
+}
+
+//copied from tst_QMap
+void tst_QHash::take()
+{
+ QHash<int, QString> map;
+
+ map.insert(2, "zwei");
+ map.insert(3, "drei");
+
+ QVERIFY(map.take(3) == "drei");
+ QVERIFY(!map.contains(3));
+}
+
+//copied from tst_QMap
+void tst_QHash::operator_eq()
+{
+ {
+ // compare for equality:
+ QHash<int, int> a;
+ QHash<int, int> b;
+
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+
+ a.insert(1,1);
+ b.insert(1,1);
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+
+ a.insert(0,1);
+ b.insert(0,1);
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+
+ // compare for inequality:
+ a.insert(42,0);
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+
+ a.insert(65, -1);
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+
+ b.insert(-1, -1);
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+ }
+
+ {
+ // a more complex map
+ QHash<QString, QString> a;
+ QHash<QString, QString> b;
+
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+
+ a.insert("Hello", "World");
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+
+ b.insert("Hello", "World");
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+
+ a.insert("Goodbye", "cruel world");
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+
+ b.insert("Goodbye", "cruel world");
+
+ // what happens if we insert nulls?
+ a.insert(QString(), QString());
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+
+ // empty keys and null keys match:
+ b.insert(QString(""), QString());
+ QVERIFY(a == b);
+ QVERIFY(!(a != b));
+ }
+
+ {
+ // task 102658
+
+ QHash<QString, int> a;
+ QHash<QString, int> b;
+
+ a.insert("otto", 1);
+ b.insert("willy", 1);
+ QVERIFY(a != b);
+ QVERIFY(!(a == b));
+ }
+}
+
+void tst_QHash::compare()
+{
+ QHash<int, QString> hash1,hash2;
+ QString testString = "Teststring %1";
+ int i;
+
+ for(i = 0; i < 1000; ++i)
+ hash1.insert(i,testString.arg(i));
+
+ for(--i; i >= 0; --i)
+ hash2.insert(i,testString.arg(i));
+
+ hash1.squeeze();
+ hash2.squeeze();
+
+ QVERIFY(hash1 == hash2);
+ QVERIFY(!(hash1 != hash2));
+
+ hash1.take(234);
+ hash2.take(234);
+ QVERIFY(hash1 == hash2);
+ QVERIFY(!(hash1 != hash2));
+
+ hash2.take(261);
+ QVERIFY(!(hash1 == hash2));
+ QVERIFY(hash1 != hash2);
+}
+
+#if QT_VERSION > 0x040100
+void tst_QHash::compare2()
+{
+ QHash<int, int> a;
+ QHash<int, int> b;
+
+ a.insertMulti(17, 1);
+ a.insertMulti(17 * 2, 1);
+ b.insertMulti(17 * 2, 1);
+ b.insertMulti(17, 1);
+ QVERIFY(a == b);
+ QVERIFY(b == a);
+
+ a.insertMulti(17, 2);
+ a.insertMulti(17 * 2, 3);
+ b.insertMulti(17 * 2, 3);
+ b.insertMulti(17, 2);
+ QVERIFY(a == b);
+ QVERIFY(b == a);
+
+ a.insertMulti(17, 4);
+ a.insertMulti(17 * 2, 5);
+ b.insertMulti(17 * 2, 4);
+ b.insertMulti(17, 5);
+ QVERIFY(!(a == b));
+ QVERIFY(!(b == a));
+
+ a.clear();
+ b.clear();
+ a.insertMulti(1, 1);
+ a.insertMulti(1, 2);
+ a.insertMulti(1, 3);
+ b.insertMulti(1, 1);
+ b.insertMulti(1, 2);
+ b.insertMulti(1, 3);
+ b.insertMulti(1, 4);
+ QVERIFY(!(a == b));
+ QVERIFY(!(b == a));
+}
+#endif // QT_VERSION
+
+//sligthly modified from tst_QMap
+void tst_QHash::iterators()
+{
+ QHash<int, QString> hash;
+ QMap<int, QString> testMap;
+ QString testString="Teststring %1";
+ QString testString1;
+ int i;
+
+ for(i = 1; i < 100; ++i)
+ hash.insert(i, testString.arg(i));
+
+ //to get some chaos in the hash
+ hash.squeeze();
+
+ //STL-Style iterators
+
+ QHash<int, QString>::iterator stlIt = hash.begin();
+ for(stlIt = hash.begin(), i = 1; stlIt != hash.end(), i < 100; ++stlIt, ++i) {
+ testMap.insert(i,stlIt.value());
+ //QVERIFY(stlIt.value() == hash.value(
+ }
+ stlIt = hash.begin();
+
+ QVERIFY(stlIt.value() == testMap.value(1));
+
+ stlIt+=5;
+ QVERIFY(stlIt.value() == testMap.value(6));
+
+ stlIt++;
+ QVERIFY(stlIt.value() == testMap.value(7));
+
+ stlIt-=3;
+ QVERIFY(stlIt.value() == testMap.value(4));
+
+ stlIt--;
+ QVERIFY(stlIt.value() == testMap.value(3));
+
+ testMap.clear();
+
+ //STL-Style const-iterators
+
+ QHash<int, QString>::const_iterator cstlIt = hash.constBegin();
+ for(cstlIt = hash.constBegin(), i = 1; cstlIt != hash.constEnd(), i < 100; ++cstlIt, ++i) {
+ testMap.insert(i,cstlIt.value());
+ //QVERIFY(stlIt.value() == hash.value(
+ }
+ cstlIt = hash.constBegin();
+
+ QVERIFY(cstlIt.value() == testMap.value(1));
+
+ cstlIt+=5;
+ QVERIFY(cstlIt.value() == testMap.value(6));
+
+ cstlIt++;
+ QVERIFY(cstlIt.value() == testMap.value(7));
+
+ cstlIt-=3;
+ QVERIFY(cstlIt.value() == testMap.value(4));
+
+ cstlIt--;
+ QVERIFY(cstlIt.value() == testMap.value(3));
+
+ testMap.clear();
+
+ //Java-Style iterators
+
+ QHashIterator<int, QString> javaIt(hash);
+
+ //walk through
+ i = 0;
+ while(javaIt.hasNext()) {
+ ++i;
+ javaIt.next();
+ testMap.insert(i,javaIt.value());
+ }
+ javaIt.toFront();
+ i = 0;
+ while(javaIt.hasNext()) {
+ ++i;
+ javaIt.next();
+ //qDebug(javaIt.value());
+ QVERIFY(javaIt.value() == testMap.value(i));
+ }
+
+ ++i;
+ while(javaIt.hasPrevious()) {
+ --i;
+ javaIt.previous();
+ QVERIFY(javaIt.value() == testMap.value(i));
+ }
+
+ /*
+ I've removed findNextKey() and findPreviousKey() from the API
+ for Qt 4.0 beta 1.
+ */
+
+#if 0
+ //findPreviousKey() findNextKey()
+ for(i = 1; i < 100; ++i) {
+ if(javaIt.findNextKey(i))
+ QVERIFY(javaIt.value() == testString.arg(i));
+ else {
+ QVERIFY(!javaIt.hasNext());
+ QVERIFY(javaIt.findPreviousKey(i));
+ QVERIFY(javaIt.value() == testString.arg(i));
+ }
+
+ if(javaIt.findPreviousKey(i))
+ QVERIFY(javaIt.value() == testString.arg(i));
+ else {
+ QVERIFY(!javaIt.hasPrevious());
+ QVERIFY(javaIt.findNextKey(i));
+ QVERIFY(javaIt.value() == testString.arg(i));
+ }
+ }
+#endif
+
+ //peekNext() peekPrevious()
+ javaIt.toFront();
+ javaIt.next();
+ while(javaIt.hasNext()) {
+ testString = javaIt.value();
+ testString1 = javaIt.peekNext().value();
+ javaIt.next();
+ //qDebug(testString + " " + testString1 + " " + javaIt.peekPrevious().value());
+ QVERIFY(javaIt.value() == testString1);
+ QCOMPARE(javaIt.peekPrevious().value(), testString1);
+ }
+ while(javaIt.hasPrevious()) {
+ testString = javaIt.value();
+ testString1 = javaIt.peekPrevious().value();
+ javaIt.previous();
+ QVERIFY(javaIt.value() == testString1);
+ //qDebug(testString + testString1 + javaIt.peekNext().value());
+ QCOMPARE(javaIt.peekNext().value(), testString1);
+ }
+}
+
+void tst_QHash::rehash_isnt_quadratic()
+{
+ // this test should be incredibly slow if rehash() is quadratic
+ for (int j = 0; j < 5; ++j) {
+ QHash<int, int> testHash;
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) // mobiles do not have infinite mem...
+ for (int i = 0; i < 50000; ++i)
+#else
+ for (int i = 0; i < 500000; ++i)
+#endif
+ testHash.insertMulti(1, 1);
+ }
+}
+
+class Bar
+{
+public:
+#if QT_VERSION < 0x040100
+ Bar() : j(0) {}
+#endif
+ Bar(int i) : j(i) {}
+
+ int j;
+};
+
+void tst_QHash::dont_need_default_constructor()
+{
+ QHash<int, Bar> hash1;
+ for (int i = 0; i < 100; ++i) {
+ hash1.insert(i, Bar(2 * i));
+ QVERIFY(hash1.value(i, Bar(-1)).j == 2 * i);
+ QVERIFY(hash1.size() == i + 1);
+ }
+
+ QHash<QString, Bar> hash2;
+ for (int i = 0; i < 100; ++i) {
+ hash2.insert(QString::number(i), Bar(2 * i));
+ QVERIFY(hash2.value(QString::number(i), Bar(-1)).j == 2 * i);
+ QVERIFY(hash2.size() == i + 1);
+ }
+}
+
+void tst_QHash::qhash()
+{
+ {
+ QBitArray a1;
+ QBitArray a2;
+ QVERIFY(qHash(a1) == 0);
+
+ a1.resize(1);
+ a1.setBit(0, true);
+
+ a2.resize(1);
+ a2.setBit(0, false);
+
+ uint h1 = qHash(a1);
+ uint h2 = qHash(a2);
+
+ QVERIFY(h1 != h2);
+
+ a2.setBit(0, true);
+ QVERIFY(h1 == qHash(a2));
+
+ a1.fill(true, 8);
+ a1.resize(7);
+
+ h1 = qHash(a1);
+
+ a2.fill(true, 7);
+ h2 = qHash(a2);
+
+ QVERIFY(h1 == h2);
+
+ a2.setBit(0, false);
+ uint h3 = qHash(a2);
+ QVERIFY(h2 != h3);
+
+ a2.setBit(0, true);
+ QVERIFY(h2 == qHash(a2));
+
+ a2.setBit(6, false);
+ uint h4 = qHash(a2);
+ QVERIFY(h2 != h4);
+
+ a2.setBit(6, true);
+ QVERIFY(h2 == qHash(a2));
+
+ QVERIFY(h3 != h4);
+ }
+
+ {
+ QPair<int, int> p12(1, 2);
+ QPair<int, int> p21(2, 1);
+
+ QVERIFY(qHash(p12) == qHash(p12));
+ QVERIFY(qHash(p21) == qHash(p21));
+ QVERIFY(qHash(p12) != qHash(p21));
+
+ QPair<int, int> pA(0x12345678, 0x12345678);
+ QPair<int, int> pB(0x12345675, 0x12345675);
+
+ QVERIFY(qHash(pA) != qHash(pB));
+ }
+}
+
+void tst_QHash::qmultihash_specific()
+{
+ QMultiHash<int, int> hash1;
+ for (int i = 1; i <= 9; ++i) {
+ for (int j = 1; j <= i; ++j) {
+ int k = i * 10 + j;
+ QVERIFY(!hash1.contains(i, k));
+ hash1.insert(i, k);
+ QVERIFY(hash1.contains(i, k));
+ }
+ }
+
+ for (int i = 1; i <= 9; ++i) {
+ for (int j = 1; j <= i; ++j) {
+ int k = i * 10 + j;
+ QVERIFY(hash1.contains(i, k));
+ }
+ }
+
+ QVERIFY(hash1.contains(9, 99));
+ QCOMPARE(hash1.count(), 45);
+ hash1.remove(9, 99);
+ QVERIFY(!hash1.contains(9, 99));
+ QCOMPARE(hash1.count(), 44);
+
+ hash1.remove(9, 99);
+ QVERIFY(!hash1.contains(9, 99));
+ QCOMPARE(hash1.count(), 44);
+
+ hash1.remove(1, 99);
+ QCOMPARE(hash1.count(), 44);
+
+ hash1.insert(1, 99);
+ hash1.insert(1, 99);
+
+ QCOMPARE(hash1.count(), 46);
+ hash1.remove(1, 99);
+ QCOMPARE(hash1.count(), 44);
+ hash1.remove(1, 99);
+ QCOMPARE(hash1.count(), 44);
+
+ {
+ QMultiHash<int, int>::const_iterator i = hash1.constFind(1, 11);
+ QVERIFY(i.key() == 1);
+ QVERIFY(i.value() == 11);
+
+ i = hash1.constFind(2, 22);
+ QVERIFY(i.key() == 2);
+ QVERIFY(i.value() == 22);
+
+ i = hash1.constFind(9, 98);
+ QVERIFY(i.key() == 9);
+ QVERIFY(i.value() == 98);
+ }
+
+ {
+ const QMultiHash<int, int> hash2(hash1);
+ QMultiHash<int, int>::const_iterator i = hash2.find(1, 11);
+ QVERIFY(i.key() == 1);
+ QVERIFY(i.value() == 11);
+
+ i = hash2.find(2, 22);
+ QVERIFY(i.key() == 2);
+ QVERIFY(i.value() == 22);
+
+ i = hash2.find(9, 98);
+ QVERIFY(i.key() == 9);
+ QVERIFY(i.value() == 98);
+ }
+
+ {
+ QMultiHash<int, int>::iterator i = hash1.find(1, 11);
+ QVERIFY(i.key() == 1);
+ QVERIFY(i.value() == 11);
+
+ i = hash1.find(2, 22);
+ QVERIFY(i.key() == 2);
+ QVERIFY(i.value() == 22);
+
+ i = hash1.find(9, 98);
+ QVERIFY(i.key() == 9);
+ QVERIFY(i.value() == 98);
+ }
+}
+
+template <typename T>
+QList<T> sorted(const QList<T> &list)
+{
+ QList<T> res = list;
+ qSort(res);
+ return res;
+}
+
+void tst_QHash::keys_values_uniqueKeys()
+{
+ QHash<QString, int> hash;
+#if QT_VERSION >= 0x040200
+ QVERIFY(hash.uniqueKeys().isEmpty());
+#endif
+ QVERIFY(hash.keys().isEmpty());
+ QVERIFY(hash.values().isEmpty());
+
+ hash.insertMulti("alpha", 1);
+ QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha"));
+#if QT_VERSION >= 0x040200
+ QVERIFY(hash.keys() == hash.uniqueKeys());
+#endif
+ QVERIFY(hash.values() == (QList<int>() << 1));
+
+ hash.insertMulti("beta", -2);
+ QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "beta"));
+#if QT_VERSION >= 0x040200
+ QVERIFY(hash.keys() == hash.uniqueKeys());
+#endif
+ QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 1 << -2));
+
+ hash.insertMulti("alpha", 2);
+#if QT_VERSION >= 0x040200
+ QVERIFY(sorted(hash.uniqueKeys()) == (QList<QString>() << "alpha" << "beta"));
+#endif
+ QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "alpha" << "beta"));
+ QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 2 << 1 << -2));
+
+ hash.insertMulti("beta", 4);
+#if QT_VERSION >= 0x040200
+ QVERIFY(sorted(hash.uniqueKeys()) == (QList<QString>() << "alpha" << "beta"));
+#endif
+ QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "alpha" << "beta" << "beta"));
+ QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 2 << 1 << 4 << -2));
+}
+
+void tst_QHash::noNeedlessRehashes()
+{
+ QHash<int, int> hash;
+ for (int i = 0; i < 512; ++i) {
+ int j = (i * 345) % 512;
+ hash.insert(j, j);
+ int oldCapacity = hash.capacity();
+ hash[j] = j + 1;
+ QCOMPARE(oldCapacity, hash.capacity());
+ hash.insert(j, j + 1);
+ QCOMPARE(oldCapacity, hash.capacity());
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QHash)
+#include "tst_qhash.moc"