diff options
Diffstat (limited to 'tests/auto/other')
-rw-r--r-- | tests/auto/other/collections/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/other/collections/collections.pro | 9 | ||||
-rw-r--r-- | tests/auto/other/collections/tst_collections.cpp | 3762 | ||||
-rw-r--r-- | tests/auto/other/compiler/compiler.pro | 4 | ||||
-rw-r--r-- | tests/auto/other/compiler/othersource.cpp | 51 | ||||
-rw-r--r-- | tests/auto/other/compiler/tst_compiler.cpp | 758 | ||||
-rw-r--r-- | tests/auto/other/lancelot/scripts/text.qps | 12 | ||||
-rw-r--r-- | tests/auto/other/other.pro | 1 | ||||
-rw-r--r-- | tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 237 | ||||
-rw-r--r-- | tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp | 76 | ||||
-rw-r--r-- | tests/auto/other/qobjectrace/tst_qobjectrace.cpp | 25 | ||||
-rw-r--r-- | tests/auto/other/qvariant_common/tst_qvariant_common.h | 27 |
12 files changed, 1088 insertions, 3875 deletions
diff --git a/tests/auto/other/collections/.gitignore b/tests/auto/other/collections/.gitignore deleted file mode 100644 index dcd9d49ec0..0000000000 --- a/tests/auto/other/collections/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_collections diff --git a/tests/auto/other/collections/collections.pro b/tests/auto/other/collections/collections.pro deleted file mode 100644 index 51ea667f58..0000000000 --- a/tests/auto/other/collections/collections.pro +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG += testcase -TARGET = tst_collections -SOURCES += tst_collections.cpp -QT = core testlib -CONFIG += parallel_test - -# This test does not work with strict iterators -DEFINES -= QT_STRICT_ITERATORS -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp deleted file mode 100644 index 17ed9c8a45..0000000000 --- a/tests/auto/other/collections/tst_collections.cpp +++ /dev/null @@ -1,3762 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// test the container forwards -#include <QtContainerFwd> - -static QCache<int, int> *cacheX; -static QHash<int, int> *hashX; -static QLinkedList<int> *linkedListX; -static QList<int> *listX; -static QMap<int, int> *mapX; -static QMultiHash<int, int> *multiHashX; -static QMultiMap<int, int> *multiMapX; -static QPair<int, int> *pairX; -static QQueue<int> *queueX; -static QSet<int> *setX; -static QStack<int> *stackX; -static QVarLengthArray<int> *varLengthArrayX; -static QVarLengthArray<int, 512> *varLengthArrayY; -static QVector<int> *vectorX; - -void foo() -{ - cacheX = 0; - hashX = 0; - linkedListX = 0; - listX = 0; - mapX = 0; - multiHashX = 0; - multiMapX = 0; - pairX = 0; - queueX = 0; - setX = 0; - stackX = 0; - varLengthArrayX = 0; - varLengthArrayY = 0; - vectorX = 0; -} - -#include <QtTest/QtTest> - -#include <algorithm> - -#include "qalgorithms.h" -#include "qbitarray.h" -#include "qbytearray.h" -#include "qcache.h" -#include "qhash.h" -#include "qlinkedlist.h" -#include "qlist.h" -#include "qmap.h" -#include "qpair.h" -#include "qregexp.h" -#include "qset.h" -#include "qstack.h" -#include "qstring.h" -#include "qstringlist.h" -#include "qvarlengtharray.h" -#include "qvector.h" -#include "qqueue.h" - -template class QList<int>; - -class tst_Collections : public QObject -{ - Q_OBJECT - -public: - tst_Collections(); - ~tst_Collections(); - -public slots: - void init(); - void cleanup(); -private slots: - void typeinfo(); - void qstring(); - void list(); - void linkedList(); - void vector(); - void byteArray(); - void stack(); - void hash(); - void map(); - void bitArray(); - void cache(); - void regexp(); - void pair(); - void sharableQList(); - void sharableQLinkedList(); - void sharableQVector(); - void sharableQMap(); - void sharableQHash(); - void q_foreach(); - void conversions(); - void javaStyleIterators(); - void constAndNonConstStlIterators(); - void vector_stl_data(); - void vector_stl(); - void list_stl_data(); - void list_stl(); - void linkedlist_stl_data(); - void linkedlist_stl(); - void q_init(); - void pointersize(); - void containerInstantiation(); - void qtimerList(); - void containerTypedefs(); - void forwardDeclared(); - void alignment(); - void QTBUG13079_collectionInsideCollection(); - - void foreach_2(); - void insert_remove_loop(); -}; - -struct LargeStatic { - static int count; - LargeStatic():c(count) { ++count; } - LargeStatic(const LargeStatic& o):c(o.c) { ++count; } - ~LargeStatic() { --count; } - int c; - int data[8]; -}; - -int LargeStatic::count = 0; - -struct Movable { - static int count; - Movable():c(count) { ++count; } - Movable(const Movable& o):c(o.c) { ++count; } - ~Movable() { --count; } - int c; -}; - -int Movable::count = 0; -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); -QT_END_NAMESPACE - - -struct Pod { - int i1, i2; -}; - -tst_Collections::tst_Collections() -{ -} - -tst_Collections::~tst_Collections() -{ - -} - -void tst_Collections::init() -{ -} - -void tst_Collections::cleanup() -{ -} - -void tst_Collections::typeinfo() -{ - QVERIFY(QTypeInfo<int*>::isPointer); - QVERIFY(!QTypeInfo<int>::isPointer); - QVERIFY(QTypeInfo<QString>::isComplex); - QVERIFY(!QTypeInfo<int>::isComplex); -} - -void tst_Collections::list() -{ - { - QList<int> list; - QVERIFY(list.isEmpty()); - list.append(1); - QVERIFY(list.size() == 1); - - QVERIFY(*list.begin() == 1); - - list.push_back(2); - list += (3); - list << 4 << 5 << 6; - QVERIFY(!list.isEmpty()); - QVERIFY(list.size() == 6); - QVERIFY(list.end() - list.begin() == list.size()); - -#if !defined(Q_CC_MSVC) && !defined(Q_CC_SUN) - QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true); - QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false); -#endif - QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1); - QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1); - QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2); - QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end()); - QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end()); - QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end()); - { - int sum = 0; - QListIterator<int> i(list); - while (i.hasNext()) - sum += i.next(); - QVERIFY(sum == 21); - } - - { - QList<int> list1; - list1 << 1 << 2 << 3 << 5 << 7 << 8 << 9; - QList<int> list2 = list1; - - QMutableListIterator<int> i1(list1); - while (i1.hasNext()) { - if (i1.next() % 2 != 0) - i1.remove(); - } - - QMutableListIterator<int> i2(list2); - i2.toBack(); - while (i2.hasPrevious()) { - if (i2.previous() % 2 != 0) - i2.remove(); - } - QVERIFY(list1.size() == 2); - QVERIFY(list2.size() == 2); - QVERIFY(list1 == list2); - } - - { - int sum = 0; - for (int i = 0; i < list.size(); ++i) - sum += list[i]; - QVERIFY(sum == 21); - } - { - int sum = 0; - QList<int>::const_iterator i = list.begin(); - while (i != list.end()) - sum += *i++; - QVERIFY(sum == 21); - } - { - int sum = 0; - QList<int>::ConstIterator i = list.begin(); - while (i != list.end()) - sum += *i++; - QVERIFY(sum == 21); - } - { - QList<int>::Iterator i = list.begin(); - i += 2; - QCOMPARE(*i, 3); - i -= 1; - QCOMPARE(*i, 2); - } - { - QList<int>::ConstIterator i = list.begin(); - i += 2; - QCOMPARE(*i, 3); - i -= 1; - QCOMPARE(*i, 2); - } - { - int sum = 0; - int i; - for (i = 0; i < list.size(); ++i) - list[i] = list[i] +1; - for (i = 0; i < list.size(); ++i) - sum += list[i]; - QVERIFY(sum == 21 + list.size()); - } - { - int sum = 0; - int i; - for (i = 0; i < list.size(); ++i) - --list[i]; - for (i = 0; i < list.size(); ++i) - sum += list[i]; - QVERIFY(sum == 21); - } - { - QMutableListIterator<int> i(list); - while (i.hasNext()) - i.setValue(2*i.next()); - } - { - int sum = 0; - QListIterator<int> i(list); - i.toBack(); - while (i.hasPrevious()) - sum += i.previous(); - QVERIFY(sum == 2*21); - } - { - QMutableListIterator<int> i(list); - i.toBack(); - while (i.hasPrevious()) - i.setValue(2*i.previous()); - } - { - int sum = 0; - QListIterator<int> i(list); - i.toBack(); - while (i.hasPrevious()) - sum += i.previous(); - QVERIFY(sum == 2*2*21); - } - { - QMutableListIterator<int> i(list); - while (i.hasNext()) { - int a = i.next(); - i.insert(a); - } - } - { - int sum = 0; - QList<int>::iterator i = list.begin(); - while (i != list.end()) - sum += *i++; - QVERIFY(sum == 2*2*2*21); - } - { - int duplicates = 0; - QListIterator<int> i(list); - while (i.hasNext()) { - int a = i.next(); - if (i.hasNext() && a == i.peekNext()) - duplicates++; - } - QVERIFY(duplicates == 6); - } - { - int duplicates = 0; - QListIterator<int> i(list); - i.toBack(); - while (i.hasPrevious()) { - int a = i.previous(); - if (i.hasPrevious() && a == i.peekPrevious()) - duplicates++; - } - QVERIFY(duplicates == 6); - } - { - QMutableListIterator<int> i(list); - while (i.hasNext()) { - int a = i.next(); - if (i.hasNext() && - i.peekNext() == a) - i.remove(); - } - } - { - int duplicates = 0; - QMutableListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) { - int a = i.previous(); - if (i.hasPrevious() && a == i.peekPrevious()) - duplicates++; - } - QVERIFY(duplicates == 0); - } - { - QVERIFY(list.size() == 6); - QMutableListIterator<int> i = list; - while (i.hasNext()) { - int a = i.peekNext(); - i.insert(42); - QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a); - i.next(); - } - QVERIFY(list.size() == 12); - i.toFront(); - while (i.findNext(42)) - i.remove(); - } - { - QList<int> l; - l << 4 << 8 << 12 << 16 << 20 << 24; - QVERIFY(l == list); - QList<int> copy = list; - list += list; - QVERIFY(l != list && l.size() == list.size()/2 && l == copy); - l += copy; - QVERIFY(l == list); - list = copy; - } - { - QList<int> copy = list; - list << 8; - QVERIFY(list.indexOf(8) == 1); - QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6); - int a = list.indexOf(8); - QVERIFY(list.count(8) == 2); - int r = list.removeAll(8); - QVERIFY(r == 2); - list.insert(a, 8); - QVERIFY(list == copy); - } - { - QList<QString> list; - list << "one" << "two" << "three" << "four" << "five" << "six"; - while (!list.isEmpty()) - list.removeAll(list.first()); - } - { - QList<QString> list; - list << "one" << "two" << "one" << "two"; - QVERIFY(!list.removeOne("three")); - QVERIFY(list.removeOne("two")); - QCOMPARE(list, QList<QString>() << "one" << "one" << "two");; - QVERIFY(list.removeOne("two")); - QCOMPARE(list, QList<QString>() << "one" << "one"); - QVERIFY(!list.removeOne("two")); - QCOMPARE(list, QList<QString>() << "one" << "one"); - QVERIFY(list.removeOne("one")); - QCOMPARE(list, QList<QString>() << "one"); - QVERIFY(list.removeOne("one")); - QVERIFY(list.isEmpty()); - QVERIFY(!list.removeOne("one")); - QVERIFY(list.isEmpty()); - } - { - QList<int> copy = list; - list << 8; - QVERIFY(list.lastIndexOf(8) == 6); - QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1); - list = copy; - } - { - QList<int> copy = list; - list.insert(3, 999); - QVERIFY(list[3] == 999); - list.replace(3, 222); - QVERIFY(list[3] == 222); - QVERIFY(list.contains(222) && ! list.contains(999)); - list.removeAt(3); - list = copy; - QVERIFY(list == copy); - } - { - list.clear(); - QVERIFY(list.isEmpty()); - QVERIFY(list.begin() == list.end()); - QListIterator<int> i(list); - QVERIFY(!i.hasNext() && !i.hasPrevious()); - } - { - QList<int> l1; - QList<int> l2; - l1 << 1 << 2 << 3; - l2 << 4 << 5 << 6; - QList<int> l3 = l1 + l2; - l1 += l2; - QVERIFY(l3 == l1); - } - { - QList<int> list; - QVERIFY(list.isEmpty()); - list.append(1); - QList<int> list2; - list2 = list; - list2.clear(); - QVERIFY(list2.size() == 0); - QVERIFY(list.size() == 1); - } - { - QList<int> list; - list.append(1); - list = list; - QVERIFY(list.size() == 1); - } - } - { - QList<void*> list; - list.append(0); - list.append((void*)42); - QCOMPARE(list.size(), 2); - QCOMPARE(list.at(0), (void*)0); - QCOMPARE(list.at(1), (void*)42); - } - - { - QVector<QString> vector(5); - vector[0] = "99"; - vector[4] ="100"; - QList<QString> list = vector.toList(); - - QVERIFY(list.size() == 5); - QVERIFY(list.at(0) == "99"); - QVERIFY(list.at(4) == "100"); - list[0] = "10"; - QVERIFY(list.at(0) == "10"); - QVERIFY(vector.at(0) == "99"); - - } - - { - QList<QString> list; - list.append("Hello"); - - QList<QString>::iterator it = list.begin(); - QVERIFY((*it)[0] == QChar('H')); - QVERIFY(it->constData()[0] == QChar('H')); - it->replace(QChar('H'), QChar('X')); - QVERIFY(list.first() == "Xello"); - - QList<QString>::const_iterator cit = list.constBegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - - cit = list.cbegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - } - - { - QList<int *> list; - QVERIFY(list.value(0) == 0); - int i; - list.append(&i); - QVERIFY(list.value(0) == &i); - } - { - QList<const int *> list; - QVERIFY(list.value(0) == 0); - int i; - list.append(&i); - QVERIFY(list.value(0) == &i); - } - { - QList<int> list; - QVERIFY(list.value(0) == 0); - list.append(10); - QVERIFY(list.value(0) == 10); - } - { - QList<Pod> list; - QCOMPARE(list.value(0).i1, 0); - QCOMPARE(list.value(0).i2, 0); - } - - { - QList<QString> list; - list << "alpha" << "beta"; - list += list; - QVERIFY(list.size() == 4); - QVERIFY(list.at(0) == "alpha"); - QVERIFY(list.at(1) == "beta"); - QVERIFY(list.at(2) == "alpha"); - QVERIFY(list.at(3) == "beta"); - } - - // test endcases for inserting into a qlist - { - QList<QString> list; - list << "foo" << "bar"; - QVERIFY(!list.isEmpty()); - - list.insert(-1, "lessthanzero"); - QCOMPARE(list.at(0), QString("lessthanzero")); - - list.insert(0, "atzero"); - QCOMPARE(list.at(0), QString("atzero")); - - int listCount = list.count(); - list.insert(listCount, "atcount"); - QCOMPARE(list.at(listCount), QString("atcount")); - - listCount = list.count(); - list.insert(listCount + 1, "beyondcount"); - QCOMPARE(list.at(listCount), QString("beyondcount")); - } - - { - QList<int> list1; - list1 << 0 << 1 << 2 << 3; - list1.removeFirst(); - - list1.swap(0, 0); - QVERIFY(list1 == QList<int>() << 1 << 2 << 3); - - list1.swap(1, 1); - QVERIFY(list1 == QList<int>() << 1 << 2 << 3); - - list1.swap(2, 2); - QVERIFY(list1 == QList<int>() << 1 << 2 << 3); - - list1.swap(0, 1); - QVERIFY(list1 == QList<int>() << 2 << 1 << 3); - - list1.swap(0, 2); - QVERIFY(list1 == QList<int>() << 3 << 1 << 2); - - list1.swap(1, 2); - QVERIFY(list1 == QList<int>() << 3 << 2 << 1); - - list1.swap(1, 2); - QVERIFY(list1 == QList<int>() << 3 << 1 << 2); - - QList<QString> list2; - list2 << "1" << "2" << "3"; - - list2.swap(0, 0); - QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); - - list2.swap(1, 1); - QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); - - list2.swap(2, 2); - QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); - - list2.swap(0, 1); - QVERIFY(list2 == QList<QString>() << "2" << "1" << "3"); - - list2.swap(0, 2); - QVERIFY(list2 == QList<QString>() << "3" << "1" << "2"); - - list2.swap(1, 2); - QVERIFY(list2 == QList<QString>() << "3" << "2" << "1"); - - list2.swap(1, 2); - QVERIFY(list2 == QList<QString>() << "3" << "1" << "2"); - - QList<double> list3; - list3 << 1.0 << 2.0 << 3.0; - - list3.swap(0, 0); - QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); - - list3.swap(1, 1); - QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); - - list3.swap(2, 2); - QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); - - list3.swap(0, 1); - QVERIFY(list3 == QList<double>() << 2.0 << 1.0 << 3.0); - - list3.swap(0, 2); - QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0); - - list3.swap(1, 2); - QVERIFY(list3 == QList<double>() << 3.0 << 2.0 << 1.0); - - list3.swap(1, 2); - QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0); - } - - // Check what happens when using references to own items. - // Ideally we should run valgrind on this. - { - int i; - - QList<void *> list1; - list1.append(reinterpret_cast<void *>(50)); - - for (i = 1; i < 100; ++i) { - list1.append(list1.at(i - 1)); - list1.prepend(list1.at(i)); - list1.insert(i, list1.at(i - 1)); - list1.insert(i, list1.at(i)); - list1.insert(i, list1.at(i + 1)); - list1.replace(i, list1.at(i - 1)); - list1.replace(i, list1.at(i)); - list1.replace(i, list1.at(i + 1)); - } - QCOMPARE(list1.size(), 496); - for (i = 0; i < list1.size(); ++i) { - QCOMPARE(list1.at(i), reinterpret_cast<void *>(50)); - } - - QList<QString> list2; - list2.append("50"); - - for (i = 1; i < 100; ++i) { - list2.append(list2.at(i - 1)); - list2.prepend(list2.at(i)); - list2.insert(i, list2.at(i - 1)); - list2.insert(i, list2.at(i)); - list2.insert(i, list2.at(i + 1)); - list2.replace(i, list2.at(i - 1)); - list2.replace(i, list2.at(i)); - list2.replace(i, list2.at(i + 1)); - } - QCOMPARE(list2.size(), 496); - for (i = 0; i < list2.size(); ++i) { - QCOMPARE(list2.at(i), QString::fromLatin1("50")); - } - - QList<double> list3; - list3.append(50.0); - - for (i = 1; i < 100; ++i) { - list3.append(list3.at(i - 1)); - list3.prepend(list3.at(i)); - list3.insert(i, list3.at(i - 1)); - list3.insert(i, list3.at(i)); - list3.insert(i, list3.at(i + 1)); - list3.replace(i, list3.at(i - 1)); - list3.replace(i, list3.at(i)); - list3.replace(i, list3.at(i + 1)); - } - QCOMPARE(list3.size(), 496); - for (i = 0; i < list3.size(); ++i) { - QCOMPARE(list3.at(i), 50.0); - } - - QList<QTime> list4; - list4.append(QTime(12, 34, 56)); - - for (i = 1; i < 100; ++i) { - list4.append(list4.at(i - 1)); - list4.prepend(list4.at(i)); - list4.insert(i, list4.at(i - 1)); - list4.insert(i, list4.at(i)); - list4.insert(i, list4.at(i + 1)); - list4.replace(i, list4.at(i - 1)); - list4.replace(i, list4.at(i)); - list4.replace(i, list4.at(i + 1)); - } - QCOMPARE(list4.size(), 496); - for (i = 0; i < list4.size(); ++i) { - QVERIFY(list4.at(i) == QTime(12, 34, 56)); - } - - } - { - QList<int> a; - QCOMPARE(a.startsWith(1), false); - QCOMPARE(a.endsWith(1), false); - a.append(1); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), true); - QCOMPARE(a.endsWith(2), false); - a.append(2); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), false); - QCOMPARE(a.endsWith(2), true); - } -} - -void tst_Collections::linkedList() -{ - { - QLinkedList<int> list; - QVERIFY(list.isEmpty()); - list.append(1); - list.push_back(2); - list += (3); - list << 4 << 5 << 6; - QVERIFY(!list.isEmpty()); - QVERIFY(list.size() == 6); - { - int sum = 0; - QLinkedListIterator<int> i = list; - while (i.hasNext()) { - sum += i.next(); - } - QVERIFY(sum == 21); - } - { - int sum = 0; - QLinkedList<int>::const_iterator i = list.begin(); - while (i != list.end()) - sum += *i++; - QVERIFY(sum == 21); - } - { - QMutableLinkedListIterator<int> i = list; - while (i.hasNext()) - i.setValue(2*i.next()); - } - { - int sum = 0; - QLinkedListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) - sum += i.previous(); - QVERIFY(sum == 2*21); - } - { - QMutableLinkedListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) - i.setValue(2*i.previous()); - } - { - int sum = 0; - QLinkedListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) - sum += i.previous(); - QVERIFY(sum == 2*2*21); - } - { - QMutableLinkedListIterator<int> i = list; - while (i.hasNext()) { - int a = i.next(); - i.insert(a); - } - } - { - int sum = 0; - QLinkedList<int>::iterator i = list.begin(); - while (i != list.end()) - sum += *i++; - QVERIFY(sum == 2*2*2*21); - } - { - int duplicates = 0; - QLinkedListIterator<int> i = list; - while (i.hasNext()) { - int a = i.next(); - if (i.hasNext() && a == i.peekNext()) - duplicates++; - } - QVERIFY(duplicates == 6); - } - { - int duplicates = 0; - QLinkedListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) { - int a = i.previous(); - if (i.hasPrevious() && a == i.peekPrevious()) - duplicates++; - } - QVERIFY(duplicates == 6); - } - { - QMutableLinkedListIterator<int> i = list; - while (i.hasNext()) { - int a = i.next(); - if (i.hasNext() && - i.peekNext() == a) - i.remove(); - } - } - { - int duplicates = 0; - QMutableLinkedListIterator<int> i = list; - i.toBack(); - while (i.hasPrevious()) { - int a = i.previous(); - if (i.hasPrevious() && a == i.peekPrevious()) - duplicates++; - } - QVERIFY(duplicates == 0); - } - { - QVERIFY(list.size() == 6); - QMutableLinkedListIterator<int> i = list; - while (i.hasNext()) { - int a = i.peekNext(); - i.insert(42); - QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a); - i.next(); - } - QVERIFY(list.size() == 12); - i.toFront(); - while (i.findNext(42)) - i.remove(); - } - { - QLinkedList<int> l; - l << 4 << 8 << 12 << 16 << 20 << 24; - QVERIFY(l == list); - QLinkedList<int> copy = list; - list += list; - QVERIFY(l != list && l.size() == list.size()/2 && l == copy); - l += copy; - QVERIFY(l == list); - list = copy; - } - { - QLinkedList<int> copy = list; - list.prepend(999); - list.append(999); - QVERIFY(list.contains(999)); - QVERIFY(list.count(999) == 2); - list.removeAll(999); - QVERIFY(list == copy); - } - { - QLinkedList<QString> list; - list << "one" << "two" << "three" << "four" << "five" << "six"; - while (!list.isEmpty()) - list.removeAll(list.first()); - } - { - QLinkedList<QString> list; - list << "one" << "two" << "one" << "two"; - QVERIFY(!list.removeOne("three")); - QVERIFY(list.removeOne("two")); - QCOMPARE(list, QLinkedList<QString>() << "one" << "one" << "two");; - QVERIFY(list.removeOne("two")); - QCOMPARE(list, QLinkedList<QString>() << "one" << "one"); - QVERIFY(!list.removeOne("two")); - QCOMPARE(list, QLinkedList<QString>() << "one" << "one"); - QVERIFY(list.removeOne("one")); - QCOMPARE(list, QLinkedList<QString>() << "one"); - QVERIFY(list.removeOne("one")); - QVERIFY(list.isEmpty()); - QVERIFY(!list.removeOne("one")); - QVERIFY(list.isEmpty()); - } - { - list.clear(); - QVERIFY(list.isEmpty()); - QVERIFY(list.begin() == list.end()); - QLinkedListIterator<int> i(list); - QVERIFY(!i.hasNext() && !i.hasPrevious()); - } - } - - { - QLinkedList<QString> list; - list.append("Hello"); - - QLinkedList<QString>::iterator it = list.begin(); - QVERIFY((*it)[0] == QChar('H')); - QVERIFY(it->constData()[0] == QChar('H')); - it->replace(QChar('H'), QChar('X')); - QVERIFY(list.first() == "Xello"); - - QLinkedList<QString>::const_iterator cit = list.constBegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - - cit = list.cbegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - } - - { - QLinkedList<QString> list; - list << "alpha" << "beta"; - list += list; - QVERIFY(list.size() == 4); - QVERIFY(*list.begin() == "alpha"); - QVERIFY(*(list.begin() + 1) == "beta"); - QVERIFY(*(list.begin() + 2) == "alpha"); - QVERIFY(*(list.begin() + 3) == "beta"); - } - - { - QLinkedList<int> a; - QCOMPARE(a.startsWith(1), false); - QCOMPARE(a.endsWith(1), false); - a.append(1); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), true); - QCOMPARE(a.endsWith(2), false); - a.append(2); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), false); - QCOMPARE(a.endsWith(2), true); - } -}; - - -void tst_Collections::vector() -{ - QVector<int> v1; - v1 << 1 << 2 << 3; - QVector<int> v2; - v2 << 4 << 5; - QVector<int> v3; - v3 << 1 << 2 << 3 << 4 << 5; - QVERIFY(v1 + v2 == v3); - - QVector<int> emptyVector; - // emptyVector.remove(3, -3); // Q_ASSERT_X() triggered with "index out of range" message. - QCOMPARE(emptyVector.size(), 0); - - emptyVector.remove(0, 0); - QCOMPARE(emptyVector.size(), 0); - - QVector<int> v4; - v4 << 1 << 2 << 3; - QCOMPARE(v4.size(), 3); - v4.remove(1, 0); - QCOMPARE(v4.size(), 3); - - QVector<int> v; - v.append(2); - QVERIFY(*v.begin() == 2); - v.prepend(1); - - v << 3 << 4 << 5 << 6; - QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true); - QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false); - QVERIFY(qBinaryFind(v.begin(), v.end(), 2) == v.begin() + 1); - QVERIFY(qLowerBound(v.begin(), v.end(), 2) == v.begin() + 1); - QVERIFY(qUpperBound(v.begin(), v.end(), 2) == v.begin() + 2); - QVERIFY(qBinaryFind(v.begin(), v.end(), 9) == v.end()); - QVERIFY(qLowerBound(v.begin(), v.end(), 9) == v.end()); - QVERIFY(qUpperBound(v.begin(), v.end(), 9) == v.end()); - - v.clear(); - v << 1 << 2 << 3; - v.insert(v.begin(), 0); - v.insert(v.end(), 4); - v.insert(v.begin()+2, 9); - - QVector<int> result; - result << 0 << 1 << 9 << 2 << 3 << 4; - - QVERIFY( v == result ); - - v.clear(); - v << 1 << 2 << 3; - v.insert(0, 0); - v.insert(4, 4); - v.insert(2, 9); - - QVERIFY( v == result ); - - QVector<QString> vec; - vec << "foo" << "bar"; - vec.reserve( 512 ); - QVERIFY(vec[0] == "foo"); - QVERIFY(vec[1] == "bar"); - - int initialLargeStaticCount = LargeStatic::count; - { - QVector<LargeStatic> vector; - vector.append(LargeStatic()); - vector.resize(0); - } - QCOMPARE(LargeStatic::count, initialLargeStaticCount); - - { - QVector<QString> vector; - vector << "alpha" << "beta"; - vector += vector; - QVERIFY(vector.size() == 4); - QVERIFY(vector.at(0) == "alpha"); - QVERIFY(vector.at(1) == "beta"); - QVERIFY(vector.at(2) == "alpha"); - QVERIFY(vector.at(3) == "beta"); - } - - int originalLargeStaticCount = LargeStatic::count; - { - QVector<LargeStatic> vector(5); - } - QVERIFY(LargeStatic::count == originalLargeStaticCount); - { - QVector<LargeStatic> vector(5); - QList<LargeStatic> list = vector.toList(); - } - QVERIFY(LargeStatic::count == originalLargeStaticCount); - { - QVector<LargeStatic> vector; - LargeStatic *dummy = 0; - for (int i = 0; i < 10000; ++i) { - delete dummy; - dummy = new LargeStatic; - vector.append(LargeStatic()); - } - delete dummy; - } - QVERIFY(LargeStatic::count == originalLargeStaticCount); - - int originalMovableCount = Movable::count; - { - QVector<Movable> vector(5); - } - QVERIFY(Movable::count == originalMovableCount); - { - QVector<Movable> vector(5); - QList<Movable> list = vector.toList(); - } - QVERIFY(Movable::count == originalMovableCount); - { - QVector<Movable> vector; - Movable *dummy = 0; - for (int i = 0; i < 10000; ++i) { - delete dummy; - dummy = new Movable; - vector.append(Movable()); - } - delete dummy; - } - QVERIFY(Movable::count == originalMovableCount); - - // Check what happens when using references to own items. - // Ideally we should run valgrind on this. - { - int i; - - QVector<void *> vect1; - vect1.append(reinterpret_cast<void *>(50)); - - for (i = 1; i < 100; ++i) { - vect1.append(vect1.at(i - 1)); - vect1.prepend(vect1.at(i)); - vect1.insert(i, vect1.at(i - 1)); - vect1.insert(i, vect1.at(i)); - vect1.insert(i, vect1.at(i + 1)); - vect1.replace(i, vect1.at(i - 1)); - vect1.replace(i, vect1.at(i)); - vect1.replace(i, vect1.at(i + 1)); - } - QCOMPARE(vect1.size(), 496); - for (i = 0; i < vect1.size(); ++i) { - QCOMPARE(vect1.at(i), reinterpret_cast<void *>(50)); - } - - QVector<QString> vect2; - vect2.append("50"); - - for (i = 1; i < 100; ++i) { - vect2.append(vect2.at(i - 1)); - vect2.prepend(vect2.at(i)); - vect2.insert(i, vect2.at(i - 1)); - vect2.insert(i, vect2.at(i)); - vect2.insert(i, vect2.at(i + 1)); - vect2.replace(i, vect2.at(i - 1)); - vect2.replace(i, vect2.at(i)); - vect2.replace(i, vect2.at(i + 1)); - } - QCOMPARE(vect2.size(), 496); - for (i = 0; i < vect2.size(); ++i) { - QCOMPARE(vect2.at(i), QString::fromLatin1("50")); - } - - QVector<double> vect3; - vect3.append(50.0); - - for (i = 1; i < 100; ++i) { - vect3.append(vect3.at(i - 1)); - vect3.prepend(vect3.at(i)); - vect3.insert(i, vect3.at(i - 1)); - vect3.insert(i, vect3.at(i)); - vect3.insert(i, vect3.at(i + 1)); - vect3.replace(i, vect3.at(i - 1)); - vect3.replace(i, vect3.at(i)); - vect3.replace(i, vect3.at(i + 1)); - } - QCOMPARE(vect3.size(), 496); - for (i = 0; i < vect3.size(); ++i) { - QCOMPARE(vect3.at(i), 50.0); - } - - QVector<QTime> vect4; - vect4.append(QTime(12, 34, 56)); - - for (i = 1; i < 100; ++i) { - vect4.append(vect4.at(i - 1)); - vect4.prepend(vect4.at(i)); - vect4.insert(i, vect4.at(i - 1)); - vect4.insert(i, vect4.at(i)); - vect4.insert(i, vect4.at(i + 1)); - vect4.replace(i, vect4.at(i - 1)); - vect4.replace(i, vect4.at(i)); - vect4.replace(i, vect4.at(i + 1)); - } - QCOMPARE(vect4.size(), 496); - for (i = 0; i < vect4.size(); ++i) { - QVERIFY(vect4.at(i) == QTime(12, 34, 56)); - } - } - - // this used to trigger an uninitialized read in valgrind - QVector<char> foo; - foo.resize(144); - - { - QVector<int> a; - QCOMPARE(a.startsWith(1), false); - QCOMPARE(a.endsWith(1), false); - a.append(1); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), true); - QCOMPARE(a.endsWith(2), false); - a.append(2); - QCOMPARE(a.startsWith(1), true); - QCOMPARE(a.startsWith(2), false); - QCOMPARE(a.endsWith(1), false); - QCOMPARE(a.endsWith(2), true); - } -} - -void tst_Collections::byteArray() -{ - QByteArray hello = "hello"; - QByteArray ello = "ello"; - QByteArray World = "World"; - QByteArray Wor = "Wor"; - QByteArray helloWorld = "helloWorld"; - QVERIFY(hello + World == helloWorld); - QVERIFY(hello + "World" == helloWorld); - QVERIFY("hello" + World == helloWorld); - - - QByteArray l; - QVERIFY('h' + ello == hello); - QVERIFY(Wor + 'l' + 'd' == "World"); - QVERIFY(hello + World == "helloWorld"); - QVERIFY(hello + "World" == "helloWorld"); - QVERIFY("hello" + World == "helloWorld"); - QVERIFY('h' + ello == "hello"); - QVERIFY(Wor + 'l' + 'd' == "World"); - QVERIFY("helloWorld" == hello + World); - QVERIFY("helloWorld" == hello + "World"); - QVERIFY("helloWorld" == "hello" + World); - QVERIFY("hello" == 'h' + ello); - QVERIFY("World" == Wor + 'l' + 'd'); - - QVERIFY(hello.contains('e')); - QVERIFY (true == hello.contains('e')); - QVERIFY (hello.contains('e') != false); - - QVERIFY(hello.indexOf('e') == 1); - QVERIFY(hello.indexOf('e', -10) == 1); - QVERIFY(hello.indexOf('l') == 2); - QVERIFY(hello.indexOf('l',2) == 2); - QVERIFY(hello.indexOf('l',3) == 3); - - QByteArray large = "000 100 200 300 400 500 600 700 800 900"; - - QVERIFY(large.indexOf("700") == 28); - QVERIFY(large.indexOf("700", 28) == 28); - QVERIFY(large.indexOf("700", 29) == -1); - QVERIFY(large.lastIndexOf("700") == 28); - QVERIFY(large.lastIndexOf("700", 28) == 28); - QVERIFY(large.lastIndexOf("700", 27) == -1); - - QVERIFY(large.contains("200")); - QVERIFY(!large.contains("201")); - QVERIFY(large.contains('3')); - QVERIFY(!large.contains('a')); - - QVERIFY(large.count("00") == 11); - QVERIFY(large.count('3') == 1); - QVERIFY(large.count('0') == 21); - QVERIFY(large.count("0") == 21); - QVERIFY(large.count("200") == 1); - QVERIFY(large.count("201") == 0); - - QVERIFY(hello.left(0) == ""); - QVERIFY(!hello.left(0).isNull()); - QVERIFY(hello.left(1) == "h"); - QVERIFY(hello.left(2) == "he"); - QVERIFY(hello.left(200) == "hello"); - QVERIFY(hello.left(hello.size()) == hello); - QVERIFY(hello.left(hello.size()+1) == hello); - - QVERIFY(hello.right(0) == ""); - QVERIFY(!hello.right(0).isNull()); - QVERIFY(hello.right(1) == "o"); - QVERIFY(hello.right(2) == "lo"); - QVERIFY(hello.right(200) == "hello"); - QVERIFY(hello.right(hello.size()) == hello); - QVERIFY(hello.right(hello.size()+1) == hello); - - QVERIFY(!hello.mid(0, 0).isNull()); - QVERIFY(hello.mid(0, 1) == "h"); - QVERIFY(hello.mid(0, 2) == "he"); - QVERIFY(hello.mid(0, 200) == "hello"); - QVERIFY(hello.mid(0) == "hello"); - QVERIFY(hello.mid(0, hello.size()) == hello); - QVERIFY(hello.mid(0, hello.size()+1) == hello); - - QVERIFY(hello.mid(hello.size()-0) == ""); - QVERIFY(hello.mid(hello.size()-0).isEmpty()); - QVERIFY(!hello.mid(hello.size()-0).isNull()); - QVERIFY(hello.mid(hello.size()-1) == "o"); - QVERIFY(hello.mid(hello.size()-2) == "lo"); - QVERIFY(hello.mid(hello.size()-200) == "hello"); - - QByteArray nullByteArray; - QByteArray nonNullByteArray = ""; - QVERIFY(nullByteArray.left(10).isNull()); - QVERIFY(nullByteArray.mid(0).isNull()); - - QVERIFY(nullByteArray.isEmpty() == nonNullByteArray.isEmpty()); - QVERIFY(nullByteArray.size() == nonNullByteArray.size()); - - QVERIFY(nullByteArray == QByteArray()); // QByteArray() is both null and empty. - QVERIFY(QByteArray() == nullByteArray); - - QVERIFY(nonNullByteArray == QByteArray("")); // QByteArray("") is empty, but not null. - QVERIFY(QByteArray("") == nonNullByteArray); - - QVERIFY(nullByteArray == nonNullByteArray); - QVERIFY(QByteArray() == QByteArray("")); - - QByteArray str = "Hello"; - QByteArray cstr(str.data(), str.size()); - QVERIFY(str == "Hello"); - QVERIFY(cstr == "Hello"); - cstr.clear(); - QVERIFY(str == "Hello"); - QVERIFY(cstr.isEmpty()); - - { - QByteArray ba1("Foo"); - ba1.prepend(ba1); - QCOMPARE(ba1, QByteArray("FooFoo")); - ba1.append(ba1); - QCOMPARE(ba1, QByteArray("FooFooFooFoo")); - ba1.insert(2, ba1); - QCOMPARE(ba1, QByteArray("FoFooFooFooFoooFooFooFoo")); - ba1.replace(3, 3, ba1); - QCOMPARE(ba1, QByteArray("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo")); - ba1 = "FooFoo"; - ba1.replace(char('F'), ba1); - QCOMPARE(ba1, QByteArray("FooFooooFooFoooo")); - ba1 = "FooFoo"; - ba1.replace(char('o'), ba1); - QCOMPARE(ba1, QByteArray("FFooFooFooFooFFooFooFooFoo")); - - ba1.replace(ba1, "xxx"); - QCOMPARE(ba1, QByteArray("xxx")); - ba1.replace(ba1, QByteArray("yyy")); - QCOMPARE(ba1, QByteArray("yyy")); - ba1 += ba1; - QCOMPARE(ba1, QByteArray("yyyyyy")); - - ba1.remove(1, -1); // do nothing - QCOMPARE(ba1, QByteArray("yyyyyy")); - - ba1.replace(0, -1, "ZZZ"); - QCOMPARE(ba1, QByteArray("ZZZyyyyyy")); - } -}; - -void tst_Collections::stack() -{ - QStack<int> stack; - stack.push(1); - stack.push(2); - stack.push(3); - QVectorIterator<int> i = stack; - i.toBack(); - int sum = 0; - while (i.hasPrevious()) - sum += i.previous(); - QVERIFY(sum == 6); - - sum = 0; - for (QStack<int>::iterator i = stack.begin(); i != stack.end(); ++i) - sum += *i; - QVERIFY(sum == 6); - - while (!stack.isEmpty()) - sum -= stack.pop(); - QVERIFY(sum == 0); -} - -void tst_Collections::hash() -{ - 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,LargeStatic> hash; - for (int i = 0; i < 10; i++) - hash.insert(i, LargeStatic()); - QVERIFY(LargeStatic::count == 10); - hash.remove(7); - QVERIFY(LargeStatic::count == 9); - - } - QVERIFY(LargeStatic::count == 0); - { - QHash<int, int*> hash; - QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0); - } - - { - /* - This test relies on a certain implementation of - QHash. If you change the way QHash works internally, - change this test as well. - */ - QHash<int, int> hash; - for (int i = 0; i < 1000; ++i) - hash.insert(i, i); - QVERIFY(hash.capacity() == 1031); - hash.squeeze(); - QVERIFY(hash.capacity() == 521); - - hash.insert(12345, 12345); - QVERIFY(hash.capacity() == 1031); - - for (int j = 0; j < 900; ++j) - hash.remove(j); - QVERIFY(hash.capacity() == 257); - hash.squeeze(); - QVERIFY(hash.capacity() == 67); - hash.reserve(0); - } - } - - { - QHash<int, QString> hash; - hash.insert(0, "Hello"); - - QHash<int, QString>::iterator it = hash.begin(); - QVERIFY((*it)[0] == QChar('H')); - QVERIFY(it->constData()[0] == QChar('H')); - it->replace(QChar('H'), QChar('X')); - QVERIFY(*hash.begin() == "Xello"); - - QHash<int, QString>::const_iterator cit = hash.constBegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - - cit = hash.cbegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - } - - { - QHash<int, QString> hash1, hash2; - hash1.insertMulti(1, "Alpha"); - hash1.insertMulti(1, "Gamma"); - hash2.insertMulti(1, "Beta"); - hash2.insertMulti(1, "Gamma"); - hash2.insertMulti(1, "Gamma"); - - hash1.unite(hash2); - QCOMPARE(hash1.size(), 5); - QCOMPARE(hash1.values(), - (QList<QString>() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha")); - - hash2 = hash1; - hash2.unite(hash2); - QCOMPARE(hash2.size(), 10); - QCOMPARE(hash2.values(), hash1.values() + hash1.values()); - } -} - -void tst_Collections::map() -{ - const char *hello = "hello"; - const char *world = "world"; - const char *allo = "allo"; - const char *monde = "monde"; - - { - typedef QMap<int, const char *> Map; - Map map; - map.insert(1, hello); - map.insert(2, world); - - QVERIFY(*map.begin() == hello); - - QVERIFY(map.size() == 2); - QVERIFY(!map.isEmpty()); - - { - Map map2 = map; - map2 = map; - map = map2; - map2 = map2; - map = map; - map2.clear(); - map2 = map2; - QVERIFY(map2.size() == 0); - QVERIFY(map2.isEmpty()); - } - QVERIFY(map.size() == 2); - - { - Map map2 = map; - map2[1] = allo; - map2[2] = monde; - - QVERIFY(map2[1] == allo); - QVERIFY(map2[2] == monde); - QVERIFY(map[1] == hello); - QVERIFY(map[2] == world); - - map2[1] = map[1]; - map2[2] = map[2]; - - QVERIFY(map2[1] == hello); - QVERIFY(map2[2] == world); - - map[1] = map[1]; - QVERIFY(map[1] == hello); - } - - { - Map map2 = map; - map2.detach(); - map2.remove(1); - QVERIFY(map2.size() == 1); - map2.remove(1); - QVERIFY(map2.size() == 1); - map2.remove(0); - QVERIFY(map2.size() == 1); - map2.remove(2); - QVERIFY(map2.size() == 0); - QVERIFY(map.size() == 2); - } - - map.detach(); - - { - Map::iterator it1 = map.find(1); - QVERIFY(it1 == map.begin()); - QVERIFY(it1 != map.end()); - - Map::iterator it2 = map.find(0); - QVERIFY(it2 != map.begin()); - QVERIFY(it2 == map.end()); - - *it1 = monde; - QVERIFY(*it1 == monde); - QVERIFY(map[1] == monde); - - *it1 = hello; - QVERIFY(*it1 == hello); - QVERIFY(map[1] == hello); - - map[1] = monde; - QVERIFY(it1.key() == 1); - QVERIFY(it1.value() == monde); - QVERIFY(*it1 == monde); - QVERIFY(map[1] == monde); - - map[1] = hello; - QVERIFY(*it1 == hello); - QVERIFY(map[1] == hello); - - *++it1 = allo; - QVERIFY(*it1 == allo); - QVERIFY(map[2] == allo); - *it1 = world; - - ++it1; - QVERIFY(it1 == map.end()); - - int count = 0; - it1 = map.begin(); - while (it1 != map.end()) { - count++; - ++it1; - } - QVERIFY(count == 2); - } - - { - const Map map2 = map; - - Map::const_iterator it1 = map2.find(1); - QVERIFY(it1 != map2.end()); - QVERIFY(it1.key() == 1); - QVERIFY(it1.value() == hello); - QVERIFY(*it1 == hello); - ++it1; - - Map::const_iterator it2 = map2.find(2); - QVERIFY(it1 == it2); - ++it1; - QVERIFY(it1 == map2.end()); - QVERIFY(it2 != map2.end()); - QVERIFY(it1 != it2); - - int count = 0; - it1 = map2.begin(); - while (it1 != map2.end()) { - count++; - ++it1; - } - QVERIFY(count == 2); - - count = 0; - it1 = map.begin(); - while (it1 != map.end()) { - count++; - ++it1; - } - QVERIFY(count == 2); - } - - { - QVERIFY(map.contains(1)); - QVERIFY(map.contains(2)); - QVERIFY(!map.contains(0)); - QVERIFY(!map.contains(3)); - } - - { - QVERIFY(map.value(1) == hello); - QVERIFY(map.value(2) == world); - QVERIFY(map.value(3) == 0); - QVERIFY(map.value(1, allo) == hello); - QVERIFY(map.value(2, allo) == world); - QVERIFY(map.value(3, allo) == allo); - QVERIFY(map.value(0, monde) == monde); - } - int originalLargeStaticCount = LargeStatic::count; - { - QMap<int,LargeStatic> map; - for (int i = 0; i < 10; i++) - map.insert(i, LargeStatic()); - QVERIFY(LargeStatic::count == (originalLargeStaticCount + 10)); - map.remove(7); - QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9)); - - } - QVERIFY(LargeStatic::count == originalLargeStaticCount); - { - QMap<int, int*> map; - QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0); - } - - { - QMap<int, int> map; - map[0] = 1; - map[1] = 2; - map[2] = 4; - map[3] = 8; - int sum = 0; - int sumkey = 0; - QMapIterator<int,int> i = map; - while (i.hasNext()) { - sum += i.next().value(); - sumkey += i.key(); - } - QVERIFY(sum == 15); - QVERIFY(sumkey == 6); - } - { - QMap<int, int> map; - map[0] = 1; - map[1] = 2; - map[2] = 4; - map[3] = 8; - int sum = 0; - QMutableMapIterator<int,int> i = map; - while (i.hasNext()) - if (i.next().key() == 2) - i.remove(); - i.toFront(); - while (i.hasNext()) { - sum += i.next().value(); - i.setValue(10); - i.value() += 22; - QVERIFY(i.value() == 32); - } - QVERIFY(sum == 11); - } - { - QMap<int, int> map; - map[0] = 1; - QMutableMapIterator<int,int> i(map); - i.toBack(); - while (i.hasPrevious()) { - i.previous(); - QCOMPARE(i.key(), 0); - QCOMPARE(i.value(), 1); - } - } - } - - { - QMultiMap<QString, int> map1; - map1.insert("1", 2); - map1.insert("1", 1); - map1.insert("a", 3); - map1.insert("a", 2); - map1.insert("a", 1); - map1.insert("b", 2); - map1.insert("b", 1); - - QMultiMap<QString, int>::iterator j1, k1; - - j1 = map1.lowerBound("0"); k1 = map1.upperBound("0"); - QVERIFY(j1 == map1.begin() && k1 == j1); - j1 = map1.lowerBound("00"); k1 = map1.upperBound("00"); - QVERIFY(j1 == map1.find("1") && k1 == j1); - j1 = map1.lowerBound("1"); k1 = map1.upperBound("1"); - QVERIFY(j1 == map1.find("1") && --(--k1) == j1); - j1 = map1.lowerBound("11"); k1 = map1.upperBound("11"); - QVERIFY(j1 == map1.find("a") && k1 == j1); - j1 = map1.lowerBound("a"); k1 = map1.upperBound("a"); - QVERIFY(j1 == map1.find("a") && k1 == map1.find("b")); - QVERIFY(j1.value() == 1 && j1.value() == 1); - j1 = map1.lowerBound("aa"); k1 = map1.upperBound("aa"); - QVERIFY(j1 == map1.find("b") && k1 == j1); - QVERIFY(j1.value() == 1); - j1 = map1.lowerBound("b"); k1 = map1.upperBound("b"); - QVERIFY(j1 == map1.find("b") && k1 == map1.end()); - QVERIFY(j1.value() == 1); - j1 = map1.lowerBound("bb"); k1 = map1.upperBound("bb"); - QVERIFY(j1 == map1.end() && k1 == j1); - - const QMultiMap<QString, int> map2 = map1; - QMultiMap<QString, int>::const_iterator j2, k2; - - j2 = map2.lowerBound("0"); k2 = map2.upperBound("0"); - QVERIFY(j2 == map2.begin() && k2 == j2); - j2 = map2.lowerBound("00"); k2 = map2.upperBound("00"); - QVERIFY(j2 == map2.find("1") && k2 == j2); - j2 = map2.lowerBound("1"); k2 = map2.upperBound("1"); - QVERIFY(j2 == map2.find("1") && --(--k2) == j2); - j2 = map2.lowerBound("11"); k2 = map2.upperBound("11"); - QVERIFY(j2 == map2.find("a") && k2 == j2); - j2 = map2.lowerBound("a"); k2 = map2.upperBound("a"); - QVERIFY(j2 == map2.find("a") && k2 == map2.find("b")); - QVERIFY(j2.value() == 1 && j2.value() == 1); - j2 = map2.lowerBound("aa"); k2 = map2.upperBound("aa"); - QVERIFY(j2 == map2.find("b") && k2 == j2); - QVERIFY(j2.value() == 1); - j2 = map2.lowerBound("b"); k2 = map2.upperBound("b"); - QVERIFY(j2 == map2.find("b") && k2 == map2.end()); - QVERIFY(j2.value() == 1); - j2 = map2.lowerBound("bb"); k2 = map2.upperBound("bb"); - QVERIFY(j2 == map2.end() && k2 == j2); - } - - { - QMap<int, QString> map; - map.insert(0, "Hello"); - - QMap<int, QString>::iterator it = map.begin(); - QVERIFY((*it)[0] == QChar('H')); - QVERIFY(it->constData()[0] == QChar('H')); - it->replace(QChar('H'), QChar('X')); - QVERIFY(*map.begin() == "Xello"); - - QMap<int, QString>::const_iterator cit = map.constBegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - - cit = map.cbegin(); - QVERIFY((*cit).toLower() == "xello"); - QVERIFY(cit->toUpper() == "XELLO"); - } - - { - QMap<int, QString> map1, map2; - map1.insertMulti(1, "Alpha"); - map1.insertMulti(1, "Gamma"); - map2.insertMulti(1, "Beta"); - map2.insertMulti(1, "Gamma"); - map2.insertMulti(1, "Gamma"); - - map1.unite(map2); - QCOMPARE(map1.size(), 5); - QCOMPARE(static_cast<QStringList>(map1.values()), - (QStringList() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha")); - - map2 = map1; - map2.unite(map2); - QCOMPARE(map2.size(), 10); - QCOMPARE(map2.values(), map1.values() + map1.values()); - } -} - -void tst_Collections::qstring() -{ - QString hello = "hello"; - QString ello = "ello"; - QString World = "World"; - QString Wor = "Wor"; - QString helloWorld = "helloWorld"; - - QString s = hello + "World"; - QVERIFY(hello + World == helloWorld); - QVERIFY(hello + "World" == helloWorld); - QVERIFY("hello" + World == helloWorld); - - - QString l; - QVERIFY('h' + ello == hello); - QVERIFY(Wor + 'l' + 'd' == "World"); - QVERIFY(hello + World == "helloWorld"); - QVERIFY(hello + "World" == "helloWorld"); - QVERIFY("hello" + World == "helloWorld"); - QVERIFY('h' + ello == "hello"); - QVERIFY(Wor + 'l' + 'd' == "World"); - QVERIFY("helloWorld" == hello + World); - QVERIFY("helloWorld" == hello + "World"); - QVERIFY("helloWorld" == "hello" + World); - QVERIFY("hello" == 'h' + ello); - QVERIFY("World" == Wor + 'l' + 'd'); - - QVERIFY(hello.contains('e')); - QVERIFY (true == hello.contains('e')); - QVERIFY (hello.contains('e') != false); - - QVERIFY(hello.indexOf('e') == 1); - QVERIFY(hello.indexOf('e', -10) == 1); - QVERIFY(hello.indexOf('l') == 2); - QVERIFY(hello.indexOf('l',2) == 2); - QVERIFY(hello.indexOf('l',3) == 3); - - QString large = "000 100 200 300 400 500 600 700 800 900"; - - QVERIFY(large.indexOf("700") == 28); - QVERIFY(large.indexOf("700", 28) == 28); - QVERIFY(large.indexOf("700", 29) == -1); - QVERIFY(large.lastIndexOf("700") == 28); - QVERIFY(large.lastIndexOf("700", 28) == 28); - QVERIFY(large.lastIndexOf("700", 27) == -1); - - QVERIFY(large.contains("200")); - QVERIFY(!large.contains("201")); - QVERIFY(large.contains('3')); - QVERIFY(!large.contains('a')); - - QVERIFY(large.count("00") == 11); - QVERIFY(large.count('3') == 1); - QVERIFY(large.count('0') == 21); - QVERIFY(large.count("0") == 21); - QVERIFY(large.count("200") == 1); - QVERIFY(large.count("201") == 0); - - QVERIFY(hello.left(0) == ""); - QVERIFY(!hello.left(0).isNull()); - QVERIFY(hello.left(1) == "h"); - QVERIFY(hello.left(2) == "he"); - QVERIFY(hello.left(200) == "hello"); - QVERIFY(hello.left(hello.size()) == hello); - QVERIFY(hello.left(hello.size()+1) == hello); - - QVERIFY(hello.right(0) == ""); - QVERIFY(!hello.right(0).isNull()); - QVERIFY(hello.right(1) == "o"); - QVERIFY(hello.right(2) == "lo"); - QVERIFY(hello.right(200) == "hello"); - QVERIFY(hello.right(hello.size()) == hello); - QVERIFY(hello.right(hello.size()+1) == hello); - - QVERIFY(!hello.mid(0, 0).isNull()); - QVERIFY(hello.mid(0, 1) == "h"); - QVERIFY(hello.mid(0, 2) == "he"); - QVERIFY(hello.mid(0, 200) == "hello"); - QVERIFY(hello.mid(0) == "hello"); - QVERIFY(hello.mid(0, hello.size()) == hello); - QVERIFY(hello.mid(0, hello.size()+1) == hello); - - QVERIFY(hello.mid(hello.size()-0) == ""); - QVERIFY(hello.mid(hello.size()-0).isEmpty()); - QVERIFY(!hello.mid(hello.size()-0).isNull()); - QVERIFY(hello.mid(hello.size()-1) == "o"); - QVERIFY(hello.mid(hello.size()-2) == "lo"); - QVERIFY(hello.mid(hello.size()-200) == "hello"); - - QString null; - QString nonNull = ""; - QVERIFY(null.left(10).isNull()); - QVERIFY(null.mid(0).isNull()); - - QVERIFY(null == QString::null); - QVERIFY(QString::null == null); - QVERIFY(nonNull != QString::null); - QVERIFY(QString::null != nonNull); - QVERIFY(null == nonNull); - QVERIFY(QString::null == QString::null); - - QString fill = "123"; - fill.fill('a'); - QVERIFY(fill == "aaa"); - - s.clear(); - s = hello; - s.append(World); - QVERIFY(s == helloWorld); - s.clear(); - s = World; - s.insert(0,hello); - QVERIFY(s == helloWorld); - s = "012345"; - s.insert(3, 'E'); - QVERIFY(s == "012E345"); - s.insert(3, "INSID"); - QVERIFY(s == "012INSIDE345"); - s = "short"; - s.insert(7, 'E'); - QVERIFY(s == "short E"); - s = "short"; - s.insert(7, "END"); - QVERIFY(s == "short END"); - - QVERIFY(QString::fromLatin1("hello") == "hello"); - - s = "first"; - QVERIFY(s.toLatin1() == "first"); - s = "second"; - QVERIFY(s.toLatin1() == "second"); - s.clear(); - QVERIFY(s.isNull()); - QVERIFY(s.toLatin1().size() == 0); - QVERIFY(s.toLatin1().isEmpty()); - QVERIFY(s.toLatin1().isNull()); - - s = "first-utf8"; - QVERIFY(s.toUtf8() == "first-utf8"); - s = "second-utf8"; - QVERIFY(s.toUtf8() == "second-utf8"); - s.clear(); - QVERIFY(s.isNull()); - QVERIFY(s.toUtf8().size() == 0); - QVERIFY(s.toUtf8().isEmpty()); - QVERIFY(s.toUtf8().isNull()); - - s = "first-utf8"; - QVERIFY(s.toUtf8() == "first-utf8"); - s = "second-utf8"; - QVERIFY(s.toUtf8() == "second-utf8"); - s.clear(); - QVERIFY(s.isNull()); - QVERIFY(s.toUtf8().size() == 0); - QVERIFY(s.toUtf8().isEmpty()); - QVERIFY(s.toUtf8().isNull()); - - s = "first-local8Bit"; - QVERIFY(s.toLocal8Bit() == "first-local8Bit"); - s = "second-local8Bit"; - QVERIFY(s.toLocal8Bit() == "second-local8Bit"); - s.clear(); - QVERIFY(s.isNull()); - QVERIFY(s.toLocal8Bit().size() == 0); - QVERIFY(s.toLocal8Bit().isEmpty()); - - s = "first-ascii"; - QVERIFY(s.toLatin1() == "first-ascii"); - s = "second-ascii"; - QVERIFY(s.toLatin1() == "second-ascii"); - s.clear(); - QVERIFY(s.isNull()); - QVERIFY(s.toLatin1().size() == 0); - QVERIFY(s.toLatin1().isEmpty()); - QVERIFY(s.toLatin1().isNull()); - - s = "ascii"; - s += QChar((uchar) 0xb0); - QVERIFY(s.toUtf8() != s.toLatin1()); - QCOMPARE(s[s.length()-1].unicode(), (ushort)0xb0); - QVERIFY(s.left(s.length()-1) == "ascii"); - - QVERIFY(s == QString::fromUtf8(s.toUtf8().constData())); - - s = "12"; - s.append('3'); - s += '4'; - QVERIFY(s == "1234"); - - s = "repend"; - s.prepend('p'); - QVERIFY(s == "prepend"); - s.prepend("abc "); - QVERIFY(s == "abc prepend"); - - s = " whitespace "; - QVERIFY(s.trimmed() == "whitespace"); - s = " lots of stuff "; - QVERIFY(s.simplified() == "lots of stuff"); - - s = "a hat, a stick, a ski"; - QVERIFY(s[2] == 'h'); - QVERIFY(s[1] < 'b'); - - - s = "12223"; - s.remove(1, 2); - QVERIFY(s == "123"); - - s = "(%1)(%2)"; - s = s.arg("foo").arg(7); - QVERIFY(s == "(foo)(7)"); - - s = "stl rocks"; - std::string stl_string = s.toStdString(); // TODO: std::string stl_string = s does not work. - QVERIFY(s == "stl rocks"); - s = QString::fromStdString(stl_string); // TODO: s = stl_string does not work. - QVERIFY(s == "stl rocks"); - - { - QString str("Bananas"); - QVERIFY(str.startsWith("Ban")); - QVERIFY(false == str.startsWith("Car")); - } - { - QString str("Bananas"); - QVERIFY(str.endsWith("anas")); - QVERIFY(false == str.endsWith("pple")); - } - - - QString str = "Hello"; - QString cstr = QString::fromRawData(str.unicode(), str.length()); - QVERIFY(str == "Hello"); - QVERIFY(cstr == "Hello"); - cstr.clear(); - QVERIFY(str == "Hello"); - QVERIFY(cstr.isEmpty()); - - { - QString str1("Foo"); - str1.prepend(str1); - QCOMPARE(str1, QString("FooFoo")); - str1.append(str1); - QCOMPARE(str1, QString("FooFooFooFoo")); - str1.insert(2, str1); - QCOMPARE(str1, QString("FoFooFooFooFoooFooFooFoo")); - str1.replace(3, 3, str1); - QCOMPARE(str1, QString("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo")); - str1 = "FooFoo"; - str1.replace(char('F'), str1); - QCOMPARE(str1, QString("FooFooooFooFoooo")); - str1 = "FooFoo"; - str1.replace(char('o'), str1); - QCOMPARE(str1, QString("FFooFooFooFooFFooFooFooFoo")); - - str1 = "Foo"; - str1.replace("Foo", str1); - QCOMPARE(str1, QString("Foo")); - str1.replace(str1, str1); - QCOMPARE(str1, QString("Foo")); - - str1 = "Foo"; - str1.replace("Foo", str1, Qt::CaseInsensitive); - QCOMPARE(str1, QString("Foo")); - str1.replace(str1, str1); - QCOMPARE(str1, QString("Foo")); - - str1 = "FooFoo"; - str1.reserve(100); - str1.replace("oo", str1); - QCOMPARE(str1, QString("FFooFooFFooFoo")); - - str1 = "Bar"; - str1.replace("FooFoo", str1); - QCOMPARE(str1, QString("Bar")); - - str1.replace(str1, "xxx"); - QCOMPARE(str1, QString("xxx")); - str1.replace(str1, QString("yyy")); - QCOMPARE(str1, QString("yyy")); - str1 += str1; - QCOMPARE(str1, QString("yyyyyy")); - } -} - - -void tst_Collections::bitArray() -{ - QBitArray ba(20); - QVERIFY(ba.testBit(17) == false); - ba.setBit(17); - QVERIFY(ba.size() == 20); - QVERIFY(ba.testBit(17)==true); - QVERIFY(!ba.testBit(16)); - ba[4] = true; - QVERIFY(ba.testBit(4)); - QVERIFY(ba[4]); - int sum = 0; - for(int i = 0; i < 20; i++) - sum += ba.testBit(i) ? 1 : 0; - QVERIFY(sum == 2); - - ba = QBitArray(7, true); - QVERIFY(ba.size() == 7); - QVERIFY(ba[5]); - - ba = QBitArray(3); - ba[0] = ba[2] = true; - - QBitArray nba(3); - nba[1] = true; - - QVERIFY(~ba == nba); - -}; - -struct CacheFoo -{ - CacheFoo(int v):val(v) { counter++; } - ~CacheFoo() { counter--; } - int val; - static int counter; - bool isDetached() const { return val != 2; } -}; - -int CacheFoo::counter = 0; - -void tst_Collections::cache() -{ - { - QCache<int, CacheFoo> cache(120); - int i; - for (i = 0; i < 30; i++) { - cache.object(10); - cache.insert(i, new CacheFoo(i), i); - } - - QVERIFY(cache.contains(10)); - QVERIFY(!cache.contains(1)); - QVERIFY(!cache.contains(2)); - delete cache.take(10); - } - { - QCache<int, QString> cache(120); - int i; - QString two; - for (i = 0; i < 30; i++) { - QString s = QString::number(i); - cache.insert(i, new QString(s), i); - if (i == 2) - two = s; - } - QVERIFY(!cache.contains(3)); - QVERIFY(!cache.contains(2)); - } - { - QCache<int, int> cache(100); - cache.insert(2, new int(2)); - *cache[2] = 3; - QVERIFY(*cache.object(2) == 3); - } - - QVERIFY(CacheFoo::counter == 0); - -} - -void tst_Collections::regexp() -{ - QRegExp rx("^\\d\\d?$"); - QVERIFY(rx.indexIn("123") == -1); - QVERIFY(rx.indexIn("-6") == -1); - QVERIFY(rx.indexIn("6") == 0) ; -} - -void tst_Collections::pair() -{ - QPair<double, int> p; - QVERIFY(p.first == 0.0); - QVERIFY(p.second == 0); - - QPair<int, QString> a(1, "Zebra"), b(2, "Ying"), c(3, "Yang"), d(3, "Ying"), e(5, "Alabama"); - QVERIFY(a.first == 1); - QVERIFY(a.second == "Zebra"); - QVERIFY(a == qMakePair(1, QString("Zebra"))); - - QVERIFY(a == a && b == b && c == c && d == d && e == e); - QVERIFY(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e - && d != e); - - QVERIFY(a < b && b < c && c < d && d < e); - QVERIFY(a <= b && b <= c && c <= d && d <= e); - - QVERIFY(e > d && d > c && c > b && b > a); - QVERIFY(e >= d && d >= c && c >= b && b >= a); - - QVERIFY(!(a > b || b > c || c > d || d > e)); - QVERIFY(!(a >= b || b >= c || c >= d || d >= e)); - - QVERIFY(!(e < d || d < c || c < b || b < a)); - QVERIFY(!(e <= d || d <= c || c <= b || b <= a)); - - QVERIFY(a <= a && b <= b && c <= c && d <= d && e <= e); - QVERIFY(!(a < a || b < b || c < c || d < d || e < e)); - - QVERIFY(a >= a && b >= b && c >= c && d >= d && e >= e); - QVERIFY(!(a > a || b > b || c > c || d > d || e > e)); -} - -/* - These test that Java-style mutable iterators don't trash shared - copy (the setSharable() mechanism). -*/ - -template <class Container> -void populate(Container &); - -template <> -void populate(QList<int> &container) -{ - container << 1 << 2 << 4 << 8; -} - -template <> -void populate(QLinkedList<int> &container) -{ - container << 1 << 2 << 4 << 8; -} - -template <> -void populate(QVector<int> &container) -{ - container << 1 << 2 << 4 << 8; -} - -template <> -void populate(QMap<int, int> &container) -{ - container.insert(1, 1); - container.insert(2, 2); - container.insert(4, 4); - container.insert(8, 8); -} - -template <> -void populate(QHash<int, int> &container) -{ - container.insert(1, 1); - container.insert(2, 2); - container.insert(4, 4); - container.insert(8, 8); -} - -template <class Container> -bool isSharable(const Container &container) -{ - Container copy = container; - return !container.isDetached(); -} - -template <class Container> Container newInstance() { - Container container; - populate(container); - if (!container.isEmpty()) - return container; - return Container(); -} - -template <class Container, class ContainerMutableIterator> -void testContainer() -{ - /* - Verify that shared_null's 'sharable' flag is set to true. - */ - { - Container c1; - QVERIFY(!c1.isDetached()); - - Container c2 = c1; - QVERIFY(!c1.isDetached()); - QVERIFY(!c2.isDetached()); - } - - /* - Verify that the 'sharable' flag is true while no mutable - iterator is active. - */ - { - Container c1; - populate(c1); - QVERIFY(c1.size() == 4); - QVERIFY(c1.isDetached()); - - Container c2 = c1; - QVERIFY(c1.size() == 4); - QVERIFY(c2.size() == 4); - QVERIFY(!c1.isDetached()); - QVERIFY(!c2.isDetached()); - } - - /* - Verify that the 'sharable' flag is set to false by the - mutable iterator. - */ - { - Container c1; - populate(c1); - QVERIFY(c1.size() == 4); - QVERIFY(c1.isDetached()); - - ContainerMutableIterator i(c1); - i.next(); - - Container c2 = c1; - QVERIFY(c1.size() == 4); - QVERIFY(c2.size() == 4); - QVERIFY(c1.isDetached()); - QVERIFY(c2.isDetached()); - - i.remove(); - QVERIFY(c1.size() == 3); - QVERIFY(c2.size() == 4); - } - - /* - Verify that the 'sharable' flag is reset to true by the - mutable iterator's destructor. - */ - { - Container c1; - populate(c1); - QVERIFY(c1.size() == 4); - QVERIFY(c1.isDetached()); - - { - ContainerMutableIterator i(c1); - i.next(); - } - - Container c2 = c1; - QVERIFY(c1.size() == 4); - QVERIFY(c2.size() == 4); - QVERIFY(!c1.isDetached()); - QVERIFY(!c2.isDetached()); - } - - /* - Verify that the 'sharable' flag only affects the original - object, not the copies. - */ - { - Container c1; - populate(c1); - QVERIFY(c1.size() == 4); - QVERIFY(c1.isDetached()); - - Container c2 = c1; - QVERIFY(isSharable(c2)); - - ContainerMutableIterator i(c1); - QVERIFY(!isSharable(c1)); - QVERIFY(isSharable(c2)); - - Container c3 = c1; - QVERIFY(!isSharable(c1)); - QVERIFY(isSharable(c2)); - QVERIFY(isSharable(c3)); - QVERIFY(c1.isDetached()); - QVERIFY(c2.isDetached()); - QVERIFY(c3.isDetached()); - - Container c4; - c4 = c1; - QVERIFY(!isSharable(c1)); - QVERIFY(isSharable(c2)); - QVERIFY(isSharable(c4)); - QVERIFY(c1.isDetached()); - QVERIFY(c2.isDetached()); - QVERIFY(c4.isDetached()); - - c3 = c2; - QVERIFY(!isSharable(c1)); - QVERIFY(isSharable(c2)); - QVERIFY(isSharable(c3)); - QVERIFY(c1.isDetached()); - QVERIFY(!c2.isDetached()); - QVERIFY(!c3.isDetached()); - } - - /* test that the move operators work properly */ - { - Container c1 = Container(newInstance<Container>()); - QVERIFY(c1.size() == 4); - QVERIFY(c1 == newInstance<Container>()); - c1 = newInstance<Container>(); - QVERIFY(c1.size() == 4); - QVERIFY(c1 == newInstance<Container>()); - Container c2 = qMove(c1); - QVERIFY(c2.size() == 4); - QVERIFY(c2 == newInstance<Container>()); - } -} - -#define TEST_SEQUENTIAL_CONTAINER(Container) \ - testContainer<Q##Container<int>, QMutable##Container##Iterator<int> >() \ - -#define TEST_ASSOCIATIVE_CONTAINER(Container) \ - testContainer<Q##Container<int, int>, QMutable##Container##Iterator<int, int> >() - -void tst_Collections::sharableQList() -{ - TEST_SEQUENTIAL_CONTAINER(List); -} - -void tst_Collections::sharableQLinkedList() -{ - TEST_SEQUENTIAL_CONTAINER(LinkedList); -} - -void tst_Collections::sharableQVector() -{ - TEST_SEQUENTIAL_CONTAINER(Vector); -} - -void tst_Collections::sharableQMap() -{ - TEST_ASSOCIATIVE_CONTAINER(Map); -} - -void tst_Collections::sharableQHash() -{ - TEST_ASSOCIATIVE_CONTAINER(Hash); -} - -static int getList_calls = 0; -QList<int> getList() -{ - ++getList_calls; - QList<int> list; - list << 1 << 2 << 3 << 4 << 5 << 6; - return list; -} - - -void tst_Collections::q_foreach() -{ - QList<int> list; - list << -2 << -1 << 0 << 1 << 2; - - int sum = 0; - int j = 0; - foreach(int i, list) { - QCOMPARE(i, list.at(j)); - sum += i; - ++j; - } - QCOMPARE(sum, 0); - - // again, but without scope - foreach(int i, list) - sum += i; - QCOMPARE(sum, 0); - - foreach(int i, list) { - sum += i; - if (i == 0) - break; - } - QCOMPARE(sum, -3); - - sum = 0; - foreach(int i, list) { - if (i < 0) - continue; - sum += i; - } - QCOMPARE(sum, 3); - - sum = 0; - getList_calls = 0; - foreach(int i, getList()) - sum += i; - QCOMPARE(sum, 21); - QCOMPARE(getList_calls, 1); -} - - -void tst_Collections::conversions() -{ -#define STUFF "A" << "C" << "B" << "A" - - { - QList<QString> list1; - list1 << STUFF; - - QVector<QString> vect1 = list1.toVector(); - QCOMPARE(list1.size(), 4); - QVERIFY(vect1 == (QVector<QString>() << STUFF)); - - QList<QString> list2 = vect1.toList(); - QCOMPARE(list2.size(), 4); - QVERIFY(list2 == (QList<QString>() << STUFF)); - - QSet<QString> set1 = list1.toSet(); - QCOMPARE(set1.size(), 3); - QVERIFY(set1.contains("A")); - QVERIFY(set1.contains("B")); - QVERIFY(set1.contains("C")); - QVERIFY(!set1.contains("D")); - - QList<QString> list3 = set1.toList(); - QCOMPARE(list3.size(), 3); - QVERIFY(list3.contains("A")); - QVERIFY(list3.contains("B")); - QVERIFY(list3.contains("C")); - QVERIFY(!list3.contains("D")); - - QVERIFY(QList<int>().toVector().isEmpty()); - QVERIFY(QList<int>().toSet().isEmpty()); - QVERIFY(QVector<int>().toList().isEmpty()); - QVERIFY(QSet<int>().toList().isEmpty()); - } - - { - QList<QString> list1; - list1 << STUFF; - - QVector<QString> vect1 = QVector<QString>::fromList(list1); - QCOMPARE(list1.size(), 4); - QVERIFY(vect1 == (QVector<QString>() << STUFF)); - - QList<QString> list2 = QList<QString>::fromVector(vect1); - QCOMPARE(list2.size(), 4); - QVERIFY(list2 == (QList<QString>() << STUFF)); - - QSet<QString> set1 = QSet<QString>::fromList(list1); - QCOMPARE(set1.size(), 3); - QVERIFY(set1.contains("A")); - QVERIFY(set1.contains("B")); - QVERIFY(set1.contains("C")); - QVERIFY(!set1.contains("D")); - - QList<QString> list3 = QList<QString>::fromSet(set1); - QCOMPARE(list3.size(), 3); - QVERIFY(list3.contains("A")); - QVERIFY(list3.contains("B")); - QVERIFY(list3.contains("C")); - QVERIFY(!list3.contains("D")); - - QVERIFY(QVector<int>::fromList(QList<int>()).isEmpty()); - QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty()); - QVERIFY(QList<int>::fromVector(QVector<int>()).isEmpty()); - QVERIFY(QList<int>::fromSet(QSet<int>()).isEmpty()); - } -#undef STUFF -} - -void tst_Collections::javaStyleIterators() -{ - QStringList list; - list << "a" << "b" << "c"; - QMutableStringListIterator i(list); - while (i.hasNext()) { - i.next(); - i.setValue(""); - } - while (i.hasPrevious()) { - i.previous(); - QVERIFY(i.value().isEmpty()); - i.value() = "x"; - QCOMPARE(i.value(), QString("x")); - } -} - -template <class Container> -void testLinkedListLikeStlIterators() -{ - Container fake; - typename Container::value_type t; - fake << t; - - typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; - typename Container::const_iterator c1 = i1, c2 = c1 + 1; - - QVERIFY(i1 == i1); - QVERIFY(i1 == c1); - QVERIFY(c1 == i1); - QVERIFY(c1 == c1); - QVERIFY(i2 == i2); - QVERIFY(i2 == c2); - QVERIFY(c2 == i2); - QVERIFY(c2 == c2); - - QVERIFY(i1 != i2); - QVERIFY(i1 != c2); - QVERIFY(c1 != i2); - QVERIFY(c1 != c2); - QVERIFY(i2 != i1); - QVERIFY(i2 != c1); - QVERIFY(c2 != i1); - QVERIFY(c2 != c1); -} - -template <class Container> -void testListLikeStlIterators() -{ - testLinkedListLikeStlIterators<Container>(); - - Container fake; - typename Container::value_type t; - fake << t; - - typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; - typename Container::const_iterator c1 = i1, c2 = c1 + 1; - - QVERIFY(i1 < i2); - QVERIFY(i1 < c2); - QVERIFY(c1 < i2); - QVERIFY(c1 < c2); - QVERIFY(!(i2 < i1)); - QVERIFY(!(i2 < c1)); - QVERIFY(!(c2 < i1)); - QVERIFY(!(c2 < c1)); - QVERIFY(!(i1 < i1)); - QVERIFY(!(i1 < c1)); - QVERIFY(!(c1 < i1)); - QVERIFY(!(c1 < c1)); - QVERIFY(!(i2 < i2)); - QVERIFY(!(i2 < c2)); - QVERIFY(!(c2 < i2)); - QVERIFY(!(c2 < c2)); - - QVERIFY(i2 > i1); - QVERIFY(i2 > c1); - QVERIFY(c2 > i1); - QVERIFY(c2 > c1); - QVERIFY(!(i1 > i2)); - QVERIFY(!(i1 > c2)); - QVERIFY(!(c1 > i2)); - QVERIFY(!(c1 > c2)); - QVERIFY(!(i1 > i1)); - QVERIFY(!(i1 > c1)); - QVERIFY(!(c1 > i1)); - QVERIFY(!(c1 > c1)); - QVERIFY(!(i2 > i2)); - QVERIFY(!(i2 > c2)); - QVERIFY(!(c2 > i2)); - QVERIFY(!(c2 > c2)); - - QVERIFY(!(i1 >= i2)); - QVERIFY(!(i1 >= c2)); - QVERIFY(!(c1 >= i2)); - QVERIFY(!(c1 >= c2)); - QVERIFY(i2 >= i1); - QVERIFY(i2 >= c1); - QVERIFY(c2 >= i1); - QVERIFY(c2 >= c1); - QVERIFY(i1 >= i1); - QVERIFY(i1 >= c1); - QVERIFY(c1 >= i1); - QVERIFY(c1 >= c1); - QVERIFY(i2 >= i2); - QVERIFY(i2 >= c2); - QVERIFY(c2 >= i2); - QVERIFY(c2 >= c2); - - QVERIFY(!(i2 <= i1)); - QVERIFY(!(i2 <= c1)); - QVERIFY(!(c2 <= i1)); - QVERIFY(!(c2 <= c1)); - QVERIFY(i1 <= i2); - QVERIFY(i1 <= c2); - QVERIFY(c1 <= i2); - QVERIFY(c1 <= c2); - QVERIFY(i1 <= i1); - QVERIFY(i1 <= c1); - QVERIFY(c1 <= i1); - QVERIFY(c1 <= c1); - QVERIFY(i2 <= i2); - QVERIFY(i2 <= c2); - QVERIFY(c2 <= i2); - QVERIFY(c2 <= c2); -} - -template <class Container> -void testMapLikeStlIterators() -{ - Container fake; - QString k; - QString t; - fake.insert(k, t); - - typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; - typename Container::const_iterator c1 = i1, c2 = c1 + 1; - - QVERIFY(i1 == i1); - QVERIFY(i1 == c1); - QVERIFY(c1 == i1); - QVERIFY(c1 == c1); - QVERIFY(i2 == i2); - QVERIFY(i2 == c2); - QVERIFY(c2 == i2); - QVERIFY(c2 == c2); - - QVERIFY(i1 != i2); - QVERIFY(i1 != c2); - QVERIFY(c1 != i2); - QVERIFY(c1 != c2); - QVERIFY(i2 != i1); - QVERIFY(i2 != c1); - QVERIFY(c2 != i1); - QVERIFY(c2 != c1); -} - -void tst_Collections::constAndNonConstStlIterators() -{ - testListLikeStlIterators<QList<int> >(); - testListLikeStlIterators<QStringList >(); - testLinkedListLikeStlIterators<QLinkedList<int> >(); - testListLikeStlIterators<QVector<int> >(); - testMapLikeStlIterators<QMap<QString, QString> >(); - testMapLikeStlIterators<QMultiMap<QString, QString> >(); - testMapLikeStlIterators<QHash<QString, QString> >(); - testMapLikeStlIterators<QMultiHash<QString, QString> >(); -} - -void tst_Collections::vector_stl_data() -{ - QTest::addColumn<QStringList>("elements"); - - QTest::newRow("empty") << QStringList(); - QTest::newRow("one") << (QStringList() << "Hei"); - QTest::newRow("two") << (QStringList() << "Hei" << "Hopp"); - QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann"); -} - -void tst_Collections::vector_stl() -{ - QFETCH(QStringList, elements); - - QVector<QString> vector; - for (int i = 0; i < elements.count(); ++i) - vector << elements.at(i); - - std::vector<QString> stdVector = vector.toStdVector(); - - QCOMPARE(int(stdVector.size()), elements.size()); - - std::vector<QString>::const_iterator it = stdVector.begin(); - for (uint j = 0; j < stdVector.size() && it != stdVector.end(); ++j, ++it) - QCOMPARE(*it, vector[j]); - - QCOMPARE(QVector<QString>::fromStdVector(stdVector), vector); -} - -void tst_Collections::linkedlist_stl_data() -{ - list_stl_data(); -} - -void tst_Collections::linkedlist_stl() -{ - QFETCH(QStringList, elements); - - QLinkedList<QString> list; - for (int i = 0; i < elements.count(); ++i) - list << elements.at(i); - - std::list<QString> stdList = list.toStdList(); - - QCOMPARE(int(stdList.size()), elements.size()); - - std::list<QString>::const_iterator it = stdList.begin(); - QLinkedList<QString>::const_iterator it2 = list.cbegin(); - for (uint j = 0; j < stdList.size(); ++j, ++it, ++it2) - QCOMPARE(*it, *it2); - - QCOMPARE(QLinkedList<QString>::fromStdList(stdList), list); -} - -void tst_Collections::list_stl_data() -{ - QTest::addColumn<QStringList>("elements"); - - QTest::newRow("empty") << QStringList(); - QTest::newRow("one") << (QStringList() << "Hei"); - QTest::newRow("two") << (QStringList() << "Hei" << "Hopp"); - QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann"); -} - -void tst_Collections::list_stl() -{ - QFETCH(QStringList, elements); - - QList<QString> list; - for (int i = 0; i < elements.count(); ++i) - list << elements.at(i); - - std::list<QString> stdList = list.toStdList(); - - QCOMPARE(int(stdList.size()), elements.size()); - - std::list<QString>::const_iterator it = stdList.begin(); - for (uint j = 0; j < stdList.size() && it != stdList.end(); ++j, ++it) - QCOMPARE(*it, list[j]); - - QCOMPARE(QList<QString>::fromStdList(stdList), list); -} - -template <typename T> -T qtInit(T * = 0) -{ - return T(); -} - -void tst_Collections::q_init() -{ - QCOMPARE(qtInit<int>(), 0); - QCOMPARE(qtInit<double>(), 0.0); - QCOMPARE(qtInit<QString>(), QString()); - QCOMPARE(qtInit<int *>(), static_cast<int *>(0)); - QCOMPARE(qtInit<double *>(), static_cast<double *>(0)); - QCOMPARE(qtInit<QString *>(), static_cast<QString *>(0)); - QCOMPARE(qtInit<Pod>().i1, 0); - QCOMPARE(qtInit<Pod>().i2, 0); -} - -void tst_Collections::pointersize() -{ - QCOMPARE(int(sizeof(void *)), QT_POINTER_SIZE); -} - -class LessThanComparable -{ -public: - bool operator<(const LessThanComparable &) const { return true; } -}; - -class EqualsComparable -{ -public: - bool operator==(const EqualsComparable &) const { return true; } -}; - -uint qHash(const EqualsComparable &) -{ - return 0; -} - -/* - The following functions instatiates every member functions in the - Qt containers that requires either operator== or operator<. - They are ordered in a concept inheritance tree: - - Container - MutableIterationContainer - Sequence (QLinkedList) - Random Access (QVector, QList, QQueue, QStack) - Pair Associative (QHash, QMap) - Associative (QSet) -*/ -template <typename ContainerType, typename ValueType> -void instantiateContainer() -{ - const ValueType value = ValueType(); - ContainerType container; - const ContainerType constContainer(container); - - typename ContainerType::const_iterator constIt; - constIt = constContainer.begin(); - constIt = container.cbegin(); - container.constBegin(); - - constIt = constContainer.end(); - constIt = constContainer.cend(); - container.constEnd(); - Q_UNUSED(constIt) - - container.clear(); - container.contains(value); - container.count(); - container.empty(); - container.isEmpty(); - container.size(); - - Q_UNUSED((container != constContainer)); - Q_UNUSED((container == constContainer)); - container = constContainer; -} - -template <typename ContainerType, typename ValueType> -void instantiateMutableIterationContainer() -{ - instantiateContainer<ContainerType, ValueType>(); - ContainerType container; - - typename ContainerType::iterator it; - it = container.begin(); - it = container.end(); - Q_UNUSED(it) - - // QSet lacks count(T). - const ValueType value = ValueType(); - container.count(value); -} - -template <typename ContainerType, typename ValueType> -void instantiateSequence() -{ - instantiateMutableIterationContainer<ContainerType, ValueType>(); - -// QVector lacks removeAll(T) -// ValueType value = ValueType(); -// ContainerType container; -// container.removeAll(value); -} - -template <typename ContainerType, typename ValueType> -void instantiateRandomAccess() -{ - instantiateSequence<ContainerType, ValueType>(); - - ValueType value = ValueType(); - ContainerType container; - container.indexOf(value); - container.lastIndexOf(value); -} - -template <typename ContainerType, typename ValueType> -void instantiateAssociative() -{ - instantiateContainer<ContainerType, ValueType>(); - - const ValueType value = ValueType(); - ContainerType container; - const ContainerType constContainer(container); - - container.reserve(1); - container.capacity(); - container.squeeze(); - - container.remove(value); - container.values(); - - container.unite(constContainer); - container.intersect(constContainer); - container.subtract(constContainer); - - Q_UNUSED((container != constContainer)); - Q_UNUSED((container == constContainer)); - container & constContainer; - container &= constContainer; - container &= value; - container + constContainer; - container += constContainer; - container += value; - container - constContainer; - container -= constContainer; - container -= value; - container | constContainer; - container |= constContainer; - container |= value; -} - -template <typename ContainerType, typename KeyType, typename ValueType> -void instantiatePairAssociative() -{ - instantiateMutableIterationContainer<ContainerType, KeyType>(); - - typename ContainerType::iterator it; - typename ContainerType::const_iterator constIt; - const KeyType key = KeyType(); - const ValueType value = ValueType(); - ContainerType container; - const ContainerType constContainer(container); - - it = container.insert(key, value); - container.erase(it); - container.find(key); - container.constFind(key); - constContainer.find(key); - - container.key(value); - container.keys(); - constContainer.keys(); - container.remove(key); - container.take(key); - container.unite(constContainer); - container.value(key); - container.value(key, value); - container.values(); - container.values(key); - container[key]; - const int foo = constContainer[key]; - Q_UNUSED(foo); -} - -/* - Instantiate all Qt containers using a datatype that - defines the minimum amount of operators. -*/ -void tst_Collections::containerInstantiation() -{ - // Instantiate QHash member functions. - typedef QHash<EqualsComparable, int> Hash; - instantiatePairAssociative<Hash, EqualsComparable, int>(); - - Hash hash; - hash.reserve(1); - hash.capacity(); - hash.squeeze(); - - // Instantiate QMap member functions. - typedef QMap<LessThanComparable, int> Map; - instantiatePairAssociative<Map, LessThanComparable, int>(); - - // Instantiate QSet member functions. - typedef QSet<EqualsComparable> Set; - instantiateAssociative<Set, EqualsComparable>(); - - //Instantiate QLinkedList member functions. - typedef QLinkedList<EqualsComparable> LinkedList; - instantiateSequence<LinkedList, EqualsComparable> (); - { - EqualsComparable value; - LinkedList list; - list.removeAll(value); - } - - //Instantiate QList member functions. - typedef QList<EqualsComparable> List; - instantiateRandomAccess<List, EqualsComparable>(); - { - EqualsComparable value; - List list; - list.removeAll(value); - } - - //Instantiate QVector member functions. - typedef QVector<EqualsComparable> Vector; - instantiateRandomAccess<Vector, EqualsComparable>(); - - //Instantiate QQueue member functions. - typedef QQueue<EqualsComparable> Queue; - instantiateRandomAccess<Queue, EqualsComparable>(); - - //Instantiate QStack member functions. - typedef QStack<EqualsComparable> Stack; - instantiateRandomAccess<Stack, EqualsComparable>(); -} - -void tst_Collections::qtimerList() -{ - QList<double> foo; - const int N = 10000; - - foo.append(99.9); - foo.append(99.9); - foo.append(99.9); - - for(int i = 0; i < N; i++) { - foo.removeFirst(); - foo.insert(1, 99.9); - } - - QList<double>::Iterator end = foo.end(); - for (int i = 0; i < (N / 2) - 10; ++i) { - foo.prepend(99.9); - if (foo.end() != end) - return; - } - QFAIL("QList preallocates too much memory"); -} - -template <typename Container> -void testContainerTypedefs(Container container) -{ - Q_UNUSED(container) - { typedef typename Container::value_type Foo; } - { typedef typename Container::iterator Foo; } - { typedef typename Container::const_iterator Foo; } - { typedef typename Container::reference Foo; } - { typedef typename Container::const_reference Foo; } - { typedef typename Container::pointer Foo; } - { typedef typename Container::difference_type Foo; } - { typedef typename Container::size_type Foo; } -} - -template <typename Container> -void testPairAssociativeContainerTypedefs(Container container) -{ - Q_UNUSED(container) - -// TODO: Not sure how to define value_type for our associative containers -// { typedef typename Container::value_type Foo; } -// { typedef typename Container::const_iterator Foo; } -// { typedef typename Container::reference Foo; } -// { typedef typename Container::const_reference Foo; } -// { typedef typename Container::pointer Foo; } - - { typedef typename Container::difference_type Foo; } - { typedef typename Container::size_type Foo; } - { typedef typename Container::iterator Foo; } - { typedef typename Container::key_type Foo; } - { typedef typename Container::mapped_type Foo; } -// TODO -// { typedef typename Container::key_compare Foo; } -// { typedef typename Container::value_comare Foo; } -} - -template <typename Container> -void testSetContainerTypedefs(Container container) -{ - Q_UNUSED(container) - { typedef typename Container::iterator Foo; } - { typedef typename Container::const_iterator Foo; } - { typedef typename Container::reference Foo; } - { typedef typename Container::const_reference Foo; } - { typedef typename Container::pointer Foo; } - { typedef typename Container::difference_type Foo; } - { typedef typename Container::size_type Foo; } - { typedef typename Container::key_type Foo; } -} - -/* - Compile-time test that verifies that the Qt containers - have STL-compatable typedefs. -*/ -void tst_Collections::containerTypedefs() -{ - testContainerTypedefs(QVector<int>()); - testContainerTypedefs(QStack<int>()); - testContainerTypedefs(QList<int>()); - testContainerTypedefs(QLinkedList<int>()); - testContainerTypedefs(QQueue<int>()); - - testPairAssociativeContainerTypedefs(QMap<int, int>()); - testPairAssociativeContainerTypedefs(QMultiMap<int, int>()); - testPairAssociativeContainerTypedefs(QHash<int, int>()); - - testSetContainerTypedefs(QSet<int>()); -} - -class Key1; -class T1; -class T2; - -void tst_Collections::forwardDeclared() -{ - { typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QPair<T1, T2> C; C *x = 0; Q_UNUSED(x) } - { typedef QList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QVector<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) } - { typedef QStack<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) } - { typedef QQueue<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } - { typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) } -} - -#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN) - -class Q_DECL_ALIGN(4) Aligned4 -{ - char i; -public: - Aligned4(int i = 0) : i(i) {} - - enum { PreferredAlignment = 4 }; - - inline bool operator==(const Aligned4 &other) const { return i == other.i; } - inline bool operator<(const Aligned4 &other) const { return i < other.i; } - friend inline int qHash(const Aligned4 &a) { return qHash(a.i); } -}; -Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0); - -class Q_DECL_ALIGN(128) Aligned128 -{ - char i; -public: - Aligned128(int i = 0) : i(i) {} - - enum { PreferredAlignment = 128 }; - - inline bool operator==(const Aligned128 &other) const { return i == other.i; } - inline bool operator<(const Aligned128 &other) const { return i < other.i; } - friend inline int qHash(const Aligned128 &a) { return qHash(a.i); } -}; -Q_STATIC_ASSERT(Q_ALIGNOF(Aligned128) % 128 == 0); - -template<typename C> -void testVectorAlignment() -{ - typedef typename C::value_type Aligned; - C container; - container.append(Aligned()); - QCOMPARE(quintptr(&container[0]) % Aligned::PreferredAlignment, quintptr(0)); - - for (int i = 0; i < 200; ++i) - container.append(Aligned()); - - for (int i = 0; i < container.size(); ++i) - QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); -} - -template<typename C> -void testContiguousCacheAlignment() -{ - typedef typename C::value_type Aligned; - C container(150); - container.append(Aligned()); - QCOMPARE(quintptr(&container[container.firstIndex()]) % Aligned::PreferredAlignment, quintptr(0)); - - for (int i = 0; i < 200; ++i) - container.append(Aligned()); - - for (int i = container.firstIndex(); i < container.lastIndex(); ++i) - QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); -} - -template<typename C> -void testAssociativeContainerAlignment() -{ - typedef typename C::key_type Key; - typedef typename C::mapped_type Value; - C container; - container.insert(Key(), Value()); - - typename C::const_iterator it = container.constBegin(); - QCOMPARE(quintptr(&it.key()) % Key::PreferredAlignment, quintptr(0)); - QCOMPARE(quintptr(&it.value()) % Value::PreferredAlignment, quintptr(0)); - - // add some more elements - for (int i = 0; i < 200; ++i) - container.insert(Key(i), Value(i)); - - it = container.constBegin(); - for ( ; it != container.constEnd(); ++it) { - QCOMPARE(quintptr(&it.key()) % Key::PreferredAlignment, quintptr(0)); - QCOMPARE(quintptr(&it.value()) % Value::PreferredAlignment, quintptr(0)); - } -} - -void tst_Collections::alignment() -{ - testVectorAlignment<QVector<Aligned4> >(); - testVectorAlignment<QVector<Aligned128> >(); - testContiguousCacheAlignment<QContiguousCache<Aligned4> >(); - testContiguousCacheAlignment<QContiguousCache<Aligned128> >(); - testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >(); - testAssociativeContainerAlignment<QMap<Aligned4, Aligned128> >(); - testAssociativeContainerAlignment<QMap<Aligned128, Aligned4> >(); - testAssociativeContainerAlignment<QMap<Aligned128, Aligned128> >(); - testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >(); - testAssociativeContainerAlignment<QHash<Aligned4, Aligned128> >(); - testAssociativeContainerAlignment<QHash<Aligned128, Aligned4> >(); - testAssociativeContainerAlignment<QHash<Aligned128, Aligned128> >(); -} - -#else -void tst_Collections::alignment() -{ - QSKIP("Compiler doesn't support necessary extension keywords"); -} -#endif - -#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS - -template<template<class> class C> -struct QTBUG13079_Node { - C<QTBUG13079_Node> children; - QString s; - - ~QTBUG13079_Node() { - children.begin(); //play with memory - } -}; -template<template<class> class C> void QTBUG13079_collectionInsideCollectionImpl() -{ - C<QTBUG13079_Node<C> > nodeList; - nodeList << QTBUG13079_Node<C>(); - nodeList.first().s = "parent"; - nodeList.first().children << QTBUG13079_Node<C>(); - nodeList.first().children.first().s = "child"; - - nodeList = nodeList.first().children; - QCOMPARE(nodeList.first().s, QString::fromLatin1("child")); - - nodeList = nodeList.first().children; - QCOMPARE(nodeList.count(), 0); - nodeList << QTBUG13079_Node<C>(); -} - -template<template<class, class> class C> -struct QTBUG13079_NodeAssoc { - C<int, QTBUG13079_NodeAssoc> children; - QString s; - - ~QTBUG13079_NodeAssoc() { - children.begin(); //play with memory - } -}; -template<template<class, class> class C> void QTBUG13079_collectionInsideCollectionAssocImpl() -{ - C<int, QTBUG13079_NodeAssoc<C> > nodeMap; - nodeMap[18] = QTBUG13079_NodeAssoc<C>(); - nodeMap[18].s = "parent"; - nodeMap[18].children[12] = QTBUG13079_NodeAssoc<C>(); - nodeMap[18].children[12].s = "child"; - - nodeMap = nodeMap[18].children; - QCOMPARE(nodeMap[12].s, QString::fromLatin1("child")); - - nodeMap = nodeMap[12].children; - QCOMPARE(nodeMap.count(), 0); - nodeMap[42] = QTBUG13079_NodeAssoc<C>(); -} - - -quint32 qHash(const QTBUG13079_Node<QSet> &) -{ - return 0; -} - -bool operator==(const QTBUG13079_Node<QSet> &a, const QTBUG13079_Node<QSet> &b) -{ - return a.s == b.s && a.children == b.children; -} - -template<template<class> class C> -struct QTBUG13079_NodePtr : QSharedData { - C<QTBUG13079_NodePtr> child; - QTBUG13079_NodePtr *next; - QString s; - - QTBUG13079_NodePtr() : next(0) {} - ~QTBUG13079_NodePtr() { - next = child.data(); //play with memory - } -}; -template<template<class> class C> void QTBUG13079_collectionInsidePtrImpl() -{ - typedef C<QTBUG13079_NodePtr<C> > Ptr; - { - Ptr nodePtr; - nodePtr = Ptr(new QTBUG13079_NodePtr<C>()); - nodePtr->s = "parent"; - nodePtr->child = Ptr(new QTBUG13079_NodePtr<C>()); - nodePtr->child->s = "child"; - nodePtr = nodePtr->child; - QCOMPARE(nodePtr->s, QString::fromLatin1("child")); - nodePtr = nodePtr->child; - QVERIFY(!nodePtr); - } - { - Ptr nodePtr; - nodePtr = Ptr(new QTBUG13079_NodePtr<C>()); - nodePtr->s = "parent"; - nodePtr->next = new QTBUG13079_NodePtr<C>(); - nodePtr->next->s = "next"; - nodePtr = Ptr(nodePtr->next); - QCOMPARE(nodePtr->s, QString::fromLatin1("next")); - nodePtr = Ptr(nodePtr->next); - QVERIFY(!nodePtr); - } -} - -#endif - -void tst_Collections::QTBUG13079_collectionInsideCollection() -{ -#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS - QTBUG13079_collectionInsideCollectionImpl<QVector>(); - QTBUG13079_collectionInsideCollectionImpl<QStack>(); - QTBUG13079_collectionInsideCollectionImpl<QList>(); - QTBUG13079_collectionInsideCollectionImpl<QLinkedList>(); - QTBUG13079_collectionInsideCollectionImpl<QQueue>(); - - { - QSet<QTBUG13079_Node<QSet> > nodeSet; - nodeSet << QTBUG13079_Node<QSet>(); - nodeSet = nodeSet.begin()->children; - QCOMPARE(nodeSet.count(), 0); - } - - QTBUG13079_collectionInsideCollectionAssocImpl<QMap>(); - QTBUG13079_collectionInsideCollectionAssocImpl<QHash>(); - - QTBUG13079_collectionInsidePtrImpl<QSharedPointer>(); - QTBUG13079_collectionInsidePtrImpl<QExplicitlySharedDataPointer>(); - QTBUG13079_collectionInsidePtrImpl<QSharedDataPointer>(); -#endif -} - -template<class Container> void foreach_test_arrays(const Container &container) -{ - typedef typename Container::value_type T; - int i = 0; - QSet <T> set; - foreach(const T & val, container) { - QVERIFY( val == container[i] ); - set << val; - i++; - } - QCOMPARE(set.count(), container.count()); - - //modify the container while iterating. - Container c2 = container; - Container c3; - i = 0; - foreach (T val, c2) { - c3 << val; - c2.insert((i * 89) % c2.size(), T() ); - QVERIFY( val == container.at(i) ); - val = T(); - i++; - } - QVERIFY(c3 == container); -} - - -void tst_Collections::foreach_2() -{ - QStringList strlist = QString::fromLatin1("a,b,c,d,e,f,g,h,ih,kl,mn,op,qr,st,uvw,xyz").split(","); - foreach_test_arrays(strlist); - foreach_test_arrays(QList<QString>(strlist)); - foreach_test_arrays(strlist.toVector()); - - QList<int> intlist; - intlist << 1 << 2 << 3 << 4 <<5 << 6 << 7 << 8 << 9; - foreach_test_arrays(intlist); - foreach_test_arrays(intlist.toVector()); - - QVarLengthArray<int> varl1; - QVarLengthArray<int, 3> varl2; - QVarLengthArray<int, 10> varl3; - foreach(int i, intlist) { - varl1 << i; - varl2 << i; - varl3 << i; - } - QCOMPARE(varl1.count(), intlist.count()); - QCOMPARE(varl2.count(), intlist.count()); - QCOMPARE(varl3.count(), intlist.count()); - foreach_test_arrays(varl1); - foreach_test_arrays(varl2); - foreach_test_arrays(varl3); - - QVarLengthArray<QString> varl4; - QVarLengthArray<QString, 3> varl5; - QVarLengthArray<QString, 18> varl6; - foreach(const QString &str, strlist) { - varl4 << str; - varl5 << str; - varl6 << str; - } - QCOMPARE(varl4.count(), strlist.count()); - QCOMPARE(varl5.count(), strlist.count()); - QCOMPARE(varl6.count(), strlist.count()); - foreach_test_arrays(varl4); - foreach_test_arrays(varl5); - foreach_test_arrays(varl6); -} - -struct IntOrString -{ - int val; - IntOrString(int v) : val(v) { } - IntOrString(const QString &v) : val(v.toInt()) { } - operator int() { return val; } - operator QString() { return QString::number(val); } - operator std::string() { return QString::number(val).toStdString(); } - IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { } -}; - -template<class Container> void insert_remove_loop_impl() -{ - typedef typename Container::value_type T; - Container t; - t.append(T(IntOrString(1))); - t << (T(IntOrString(2))); - t += (T(IntOrString(3))); - t.prepend(T(IntOrString(4))); - t.insert(2, 3 , T(IntOrString(5))); - t.insert(4, T(IntOrString(6))); - t.insert(t.begin() + 2, T(IntOrString(7))); - t.insert(t.begin() + 5, 3, T(IntOrString(8))); - int expect1[] = { 4 , 1 , 7, 5 , 5 , 8, 8, 8, 6, 5, 2 , 3 }; - QCOMPARE(size_t(t.count()), sizeof(expect1)/sizeof(int)); - for (int i = 0; i < t.count(); i++) { - QCOMPARE(t[i], T(IntOrString(expect1[i]))); - } - - Container compare_test1 = t; - t.replace(5, T(IntOrString(9))); - Container compare_test2 = t; - QVERIFY(!(compare_test1 == t)); - QVERIFY( (compare_test1 != t)); - QVERIFY( (compare_test2 == t)); - QVERIFY(!(compare_test2 != t)); - t.remove(7); - t.remove(2, 3); - int expect2[] = { 4 , 1 , 9, 8, 6, 5, 2 , 3 }; - QCOMPARE(size_t(t.count()), sizeof(expect2)/sizeof(int)); - for (int i = 0; i < t.count(); i++) { - QCOMPARE(t[i], T(IntOrString(expect2[i]))); - } - - for (typename Container::iterator it = t.begin(); it != t.end(); ) { - if ( int(IntOrString(*it)) % 2 ) - ++it; - else - it = t.erase(it); - } - - int expect3[] = { 1 , 9, 5, 3 }; - QCOMPARE(size_t(t.count()), sizeof(expect3)/sizeof(int)); - for (int i = 0; i < t.count(); i++) { - QCOMPARE(t[i], T(IntOrString(expect3[i]))); - } - - t.erase(t.begin() + 1, t.end() - 1); - - int expect4[] = { 1 , 3 }; - QCOMPARE(size_t(t.count()), sizeof(expect4)/sizeof(int)); - for (int i = 0; i < t.count(); i++) { - QCOMPARE(t[i], T(IntOrString(expect4[i]))); - } - - t << T(IntOrString(10)) << T(IntOrString(11)) << T(IntOrString(12)) << T(IntOrString(13)); - t << T(IntOrString(14)) << T(IntOrString(15)) << T(IntOrString(16)) << T(IntOrString(17)); - t << T(IntOrString(18)) << T(IntOrString(19)) << T(IntOrString(20)) << T(IntOrString(21)); - for (typename Container::iterator it = t.begin(); it != t.end(); ++it) { - int iv = int(IntOrString(*it)); - if ( iv % 2 ) { - it = t.insert(it, T(IntOrString(iv * iv))); - it = t.insert(it + 2, T(IntOrString(iv * iv + 1))); - } - } - - int expect5[] = { 1, 1, 2, 3*3, 3, 3*3+1, 10, 11*11, 11, 11*11+1, 12 , 13*13, 13, 13*13+1, 14, - 15*15, 15, 15*15+1, 16 , 17*17, 17, 17*17+1 ,18 , 19*19, 19, 19*19+1, 20, 21*21, 21, 21*21+1 }; - QCOMPARE(size_t(t.count()), sizeof(expect5)/sizeof(int)); - for (int i = 0; i < t.count(); i++) { - QCOMPARE(t[i], T(IntOrString(expect5[i]))); - } -} - - -//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test. -template<typename T> -struct ExtList : QList<T> { - using QList<T>::insert; - void insert(int before, int n, const T&x) { - while (n--) { - this->insert(before, x ); - } - } - void insert(typename QList<T>::iterator before, int n, const T&x) { - while (n--) { - before = this->insert(before, x); - } - } - - void remove(int i) { - this->removeAt(i); - } - void remove(int i, int n) { - while (n--) { - this->removeAt(i); - } - } -}; - -void tst_Collections::insert_remove_loop() -{ - insert_remove_loop_impl<ExtList<int> >(); - insert_remove_loop_impl<ExtList<QString> >(); - insert_remove_loop_impl<QVector<int> >(); - insert_remove_loop_impl<QVector<QString> >(); - insert_remove_loop_impl<QVarLengthArray<int> >(); - insert_remove_loop_impl<QVarLengthArray<QString> >(); - insert_remove_loop_impl<QVarLengthArray<int, 10> >(); - insert_remove_loop_impl<QVarLengthArray<QString, 10> >(); - insert_remove_loop_impl<QVarLengthArray<int, 3> >(); - insert_remove_loop_impl<QVarLengthArray<QString, 3> >(); - insert_remove_loop_impl<QVarLengthArray<int, 15> >(); - insert_remove_loop_impl<QVarLengthArray<QString, 15> >(); - - insert_remove_loop_impl<ExtList<std::string> >(); - insert_remove_loop_impl<QVector<std::string> >(); - insert_remove_loop_impl<QVarLengthArray<std::string> >(); - insert_remove_loop_impl<QVarLengthArray<std::string, 10> >(); - insert_remove_loop_impl<QVarLengthArray<std::string, 3> >(); - insert_remove_loop_impl<QVarLengthArray<std::string, 15> >(); -} - - - -QTEST_APPLESS_MAIN(tst_Collections) -#include "tst_collections.moc" diff --git a/tests/auto/other/compiler/compiler.pro b/tests/auto/other/compiler/compiler.pro index 8ebcf60bc0..213429050f 100644 --- a/tests/auto/other/compiler/compiler.pro +++ b/tests/auto/other/compiler/compiler.pro @@ -1,9 +1,9 @@ CONFIG += testcase TARGET = tst_compiler -SOURCES += tst_compiler.cpp baseclass.cpp derivedclass.cpp +SOURCES += tst_compiler.cpp baseclass.cpp derivedclass.cpp othersource.cpp HEADERS += baseclass.h derivedclass.h QT = core testlib - +contains(QT_CONFIG, c++11): CONFIG += c++14 c++11 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/compiler/othersource.cpp b/tests/auto/other/compiler/othersource.cpp new file mode 100644 index 0000000000..6ff7c4d8a9 --- /dev/null +++ b/tests/auto/other/compiler/othersource.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Intel Corporation. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qglobal.h> + +#ifdef Q_COMPILER_EXTERN_TEMPLATES +template <typename T> T externTemplate(); +template<> int externTemplate<int>() +{ + return 42; +} +#endif + diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index a239e2c888..9ed5c64c4f 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Intel Corporation ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -48,12 +49,17 @@ #include "baseclass.h" #include "derivedclass.h" +#ifdef Q_COMPILER_ATOMICS +# include <atomic> +#endif + QT_USE_NAMESPACE class tst_Compiler : public QObject { Q_OBJECT private slots: + /* C++98 & C++03 base functionality */ void template_methods(); void template_constructors(); void template_subclasses(); @@ -71,6 +77,57 @@ private slots: void charSignedness() const; void privateStaticTemplateMember() const; void staticConstUnionWithInitializerList() const; + void templateFriends(); + + /* C++11 features */ + void cxx11_alignas(); + void cxx11_alignof(); + void cxx11_alignas_alignof(); + void cxx11_atomics(); + void cxx11_attributes(); + void cxx11_auto_function(); + void cxx11_auto_type(); + void cxx11_class_enum(); + void cxx11_constexpr(); + void cxx11_decltype(); + void cxx11_default_members(); + void cxx11_delete_members(); + void cxx11_delegating_constructors(); + void cxx11_explicit_conversions(); + void cxx11_explicit_overrides(); + void cxx11_extern_templates(); + void cxx11_inheriting_constructors(); + void cxx11_initializer_lists(); + void cxx11_lambda(); + void cxx11_nonstatic_member_init(); + void cxx11_noexcept(); + void cxx11_nullptr(); + void cxx11_range_for(); + void cxx11_raw_strings(); + void cxx11_ref_qualifiers(); + void cxx11_rvalue_refs(); + void cxx11_static_assert(); + void cxx11_template_alias(); + void cxx11_thread_local(); + void cxx11_udl(); + void cxx11_unicode_strings(); + void cxx11_uniform_init(); + void cxx11_unrestricted_unions(); + void cxx11_variadic_macros(); + void cxx11_variadic_templates(); + + /* C++14 compiler features */ + void cxx14_binary_literals(); + void cxx14_init_captures(); + void cxx14_generic_lambdas(); + void cxx14_constexpr(); + void cxx14_decltype_auto(); + void cxx14_return_type_deduction(); + void cxx14_aggregate_nsdmi(); + void cxx14_variable_templates(); + + /* Future / Technical specification compiler features */ + void runtimeArrays(); }; #if defined(Q_CC_HPACC) @@ -556,5 +613,706 @@ void tst_Compiler::staticConstUnionWithInitializerList() const QVERIFY(qIsInf(d)); } +#ifndef Q_NO_TEMPLATE_FRIENDS +template <typename T> class TemplateFriends +{ + T value; +public: + TemplateFriends(T value) : value(value) {} + + template <typename X> void copy(TemplateFriends<X> other) + { value = other.value; } + + template <typename X> friend class TemplateFriends; +}; + +void tst_Compiler::templateFriends() +{ + TemplateFriends<int> ti(42); + TemplateFriends<long> tl(0); + tl.copy(ti); +} +#else +void tst_Compiler::templateFriends() +{ + QSKIP("Compiler does not support template friends"); +} +#endif + +void tst_Compiler::cxx11_alignas() +{ +#ifndef Q_COMPILER_ALIGNAS + QSKIP("Compiler does not support C++11 feature"); +#else + alignas(double) char c; + QVERIFY(Q_ALIGNOF(c) == Q_ALIGNOF(double)); +#endif +} + +void tst_Compiler::cxx11_alignof() +{ +#ifndef Q_COMPILER_ALIGNOF + QSKIP("Compiler does not support C++11 feature"); +#else + size_t alignchar = alignof(char); + size_t aligndouble = alignof(double); + QVERIFY(alignchar >= 1); + QVERIFY(alignchar <= aligndouble); +#endif +} + +void tst_Compiler::cxx11_alignas_alignof() +{ +#if !defined(Q_COMPILER_ALIGNAS) && !defined(Q_COMPILER_ALIGNOF) + QSKIP("Compiler does not support C++11 feature"); +#else + alignas(alignof(double)) char c; + Q_UNUSED(c); +#endif +} + +void tst_Compiler::cxx11_atomics() +{ +#ifndef Q_COMPILER_ATOMICS + QSKIP("Compiler does not support C++11 feature"); +#else + std::atomic<int> i; + i.store(42, std::memory_order_seq_cst); + QCOMPARE(i.load(std::memory_order_acquire), 42); + + std::atomic<short> s; + s.store(42); + QCOMPARE(s.load(), short(42)); + + std::atomic_flag flag; + flag.clear(); + QVERIFY(!flag.test_and_set()); + QVERIFY(flag.test_and_set()); +#endif +} + +void tst_Compiler::cxx11_attributes() +{ +#ifndef Q_COMPILER_ATTRIBUTES + QSKIP("Compiler does not support C++11 feature"); +#else + struct [[deprecated]] C {}; + [[gnu::unused]] struct D {} d; + [[noreturn]] void f(); + struct D e [[gnu::used, gnu::unused]]; + [[gnu::aligned(8)]] int i; + +[[gnu::unused]] end: + ; + + Q_UNUSED(d); + Q_UNUSED(e); + Q_UNUSED(i); +#endif +} + +#ifdef Q_COMPILER_AUTO_FUNCTION +auto autoFunction() -> unsigned +{ + return 1; +} +#endif + +void tst_Compiler::cxx11_auto_function() +{ +#ifndef Q_COMPILER_AUTO_FUNCTION + QSKIP("Compiler does not support C++11 feature"); +#else + QCOMPARE(autoFunction(), 1u); +#endif +} + +void tst_Compiler::cxx11_auto_type() +{ +#ifndef Q_COMPILER_AUTO_TYPE + QSKIP("Compiler does not support C++11 feature"); +#else + auto i = 1; + auto x = qrand(); + auto l = 1L; + auto s = QStringLiteral("Hello World"); + + QCOMPARE(i, 1); + Q_UNUSED(x); + QCOMPARE(l, 1L); + QCOMPARE(s.toLower(), QString("hello world")); +#endif +} + +void tst_Compiler::cxx11_class_enum() +{ +#ifndef Q_COMPILER_CLASS_ENUM + QSKIP("Compiler does not support C++11 feature"); +#else + enum class X { EnumValue }; + X x = X::EnumValue; + QCOMPARE(x, X::EnumValue); + + enum class Y : short { Val = 2 }; + enum Z : long { ValLong = LONG_MAX }; +#endif +} + +#ifdef Q_COMPILER_CONSTEXPR +constexpr int constexprValue() +{ + return 42; +} +#endif + +void tst_Compiler::cxx11_constexpr() +{ +#ifndef Q_COMPILER_CONSTEXPR + QSKIP("Compiler does not support C++11 feature"); +#else + static constexpr QBasicAtomicInt atomic = Q_BASIC_ATOMIC_INITIALIZER(1); + static constexpr int i = constexprValue(); + QCOMPARE(i, constexprValue()); + QCOMPARE(atomic.load(), 1); +#endif +} + +void tst_Compiler::cxx11_decltype() +{ +#ifndef Q_COMPILER_DECLTYPE + QSKIP("Compiler does not support C++11 feature"); +#else + decltype(qrand()) i = 0; + QCOMPARE(i, 0); +#endif +} + +void tst_Compiler::cxx11_default_members() +{ +#ifndef Q_COMPILER_DEFAULT_MEMBERS + QSKIP("Compiler does not support C++11 feature"); +#else + struct DefaultMembers + { + DefaultMembers() = default; + DefaultMembers(int) {} + }; + DefaultMembers dm; + Q_UNUSED(dm); +#endif +} + +void tst_Compiler::cxx11_delete_members() +{ +#ifndef Q_COMPILER_DELETE_MEMBERS + QSKIP("Compiler does not support C++11 feature"); +#else + struct DeleteMembers + { + DeleteMembers() = delete; + DeleteMembers(const DeleteMembers &) = delete; + ~DeleteMembers() = delete; + }; +#endif +} + +void tst_Compiler::cxx11_delegating_constructors() +{ +#ifndef Q_COMPILER_DELEGATING_CONSTRUCTORS + QSKIP("Compiler does not support C++11 feature"); +#else + struct DC { + DC(int i) : i(i) {} + DC() : DC(0) {} + int i; + }; + + DC dc; + QCOMPARE(dc.i, 0); +#endif +} + +void tst_Compiler::cxx11_explicit_conversions() +{ +#ifndef Q_COMPILER_EXPLICIT_CONVERSIONS + QSKIP("Compiler does not support C++11 feature"); +#else + struct EC { + explicit operator int() const { return 0; } + operator long long() const { return 1; } + }; + EC ec; + + int i(ec); + QCOMPARE(i, 0); + + int i2 = ec; + QCOMPARE(i2, 1); +#endif +} + +void tst_Compiler::cxx11_explicit_overrides() +{ +#ifndef Q_COMPILER_EXPLICIT_OVERRIDES + QSKIP("Compiler does not support C++11 feature"); +#else + struct Base { + virtual ~Base() {} + virtual void f() {} + }; + struct Derived final : public Base { + virtual void f() final override {} + }; +#endif +} + +#ifdef Q_COMPILER_EXTERN_TEMPLATES +template <typename T> T externTemplate() { return T(0); } +extern template int externTemplate<int>(); +#endif + +void tst_Compiler::cxx11_extern_templates() +{ +#ifndef Q_COMPILER_EXTERN_TEMPLATES + QSKIP("Compiler does not support C++11 feature"); +#else + QCOMPARE(externTemplate<int>(), 42); +#endif +} + +void tst_Compiler::cxx11_inheriting_constructors() +{ +#ifndef Q_COMPILER_INHERITING_CONSTRUCTORS + QSKIP("Compiler does not support C++11 feature"); +#else + struct Base { + int i; + Base() : i(0) {} + Base(int i) : i(i) {} + }; + struct Derived : public Base { + using Base::Base; + }; + + Derived d(1); + QCOMPARE(d.i, 1); +#endif +} + +void tst_Compiler::cxx11_initializer_lists() +{ +#ifndef Q_COMPILER_INITIALIZER_LISTS + QSKIP("Compiler does not support C++11 feature"); +#else + QList<int> l = { 1, 2, 3, 4, 5 }; + QCOMPARE(l.length(), 5); + QCOMPARE(l.at(0), 1); + QCOMPARE(l.at(4), 5); +#endif +} + +struct CallFunctor +{ + template <typename Functor> static int f(Functor f) + { return f();} +}; + +void tst_Compiler::cxx11_lambda() +{ +#ifndef Q_COMPILER_LAMBDA + QSKIP("Compiler does not support C++11 feature"); +#else + QCOMPARE(CallFunctor::f([]() { return 42; }), 42); +#endif +} + +void tst_Compiler::cxx11_nonstatic_member_init() +{ +#ifndef Q_COMPILER_NONSTATIC_MEMBER_INIT + QSKIP("Compiler does not support C++11 feature"); +#else + struct S { + int i = 42; + long l = 47; + char c; + S() : l(-47), c(0) {} + }; + S s; + + QCOMPARE(s.i, 42); + QCOMPARE(s.l, -47L); + QCOMPARE(s.c, '\0'); +#endif +} + +void tst_Compiler::cxx11_noexcept() +{ +#ifndef Q_COMPILER_NOEXCEPT + QSKIP("Compiler does not support C++11 feature"); +#else + extern void noexcept_f() noexcept; + extern void g() noexcept(noexcept(noexcept_f())); + QCOMPARE(noexcept(cxx11_noexcept()), false); + QCOMPARE(noexcept(noexcept_f), true); + QCOMPARE(noexcept(g), true); +#endif +} + +void tst_Compiler::cxx11_nullptr() +{ +#ifndef Q_COMPILER_NULLPTR + QSKIP("Compiler does not support C++11 feature"); +#else + void *v = nullptr; + char *c = nullptr; + const char *cc = nullptr; + volatile char *vc = nullptr; + std::nullptr_t np = nullptr; + v = np; + + Q_UNUSED(v); + Q_UNUSED(c); + Q_UNUSED(cc); + Q_UNUSED(vc); +#endif +} + +void tst_Compiler::cxx11_range_for() +{ +#ifndef Q_COMPILER_RANGE_FOR + QSKIP("Compiler does not support C++11 feature"); +#else + QList<int> l; + l << 1 << 2 << 3; + for (int i : l) + Q_UNUSED(i); + + l.clear(); + l << 1; + for (int i : l) + QCOMPARE(i, 1); + + QList<long> ll; + l << 2; + for (int i : ll) + QCOMPARE(i, 2); +#endif +} + +void tst_Compiler::cxx11_raw_strings() +{ +#ifndef Q_COMPILER_RAW_STRINGS + QSKIP("Compiler does not support C++11 feature"); +#else + static const char xml[] = R"(<?xml version="1.0" encoding="UTF-8" ?>)"; + static const char raw[] = R"***(*"*)***"; + QCOMPARE(strlen(raw), size_t(3)); + QCOMPARE(raw[1], '"'); + Q_UNUSED(xml); +#endif +} + +void tst_Compiler::cxx11_ref_qualifiers() +{ +#ifndef Q_COMPILER_REF_QUALIFIERS + QSKIP("Compiler does not support C++11 feature"); +#else +# ifndef Q_COMPILER_RVALUE_REFS +# error "Impossible condition: ref qualifiers are supported but not rvalue refs" +# endif + // also applies to function pointers + QByteArray (QString:: *lvalueref)() const & = &QString::toLatin1; + QByteArray (QString:: *rvalueref)() && = &QString::toLatin1; + + QString s("Hello"); + QCOMPARE((s.*lvalueref)(), QByteArray("Hello")); + QCOMPARE((std::move(s).*rvalueref)(), QByteArray("Hello")); + + // tests internal behavior: + QVERIFY(s.isEmpty()); +#endif +} + +void tst_Compiler::cxx11_rvalue_refs() +{ +#ifndef Q_COMPILER_RVALUE_REFS + QSKIP("Compiler does not support C++11 feature"); +#else + int i = 1; + i = std::move(i); + + QString s = "Hello"; + QString t = std::move(s); + QCOMPARE(t, QString("Hello")); + + s = t; + t = std::move(s); + QCOMPARE(t, QString("Hello")); + + QString &&r = std::move(s); + QCOMPARE(r, QString("Hello")); +#endif +} + +void tst_Compiler::cxx11_static_assert() +{ +#ifndef Q_COMPILER_STATIC_ASSERT + QSKIP("Compiler does not support C++11 feature"); +#else + static_assert(true, "Message"); +#endif +} + +#ifdef Q_COMPILER_TEMPLATE_ALIAS +template <typename T> using Map = QMap<QString, T>; +#endif + +void tst_Compiler::cxx11_template_alias() +{ +#ifndef Q_COMPILER_TEMPLATE_ALIAS + QSKIP("Compiler does not support C++11 feature"); +#else + Map<QVariant> m; + m.insert("Hello", "World"); + QCOMPARE(m.value("Hello").toString(), QString("World")); + + using X = int; + X i = 0; + Q_UNUSED(i); +#endif +} + +#ifdef Q_COMPILER_THREAD_LOCAL +static thread_local int stl = 42; +thread_local int gtl = 42; +#endif + +void tst_Compiler::cxx11_thread_local() +{ +#ifndef Q_COMPILER_THREAD_LOCAL + QSKIP("Compiler does not support C++11 feature"); +#else + thread_local int v = 1; + QVERIFY(v); + QVERIFY(stl); + QVERIFY(gtl); + + thread_local QString s = "Hello"; + QVERIFY(!s.isEmpty()); +#endif +} + +#ifdef Q_COMPILER_UDL +QString operator"" _tstqstring(const char *str, size_t len) +{ + return QString::fromUtf8(str, len) + " UDL"; +} +#endif + +void tst_Compiler::cxx11_udl() +{ +#ifndef Q_COMPILER_UDL + QSKIP("Compiler does not support C++11 feature"); +#else + QString s = "Hello World"_tstqstring; + QCOMPARE(s, QString("Hello World UDL")); +#endif +} + +void tst_Compiler::cxx11_unicode_strings() +{ +#ifndef Q_COMPILER_UNICODE_STRINGS + QSKIP("Compiler does not support C++11 feature"); +#else + static const char16_t u[] = u"\u200BHello\u00A0World"; + QCOMPARE(u[0], char16_t(0x200B)); + + static const char32_t U[] = U"\ufffe"; + QCOMPARE(U[0], char32_t(0xfffe)); + + QCOMPARE(u"\U00010000"[0], char16_t(0xD800)); + QCOMPARE(u"\U00010000"[1], char16_t(0xDC00)); +#endif +} + +static void noop(QPair<int, int>) {} +void tst_Compiler::cxx11_uniform_init() +{ +#ifndef Q_COMPILER_UNIFORM_INIT + QSKIP("Compiler does not support C++11 feature"); + noop(QPair<int,int>()); +#else + QString s{"Hello"}; + int i{}; + noop(QPair<int,int>{1,1}); + noop({i,1}); +#endif +} + +void tst_Compiler::cxx11_unrestricted_unions() +{ +#ifndef Q_COMPILER_UNRESTRICTED_UNIONS + QSKIP("Compiler does not support C++11 feature"); +#else + union U { + QString s; + U() {} + U(const QString &s) : s(s) {} + ~U() {} + }; + U u; + std::aligned_storage<sizeof(QString), Q_ALIGNOF(QString)> as; + Q_UNUSED(u); + Q_UNUSED(as); + + U u2("hello"); + u2.s.~QString(); +#endif +} + +void tst_Compiler::cxx11_variadic_macros() +{ +#ifndef Q_COMPILER_VARIADIC_MACROS + QSKIP("Compiler does not support C++11 feature"); +#else +# define TEST_VARARG(x, ...) __VA_ARGS__ + QCOMPARE(TEST_VARARG(0, 1), 1); +#endif +} + +#ifdef Q_COMPILER_VARIADIC_TEMPLATES +template <typename... Args> struct VariadicTemplate {}; +#endif + +void tst_Compiler::cxx11_variadic_templates() +{ +#ifndef Q_COMPILER_VARIADIC_TEMPLATES + QSKIP("Compiler does not support C++11 feature"); +#else + VariadicTemplate<> v0; + VariadicTemplate<int> v1; + VariadicTemplate<int, int, int, int, + int, int, int, int> v8; + Q_UNUSED(v0); + Q_UNUSED(v1); + Q_UNUSED(v8); +#endif +} + +void tst_Compiler::cxx14_binary_literals() +{ +#if __cpp_binary_literals-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + int i = 0b11001001; + QCOMPARE(i, 0xC9); +#endif +} + +void tst_Compiler::cxx14_init_captures() +{ +#if __cpp_init_captures-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + QCOMPARE([x = 42]() { return x; }(), 42); +#endif +} + +void tst_Compiler::cxx14_generic_lambdas() +{ +#if __cpp_generic_lambdas-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + auto identity = [](auto x) { return x; }; + QCOMPARE(identity(42), 42); + QCOMPARE(identity(42U), 42U); + QCOMPARE(identity(42L), 42L); +#endif +} + +#if __cpp_constexpr-0 >= 201304 +constexpr int relaxedConstexpr(int i) +{ + i *= 2; + i += 2; + return i; +} +#endif + +void tst_Compiler::cxx14_constexpr() +{ +#if __cpp_constexpr-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + QCOMPARE(relaxedConstexpr(0), 2); + QCOMPARE(relaxedConstexpr(2), 6); +#endif +} + +void tst_Compiler::cxx14_decltype_auto() +{ +#if __cpp_decltype_auto-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + QList<int> l; + l << 1; + decltype(auto) value = l[0]; + value = 2; + QCOMPARE(l.at(0), 2); +#endif +} + +#if __cpp_return_type_deduction >= 201304 +auto returnTypeDeduction() +{ + return 1U; +} +#endif + +void tst_Compiler::cxx14_return_type_deduction() +{ +#if __cpp_return_type_deduction-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + QCOMPARE(returnTypeDeduction(), 1U); +#endif +} + +void tst_Compiler::cxx14_aggregate_nsdmi() +{ +#if __cpp_aggregate_nsdmi-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + struct S { int i, j = i; }; + S s = { 1 }; + QCOMPARE(s.j, 1); +#endif +} + +#if __cpp_variable_templates >= 201304 +template <typename T> constexpr T variableTemplate = T(42); +#endif +void tst_Compiler::cxx14_variable_templates() +{ +#if __cpp_variable_templates-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + QCOMPARE(variableTemplate<int>, 42); + QCOMPARE(variableTemplate<long>, 42L); + QCOMPARE(variableTemplate<unsigned>, 42U); + QCOMPARE(variableTemplate<unsigned long long>, 42ULL); +#endif +} + +void tst_Compiler::runtimeArrays() +{ +#if __cpp_runtime_arrays-0 < 201304 + QSKIP("Compiler does not support this C++14 feature"); +#else + int i[qrand() & 0x1f]; + Q_UNUSED(i); +#endif +} + QTEST_MAIN(tst_Compiler) #include "tst_compiler.moc" diff --git a/tests/auto/other/lancelot/scripts/text.qps b/tests/auto/other/lancelot/scripts/text.qps index e7d47448ea..b3d8475411 100644 --- a/tests/auto/other/lancelot/scripts/text.qps +++ b/tests/auto/other/lancelot/scripts/text.qps @@ -11,7 +11,7 @@ save setFont "sansserif" 12 normal drawText 0 40 "sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawText 0 60 "sansserif 12pt, bold" setFont "sansserif" 10 bold italic @@ -27,7 +27,7 @@ save setFont "sansserif" 12 normal drawText 0 40 "alpha sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawText 0 60 "alpha sansserif 12pt, bold" setFont "sansserif" 10 bold italic @@ -45,7 +45,7 @@ save setFont "sansserif" 12 normal drawText 0 40 "scaled sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawText 0 60 "scaled sansserif 12pt, bold" setFont "sansserif" 10 bold italic @@ -63,7 +63,7 @@ save setFont "sansserif" 12 normal drawStaticText 0 40 "flipped sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawStaticText 0 60 "flipped sansserif 12pt, bold" setFont "sansserif" 10 bold italic @@ -82,7 +82,7 @@ save setFont "sansserif" 12 normal drawText 0 40 "scaled sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawText 0 60 "scaled sansserif 12pt, bold" setFont "sansserif" 10 bold italic @@ -102,7 +102,7 @@ save setFont "sansserif" 12 normal drawText 0 20 "gradient sansserif 12pt, normal" - setFont "sansserif" 10 bold + setFont "sansserif" 12 bold drawText 0 40 "gradient sansserif 12pt, bold" setFont "sansserif" 10 bold italic diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index 407237e519..745c8f2499 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -2,7 +2,6 @@ TEMPLATE=subdirs SUBDIRS=\ # atwrapper \ # QTBUG-19452 baselineexample \ - collections \ compiler \ d3dcompiler \ gestures \ diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 8b033efa4a..c9df497b07 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -243,6 +243,7 @@ private slots: void statesStructTest(); void navigateHierarchy(); void sliderTest(); + void textAttributes_data(); void textAttributes(); void hideShowTest(); @@ -250,6 +251,7 @@ private slots: void applicationTest(); void mainWindowTest(); + void subWindowTest(); void buttonTest(); void scrollBarTest(); void tabTest(); @@ -698,58 +700,118 @@ void tst_QAccessibility::accessibleName() QTestAccessibility::clearEvents(); } -void tst_QAccessibility::textAttributes() +// note: color should probably always be part of the attributes +void tst_QAccessibility::textAttributes_data() { - QTextEdit textEdit; - int startOffset; - int endOffset; - QString attributes; - QString text("<html><head></head><body>" + QTest::addColumn<QString>("text"); + QTest::addColumn<int>("offset"); + QTest::addColumn<int>("startOffsetResult"); + QTest::addColumn<int>("endOffsetResult"); + QTest::addColumn<QStringList>("attributeResult"); + + static QStringList defaults = QString("font-style:normal;font-weight:normal;text-align:left;text-position:baseline;text-underline-style:none").split(';'); + static QStringList bold = defaults; + bold[1] = QString::fromLatin1("font-weight:bold"); + + static QStringList italic = defaults; + italic[0] = QString::fromLatin1("font-style:italic"); + + static QStringList boldItalic = defaults; + boldItalic[0] = QString::fromLatin1("font-style:italic"); + boldItalic[1] = QString::fromLatin1("font-weight:bold"); + + static QStringList monospace = defaults; + monospace.append(QLatin1String("font-family:\"monospace\"")); + + static QStringList font8pt = defaults; + font8pt.append(QLatin1String("font-size:8pt")); + + static QStringList color = defaults; + color << QLatin1String("color:rgb(240,241,242)") << QLatin1String("background-color:rgb(20,240,30)"); + + static QStringList rightAlign = defaults; + rightAlign[2] = QStringLiteral("text-align:right"); + + QTest::newRow("defaults 1") << "hello" << 0 << 0 << 5 << defaults; + QTest::newRow("defaults 2") << "hello" << 1 << 0 << 5 << defaults; + QTest::newRow("defaults 3") << "hello" << 4 << 0 << 5 << defaults; + QTest::newRow("defaults 4") << "hello" << 5 << 0 << 5 << defaults; + QTest::newRow("offset -1 length") << "hello" << -1 << 0 << 5 << defaults; + QTest::newRow("offset -2 cursor pos") << "hello" << -2 << 0 << 5 << defaults; + QTest::newRow("offset -3") << "hello" << -3 << -1 << -1 << QStringList(); + QTest::newRow("invalid offset 2") << "hello" << 6 << -1 << -1 << QStringList(); + QTest::newRow("invalid offset 3") << "" << 1 << -1 << -1 << QStringList(); + + QString boldText = QLatin1String("<html><b>bold</b>text"); + QTest::newRow("bold 0") << boldText << 0 << 0 << 4 << bold; + QTest::newRow("bold 2") << boldText << 2 << 0 << 4 << bold; + QTest::newRow("bold 3") << boldText << 3 << 0 << 4 << bold; + QTest::newRow("bold 4") << boldText << 4 << 4 << 8 << defaults; + QTest::newRow("bold 6") << boldText << 6 << 4 << 8 << defaults; + + QString longText = QLatin1String("<html>" "Hello, <b>this</b> is an <i><b>example</b> text</i>." "<span style=\"font-family: monospace\">Multiple fonts are used.</span>" "Multiple <span style=\"font-size: 8pt\">text sizes</span> are used." - "Let's give some color to <span style=\"color:#f0f1f2; background-color:#14f01e\">Qt</span>." - "</body></html>"); + "Let's give some color to <span style=\"color:#f0f1f2; background-color:#14f01e\">Qt</span>."); + + QTest::newRow("default 5") << longText << 6 << 0 << 7 << defaults; + QTest::newRow("default 6") << longText << 7 << 7 << 11 << bold; + QTest::newRow("bold 7") << longText << 10 << 7 << 11 << bold; + QTest::newRow("bold 8") << longText << 10 << 7 << 11 << bold; + QTest::newRow("bold italic") << longText << 18 << 18 << 25 << boldItalic; + QTest::newRow("monospace") << longText << 34 << 31 << 55 << monospace; + QTest::newRow("8pt") << longText << 65 << 64 << 74 << font8pt; + QTest::newRow("color") << longText << 110 << 109 << 111 << color; + + QString rightAligned = QLatin1String("<html><p align=\"right\">right</p>"); + QTest::newRow("right aligned 1") << rightAligned << 0 << 0 << 5 << rightAlign; + QTest::newRow("right aligned 2") << rightAligned << 1 << 0 << 5 << rightAlign; + QTest::newRow("right aligned 3") << rightAligned << 5 << 0 << 5 << rightAlign; + + // left \n right \n left, make sure bold and alignment borders coincide + QString leftRightLeftAligned = QLatin1String("<html><p><b>left</b></p><p align=\"right\">right</p><p><b>left</b></p>"); + QTest::newRow("left right left aligned 1") << leftRightLeftAligned << 1 << 0 << 4 << bold; + QTest::newRow("left right left aligned 3") << leftRightLeftAligned << 3 << 0 << 4 << bold; + QTest::newRow("left right left aligned 4") << leftRightLeftAligned << 4 << 4 << 5 << defaults; + QTest::newRow("left right left aligned 5") << leftRightLeftAligned << 5 << 5 << 10 << rightAlign; + QTest::newRow("left right left aligned 8") << leftRightLeftAligned << 8 << 5 << 10 << rightAlign; + QTest::newRow("left right left aligned 9") << leftRightLeftAligned << 9 << 5 << 10 << rightAlign; + QTest::newRow("left right left aligned 10") << leftRightLeftAligned << 10 << 10 << 11 << rightAlign; + QTest::newRow("left right left aligned 11") << leftRightLeftAligned << 11 << 11 << 15 << bold; + QTest::newRow("left right left aligned 15") << leftRightLeftAligned << 15 << 11 << 15 << bold; +} + +void tst_QAccessibility::textAttributes() +{ + { + QFETCH(QString, text); + QFETCH(int, offset); + QFETCH(int, startOffsetResult); + QFETCH(int, endOffsetResult); + QFETCH(QStringList, attributeResult); + QTextEdit textEdit; textEdit.setText(text); + if (textEdit.document()->characterCount() > 1) + textEdit.textCursor().setPosition(1); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&textEdit); - QAccessibleTextInterface *textInterface=interface->textInterface(); - QVERIFY(textInterface); - QCOMPARE(textInterface->characterCount(), 112); + QCOMPARE(textInterface->characterCount(), textEdit.toPlainText().length()); - attributes = textInterface->attributes(10, &startOffset, &endOffset); - QCOMPARE(startOffset, 7); - QCOMPARE(endOffset, 11); - attributes.prepend(';'); - QVERIFY(attributes.contains(QLatin1String(";font-weight:bold;"))); - - attributes = textInterface->attributes(18, &startOffset, &endOffset); - QCOMPARE(startOffset, 18); - QCOMPARE(endOffset, 25); - attributes.prepend(';'); - QVERIFY(attributes.contains(QLatin1String(";font-weight:bold;"))); - QVERIFY(attributes.contains(QLatin1String(";font-style:italic;"))); - - attributes = textInterface->attributes(34, &startOffset, &endOffset); - QCOMPARE(startOffset, 31); - QCOMPARE(endOffset, 55); - attributes.prepend(';'); - QVERIFY(attributes.contains(QLatin1String(";font-family:\"monospace\";"))); - - attributes = textInterface->attributes(65, &startOffset, &endOffset); - QCOMPARE(startOffset, 64); - QCOMPARE(endOffset, 74); - attributes.prepend(';'); - QVERIFY(attributes.contains(QLatin1String(";font-size:8pt;"))); - - attributes = textInterface->attributes(110, &startOffset, &endOffset); - QCOMPARE(startOffset, 109); - QCOMPARE(endOffset, 111); - attributes.prepend(';'); - QVERIFY(attributes.contains(QLatin1String(";background-color:rgb(20,240,30);"))); - QVERIFY(attributes.contains(QLatin1String(";color:rgb(240,241,242);"))); + int startOffset = -1; + int endOffset = -1; + QString attributes = textInterface->attributes(offset, &startOffset, &endOffset); + + QCOMPARE(startOffset, startOffsetResult); + QCOMPARE(endOffset, endOffsetResult); + QStringList attrList = attributes.split(QChar(';'), QString::SkipEmptyParts); + attributeResult.sort(); + attrList.sort(); + QCOMPARE(attrList, attributeResult); + } + QTestAccessibility::clearEvents(); } void tst_QAccessibility::hideShowTest() @@ -942,6 +1004,66 @@ void tst_QAccessibility::mainWindowTest() } } +// Dialogs and other sub-windows must appear in the +// accessibility hierarchy exactly once as top level objects +void tst_QAccessibility::subWindowTest() +{ + { + QWidget mainWidget; + mainWidget.setGeometry(100, 100, 100, 100); + mainWidget.show(); + QLabel label(QStringLiteral("Window Contents"), &mainWidget); + mainWidget.setLayout(new QHBoxLayout()); + mainWidget.layout()->addWidget(&label); + + QDialog d(&mainWidget); + d.show(); + + QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp); + QVERIFY(app); + QCOMPARE(app->childCount(), 2); + + QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWidget); + QVERIFY(windowIface); + QCOMPARE(windowIface->childCount(), 1); + QCOMPARE(app->child(0), windowIface); + QCOMPARE(windowIface->parent(), app); + + QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d); + QVERIFY(dialogIface); + QCOMPARE(app->child(1), dialogIface); + QCOMPARE(dialogIface->parent(), app); + QCOMPARE(dialogIface->parent(), app); + } + + { + QMainWindow mainWindow; + mainWindow.setGeometry(100, 100, 100, 100); + mainWindow.show(); + QLabel label(QStringLiteral("Window Contents"), &mainWindow); + mainWindow.setCentralWidget(&label); + + QDialog d(&mainWindow); + d.show(); + + QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp); + QVERIFY(app); + QCOMPARE(app->childCount(), 2); + + QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWindow); + QVERIFY(windowIface); + QCOMPARE(windowIface->childCount(), 1); + QCOMPARE(app->child(0), windowIface); + + QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d); + QVERIFY(dialogIface); + QCOMPARE(app->child(1), dialogIface); + QCOMPARE(dialogIface->parent(), app); + QCOMPARE(windowIface->parent(), app); + } + QTestAccessibility::clearEvents(); +} + class CounterButton : public QPushButton { Q_OBJECT public: @@ -1191,8 +1313,11 @@ void tst_QAccessibility::tabTest() QVERIFY(leftButton->state().invisible); const int lots = 5; - for (int i = 0; i < lots; ++i) + for (int i = 0; i < lots; ++i) { tabBar->addTab("Foo"); + tabBar->setTabToolTip(i, QLatin1String("Cool tool tip")); + tabBar->setTabWhatsThis(i, QLatin1String("I don't know")); + } QAccessibleInterface *child1 = interface->child(0); QAccessibleInterface *child2 = interface->child(1); @@ -1201,6 +1326,10 @@ void tst_QAccessibility::tabTest() QVERIFY(child2); QCOMPARE(child2->role(), QAccessible::PageTab); + QCOMPARE(child1->text(QAccessible::Name), QLatin1String("Foo")); + QCOMPARE(child1->text(QAccessible::Description), QLatin1String("Cool tool tip")); + QCOMPARE(child1->text(QAccessible::Help), QLatin1String("I don't know")); + QVERIFY((child1->state().invisible) == false); tabBar->hide(); @@ -1652,6 +1781,11 @@ void tst_QAccessibility::textEditTest() QTest::qWaitForWindowShown(&edit); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit); QCOMPARE(iface->text(QAccessible::Value), edit.toPlainText()); + QVERIFY(iface->state().focusable); + QVERIFY(!iface->state().selectable); + QVERIFY(!iface->state().selected); + QVERIFY(iface->state().selectableText); + QAccessibleTextInterface *textIface = iface->textInterface(); QVERIFY(textIface); @@ -1751,8 +1885,6 @@ void tst_QAccessibility::textEditTest() QAccessibleTextRemoveEvent remove(&edit, 0, " "); QVERIFY_EVENT(&remove); - // FIXME the new text is not there yet - QEXPECT_FAIL("", "Inserting should always contain the new text", Continue); QAccessibleTextInsertEvent insert(&edit, 0, "Accessibility rocks"); QVERIFY_EVENT(&insert); } @@ -1929,7 +2061,8 @@ void tst_QAccessibility::lineEditTest() QVERIFY(iface->state().sizeable); QVERIFY(iface->state().movable); QVERIFY(iface->state().focusable); - QVERIFY(iface->state().selectable); + QVERIFY(!iface->state().selectable); + QVERIFY(iface->state().selectableText); QVERIFY(!iface->state().hasPopup); QCOMPARE(bool(iface->state().focused), le->hasFocus()); @@ -1940,13 +2073,13 @@ void tst_QAccessibility::lineEditTest() QCOMPARE(iface->text(QAccessible::Value), secret); le->setEchoMode(QLineEdit::NoEcho); QVERIFY(iface->state().passwordEdit); - QVERIFY(iface->text(QAccessible::Value).isEmpty()); + QCOMPARE(iface->text(QAccessible::Value), QString()); le->setEchoMode(QLineEdit::Password); QVERIFY(iface->state().passwordEdit); - QVERIFY(iface->text(QAccessible::Value).isEmpty()); + QCOMPARE(iface->text(QAccessible::Value), QString(secret.length(), QLatin1Char('*'))); le->setEchoMode(QLineEdit::PasswordEchoOnEdit); QVERIFY(iface->state().passwordEdit); - QVERIFY(iface->text(QAccessible::Value).isEmpty()); + QCOMPARE(iface->text(QAccessible::Value), QString(secret.length(), QLatin1Char('*'))); le->setEchoMode(QLineEdit::Normal); QVERIFY(!(iface->state().passwordEdit)); QCOMPARE(iface->text(QAccessible::Value), secret); @@ -1957,7 +2090,9 @@ void tst_QAccessibility::lineEditTest() QVERIFY(!(iface->state().sizeable)); QVERIFY(!(iface->state().movable)); QVERIFY(iface->state().focusable); - QVERIFY(iface->state().selectable); + QVERIFY(!iface->state().selectable); + QVERIFY(!iface->state().selected); + QVERIFY(iface->state().selectableText); QVERIFY(!iface->state().hasPopup); QCOMPARE(bool(iface->state().focused), le->hasFocus()); diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp index 50bf342365..4ff90e85cc 100644 --- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp +++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -47,6 +47,7 @@ #include <QtWidgets/QListWidget> #include <QtWidgets/QTreeWidget> #include <QtWidgets/QTextEdit> +#include <QtWidgets/QPushButton> #include <QDBusArgument> #include <QDBusConnection> @@ -102,6 +103,7 @@ private slots: void testTreeWidget(); void testTextEdit(); void testSlider(); + void testFocus(); void cleanupTestCase(); @@ -421,14 +423,22 @@ void tst_QAccessibilityLinux::testTextEdit() QCOMPARE(callResult.at(2).toInt(), 17); // Check if at least CharacterExtents and RangeExtents give a consistent result - QDBusReply<QRect> replyRect20 = textInterface->call(QDBus::Block, "GetCharacterExtents", 20, ATSPI_COORD_TYPE_SCREEN); - QVERIFY(replyRect20.isValid()); - QRect r1 = replyRect20.value(); - QDBusReply<QRect> replyRect21 = textInterface->call(QDBus::Block, "GetCharacterExtents", 21, ATSPI_COORD_TYPE_SCREEN); - QRect r2 = replyRect21.value(); - QDBusReply<QRect> reply = textInterface->call(QDBus::Block, "GetRangeExtents", 20, 21, ATSPI_COORD_TYPE_SCREEN); - QRect rect = reply.value(); - QCOMPARE(rect, r1|r2); + + QDBusMessage replyRect20 = textInterface->call(QDBus::Block, "GetCharacterExtents", 20, ATSPI_COORD_TYPE_SCREEN); + QCOMPARE(replyRect20.type(), QDBusMessage::ReplyMessage); + QCOMPARE(replyRect20.signature(), QStringLiteral("iiii")); + callResult = replyRect20.arguments(); + QRect r1 = QRect(callResult.at(0).toInt(), callResult.at(1).toInt(), callResult.at(2).toInt(), callResult.at(3).toInt()); + QDBusMessage replyRect21 = textInterface->call(QDBus::Block, "GetCharacterExtents", 21, ATSPI_COORD_TYPE_SCREEN); + QCOMPARE(replyRect21.type(), QDBusMessage::ReplyMessage); + QCOMPARE(replyRect21.signature(), QStringLiteral("iiii")); + callResult = replyRect21.arguments(); + QRect r2 = QRect(callResult.at(0).toInt(), callResult.at(1).toInt(), callResult.at(2).toInt(), callResult.at(3).toInt()); + + QDBusMessage replyRange = textInterface->call(QDBus::Block, "GetRangeExtents", 20, 21, ATSPI_COORD_TYPE_SCREEN); + callResult = replyRange.arguments(); + QRect rectRangeExtents = QRect(callResult.at(0).toInt(), callResult.at(1).toInt(), callResult.at(2).toInt(), callResult.at(3).toInt()); + QCOMPARE(rectRangeExtents, r1|r2); m_window->clearChildren(); delete textInterface; @@ -457,6 +467,54 @@ void tst_QAccessibilityLinux::testSlider() QCOMPARE(valueInterface->property("CurrentValue").toInt(), 4); } +quint64 getAtspiState(QDBusInterface *interface) +{ + QDBusMessage msg = interface->call(QDBus::Block, "GetState"); + const QDBusArgument arg = msg.arguments().at(0).value<QDBusArgument>(); + quint32 state1 = 0; + quint64 state2 = 0; + arg.beginArray(); + arg >> state1; + arg >> state2; + arg.endArray(); + + state2 = state2 << 32; + return state2 | state1; +} + +void tst_QAccessibilityLinux::testFocus() +{ + QLineEdit *lineEdit1 = new QLineEdit(m_window); + lineEdit1->setText("lineEdit 1"); + QLineEdit *lineEdit2 = new QLineEdit(m_window); + lineEdit2->setText("lineEdit 2"); + + m_window->addWidget(lineEdit1); + m_window->addWidget(lineEdit2); + lineEdit1->setFocus(); + + QStringList children = getChildren(mainWindow); + QCOMPARE(children.length(), 2); + QDBusInterface *accessibleInterfaceLineEdit1 = getInterface(children.at(0), "org.a11y.atspi.Accessible"); + QVERIFY(accessibleInterfaceLineEdit1->isValid()); + QDBusInterface *accessibleInterfaceLineEdit2 = getInterface(children.at(1), "org.a11y.atspi.Accessible"); + QVERIFY(accessibleInterfaceLineEdit2->isValid()); + QDBusInterface *componentInterfaceLineEdit1 = getInterface(children.at(0), "org.a11y.atspi.Component"); + QVERIFY(componentInterfaceLineEdit1->isValid()); + QDBusInterface *componentInterfaceLineEdit2 = getInterface(children.at(1), "org.a11y.atspi.Component"); + QVERIFY(componentInterfaceLineEdit2->isValid()); + + quint64 focusedState = quint64(1) << ATSPI_STATE_FOCUSED; + QVERIFY(getAtspiState(accessibleInterfaceLineEdit1) & focusedState); + QVERIFY(!(getAtspiState(accessibleInterfaceLineEdit2) & focusedState)); + + QDBusMessage focusReply = componentInterfaceLineEdit2->call(QDBus::Block, "GrabFocus"); + QVERIFY(focusReply.arguments().at(0).toBool()); + QVERIFY(lineEdit2->hasFocus()); + QVERIFY(!(getAtspiState(accessibleInterfaceLineEdit1) & focusedState)); + QVERIFY(getAtspiState(accessibleInterfaceLineEdit2) & focusedState); +} + QTEST_MAIN(tst_QAccessibilityLinux) #include "tst_qaccessibilitylinux.moc" diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index 71a90e83f7..775156e728 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -172,14 +172,18 @@ void tst_QObjectRace::moveToThreadRace() class MyObject : public QObject { Q_OBJECT + bool ok; + public: + MyObject() : ok(true) {} + ~MyObject() { Q_ASSERT(ok); ok = false; } public slots: - void slot1() { emit signal1(); } - void slot2() { emit signal2(); } - void slot3() { emit signal3(); } - void slot4() { emit signal4(); } - void slot5() { emit signal5(); } - void slot6() { emit signal6(); } - void slot7() { emit signal7(); } + void slot1() { Q_ASSERT(ok); } + void slot2() { Q_ASSERT(ok); } + void slot3() { Q_ASSERT(ok); } + void slot4() { Q_ASSERT(ok); } + void slot5() { Q_ASSERT(ok); } + void slot6() { Q_ASSERT(ok); } + void slot7() { Q_ASSERT(ok); } signals: void signal1(); void signal2(); @@ -237,6 +241,10 @@ public: disconnect(objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive], _slotsPMF[(19*i+2)%7] ); QMetaObject::Connection c = connect(objects[((i+5)*43) % nAlive], _signalsPMF[(9*i+1)%7], Functor()); + + for (int f = 0; f < 7; ++f) + emit (objects[i]->*_signalsPMF[f])(); + disconnect(c); disconnect(objects[i], _signalsPMF[(10*i+5)%7], 0, 0); @@ -249,6 +257,9 @@ public: delete objects[i]; } + + //run the possible queued slots + qApp->processEvents(); } }; diff --git a/tests/auto/other/qvariant_common/tst_qvariant_common.h b/tests/auto/other/qvariant_common/tst_qvariant_common.h index 7a34d7b0c2..89c8bc777a 100644 --- a/tests/auto/other/qvariant_common/tst_qvariant_common.h +++ b/tests/auto/other/qvariant_common/tst_qvariant_common.h @@ -44,33 +44,6 @@ #include <QString> -struct MessageHandlerInvalidType -{ - MessageHandlerInvalidType() - : oldMsgHandler(qInstallMessageHandler(handler)) - { - ok = false; - } - - ~MessageHandlerInvalidType() - { - qInstallMessageHandler(oldMsgHandler); - } - - QtMessageHandler oldMsgHandler; - - static void handler(QtMsgType type, const QMessageLogContext & /*ctxt*/, const QString &msg) - { - Q_UNUSED(type); - // uint(-1) can be platform dependent so we check only beginning of the message. - ok = msg.startsWith("Trying to construct an instance of an invalid type, type id:"); - QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData()); - } - static bool ok; -}; -bool MessageHandlerInvalidType::ok; - - class MessageHandler { public: MessageHandler(const int typeId, QtMessageHandler msgHandler = handler) |